KOTH: Semua orang suka token

24

Dalam game ini dua pemain berlomba untuk memakan token bernilai paling banyak, tetapi ada twist! Makan beberapa token dalam satu baris dengan warna yang sama memberikan bonus yang terus bertambah, tetapi waspadalah, atau lawan Anda akan menggagalkan rencana Anda dengan memakan token yang Anda inginkan sebelum Anda bisa!

Aturan:

  • 1 lawan 1
  • papan n oleh n (ukuran acak antara 5x5 dan 15x15)
  • Anda dan lawan Anda akan muncul dalam sel acak yang sama
  • Di seluruh papan akan dihasilkan angka acak dalam beberapa sel dengan nilai mulai 1-3
  • 2 * (lebar papan) token akan dihasilkan, tetapi mungkin ada penggantian, sehingga kemungkinan ada lebih sedikit secara kebetulan.
  • Setiap angka akan menjadi salah satu dari 3 warna: Merah, Hijau, atau Biru, dalam format hex RGB
  • Setiap putaran, pemain 1 bergerak dan papan diperbarui, lalu pemain 2 bergerak, dan papan diperbarui. Jadi setiap pemain dapat secara efektif mengetahui gerakan pemain sebelumnya berdasarkan perubahan pada kondisi board. Ini berlanjut sampai permainan berakhir, seperti yang dijelaskan nanti.
  • Anda memiliki 6 kemungkinan tindakan untuk belokan: ATAS, KANAN, BAWAH, KIRI, MAKAN, dan LULUS
  • 4 perintah bergerak cukup jelas, dan Anda DAPAT melewati giliran Anda. Jika Anda mengembalikan langkah yang tidak masuk akal, kami akan menganggap Anda bermaksud lulus. Jika Anda mencoba untuk menjauh dari tepi papan, Anda tidak akan bergerak. Tepi tidak membungkus.
  • EAT mengkonsumsi nomor Anda saat ini di ruang yang sama dengan
  • Anda mendapatkan poin sebanyak jumlah yang Anda konsumsi
  • Jika Anda makan 2 angka dalam satu baris dengan warna yang sama, Anda mendapatkan +1
  • Jika Anda makan 3 angka dalam satu baris dengan warna yang sama, Anda mendapatkan +2
  • Jika Anda makan angka m dalam satu baris dengan warna yang sama, Anda mendapatkan + (m-1)
  • Bonus ini ditambahkan secara kumulatif, jadi mendapatkan angka m berturut-turut akan menghasilkan total bonus m * (m-1) / 2 pada saat Anda makan warna yang berbeda.
  • Kondisi akhir gim:
    • Semua nomor dikonsumsi
    • 4 * (lebar papan) telah berlalu tanpa makan efektif (hanya mengatakan "MAKAN" tanpa tanda di mana Anda tidak dihitung) terjadi oleh salah satu pemain (token apa pun dapat dijangkau dalam 2 * (lebar) bergerak, jadi batas ini hanya akan dilampaui jika kedua pemain tidak memiliki token target tunggal dalam pikiran)
  • AI Anda harus mengambil kurang dari satu detik untuk bergerak, kalau tidak PASS akan dianggap sebagai pilihan Anda.

Turnamen akan berupa round robin dengan sejumlah besar putaran, misalkan 100 atau 1000. Papan acak dihasilkan, dan setiap pasang pemain yang berbeda dijalankan di papan itu. Setelah turnamen selesai, kami akan memberi peringkat orang berdasarkan skor total mereka. Jadi, bahkan jika Anda adalah pemain 2 untuk sebuah permainan, tujuan Anda masih mendapatkan poin sebanyak mungkin.

Kiriman AI: Bahasa yang didukung pengontrol saya adalah Javascript. Pengiriman ganda diperbolehkan. Semua orang mengirimkan konstruktor untuk objek seperti ini:

function (player1) {
    this.yourMove = function (b) {
        return "MOVE";
    }
}

Inputnya player1adalah boolean yang mengatakan apakah Anda pemain 1 atau tidak. Konstruktor Anda harus memiliki yourMovefungsi, tetapi dapat memiliki sejumlah fungsi atau nilai tambahan. Jangan mendefinisikan variabel global apa pun, cukup tempatkan sebagai variabel di objek Anda. Versi baru dari objek Anda akan dibuat pada awal setiap pertandingan, dan yourMoveakan dipanggil, dengan papan saat ini sebagai input, pada setiap putaran Anda, dan akan mengembalikan gerakan yang valid.

b, input ke yourMove, adalah salinan dari papan saat ini, berikut adalah konstruktornya, dengan contoh input, meskipun Anda tidak dapat menyebutnya sendiri:

function token(color, points) {
    this.color = color; //"#FF0000"
    this.points = points; //5
}

function player(pos, score, colorBonus, lastColor) {
    this.pos = pos; //[5, 5]
    this.score = score; //9
    this.colorBonus = colorBonus; //i.e. 2 if you just ate 3 blue tokens in a row
                                  //0 if you just ate two different colors.
    this.lastColor = lastColor; //"#00FF00", is "#000000" at start
}

function board(player1, player2, tokens) {
    this.player1 = player1; //new player([5, 5], 9, 2, "#00FF00")
    this.player2 = player2; //new player([5, 5], 9, 2, "#00FF00")
    this.tokens = tokens; //[[new token("#0000FF", 5), false],
                      // [new token("#0000FF", 5), false]]
}

Array token memiliki "false" untuk setiap kotak kosong, dan token [a] [b] adalah token di x = a, y = b, diberi nomor mulai dari sudut kiri atas.

Pengendali: Berikut ini tautan ke pengontrol di GitHub. Ini adalah file html yang dapat Anda jalankan untuk melihat bagaimana permainan dan round-robin bekerja, dan ia datang dengan dua AI, yang acak yang bergerak ke arah acak setiap belokan tetapi memakan token pada posisinya, dan algoritma naif yang berlaku untuk token terdekat yang memberikan poin terbanyak. Saya akan menambahkan setiap AI saat dikirimkan.

Di bawah ini adalah cuplikan yang memungkinkan Anda untuk menjalankan pengontrol pada AI default. AI saat ini:

  • KindaRandomAI
  • Naif
  • MirrorBot
  • HungryBot

Melon Fricative
sumber
12
Yay, KOTH! Sudah selamanya sejak yang terakhir.
TheNumberOne
2
Setuju, aku mencintaiku KOTH yang baik dan ini tampaknya menjadi premis yang bagus. Saya agak hijau untuk js, bagaimana cara mempertahankan status permainan di antara gerakan jika kita tidak dapat menyimpan hasil di dalam objek pemain?
DoctorHeckle
Apakah lebar papan dilewatkan ke fungsi?
Nomor Satu
@ BenNeeHumor Ya, fungsi yang mengambil di player1boolean adalah konstruktor untuk AI Anda, yang akan memiliki yourMovefungsi yang mengambil papan saat ini sebagai input, sebagai b.
Fricative Melon
1
@DylanSp Kadang-kadang mereka tidak diizinkan karena kemungkinan kolusi, tetapi dalam kasus ini, kolusi akan memiliki manfaat minimal, jadi saya akan mengizinkan beberapa pengiriman.
Fricative Melon

Jawaban:

4

HungryBot

Menggunakan sistem poin untuk menambah bobot pada nilai mengejar setiap token. Gunakan berbagai faktor yang berbeda dalam pertimbangannya, dan evaluasi ulang setiap giliran untuk memastikannya mengikuti strategi terbaik.

function hungryBot(first) {
  // Set up "self"
  var self = this;

  // Determine player order
  this.player = -(first - 2);
  this.enemy = first + 1;

  // Action associative array
  this.actions = ['EAT', 'LEFT', 'RIGHT', 'UP', 'DOWN'];

  //Logic handler
  this.yourMove = function(board) {
    // Determine player object
    var player = board['player' + self.player];
    var enemy = board['player' + self.enemy];

    // Point value action grid
    var actions = [0, 0, 0, 0, 0]; // Associative with "this.actions"

    // Board dimensions
    var size = board.tokens.length;
    var maxDist = size * 2;

    // Colors remaining
    var colors = {
      '#FF0000': 0,
      '#00FF00': 0,
      '#0000FF': 0
    };

    // Averaged value weight
    var average = [0, 0];

    // Total points
    var points = 0;

    // Token holder
    var tokens = [];

    // Token parser
    for (var i = 0, x = 0, y = 0; i < size * size; i += 1, x = i % size, y = i / size | 0) {
      if (!board.tokens[x][y]) {
        continue;
      } else {
        var token = {};
        token.points = board.tokens[x][y].points;
        token.color = board.tokens[x][y].color;
        token.x = x - player.pos[0];
        token.y = y - player.pos[1];
        token.distX = Math.abs(token.x);
        token.distY = Math.abs(token.y);
        token.dist = token.distX + token.distY;
        token.distE = Math.abs(x - enemy.pos[0]) + Math.abs(y - enemy.pos[1]);
        token.value = -token.points - (player.colorBonus + 1) * (token.color == player.lastColor) * ((token.dist == 0) + 1) * 1.618 - (enemy.colorBonus + 1) * (token.color == enemy.lastColor);
        tokens.push(token);
        colors[token.color] += 1;
        points += token.points;
        average[0] += x * token.points;
        average[1] += y * token.points;
      }
    }

    // Determine actual average
    average[0] = average[0] / points | 0;
    average[1] = average[1] / points | 0;

    // Pick best token
    var best = 0;

    // Calculate point values of tokens
    for (i = 0; i < tokens.length; i++) {
      var token = tokens[i];
      // Add remaining numbers of tokens of color as factor
      token.value -= (colors[token.color] / tokens.length) * 1.618;
      // Subtract distance as a factor
      token.value += token.dist;
      // Add distance to average to value
      token.value += (Math.abs(average[0] - (token.x + player.pos[0])) + Math.abs(average[1] - (token.y + player.pos[1]))) / Math.sqrt(2);
      // Consider them higher value if we are closer, and lower if they are
      token.value += ((token.dist - token.distE) / (token.dist + token.distE + 0.001)) * token.dist;
      // Don't go for it if enemy is already there
      token.value += (token.distE == 0 && token.dist > 0) * 100;

      if (tokens[best].value > tokens[i].value || (tokens[best].value === tokens[i].value && Math.round(Math.random()))) {
        best = i;
      }
    }

    // Set token to best token
    var token = tokens[best];

    // What to respond with
    var response = 'PASS';

    // Find best action to get token
    if (token.dist == 0) {
      response = 'EAT'; // We're on the token
    } else if (token.distX >= token.distY) { // Token is more horizontal
      if (token.x < 0) { // Token is left
        response = 'LEFT';
      } else if (token.x > 0) { // Token is right
        response = 'RIGHT';
      }
    } else if (token.distX < token.distY) { // Token is more vertical
      if (token.y < 0) { // Token is above
        response = 'UP';
      } else if (token.y > 0) { // Token is below
        response = 'DOWN';
      }
    }

    // Return response
    return response;
  }
};
Mwr247
sumber
Apakah Anda seorang programmer Python?
CalculatorFeline
@CatsAreFluffy Tidak juga ...?
Mwr247
Hanya mengira Anda karena self:)
CalculatorFeline
Mengapa menggunakan self? Tidak thiscukup?
Conor O'Brien
2

Bot PATH

Singkatan singkatan Pathfinding And Tree Heuristics Bot

EDIT: Sampai sekarang, berikut adalah peringkat untuk AI, dengan poin

  1. HungryBot (6422)
  2. Bot PATH (4591)
  3. Naif (3811)
  4. KindaRandomAI (618)
  5. MirrorBot (193)
  6. LazyBot (25)

Tautan ke pengontrol lengkap di github

Deskripsi: Seperti NaiveAI, bot ini menemukan token terdekat yang akan memberikan poin terbanyak. Namun, itu juga mensimulasikan hasil dari setiap gerakannya, hingga 6 kali.

Dasar Pemikiran: Karena NaiveAI sudah cukup bagus, saya pikir saya akan membuatnya lebih baik. Tanpa melihat kode terlebih dahulu (kesalahan besar).

Ketukan: Semua kecuali HungryBot
Kehilangan: Tidak ada kecuali HungryBot

Masalah:

  • Tidak dapat mensimulasikan peningkatan coretan
  • Hang saat menghitung token terbaik
  • Bisa teleportasi

Saya masih tidak tahu mengapa itu teleportasi, tapi saya memperbaikinya. Video lama di sini: https://youtu.be/BIhSKycF9iA

Kode lengkap:

pathBot = function (player1)
{
    this.pathNode = function(pos,ppt,parents,par)
    {
        this.pos = pos;this.ppt = ppt;this.parents = parents;this.par=par;
        this.childs=[];
    }
    this.addChildren = function (pn,children)
    {
        pn.childs=[];
        for(var i=0; i<children.length; i=i+1)
        {
            if(pn.parents.indexOf(children[i].pos)==-1&&pn.pos!=children[i].pos)
                pn.childs.push(
                    new this.pathNode(
                        children[i].pos,
                        children[i].ppt*pn.ppt,
                        pn.parents.concat([pn.pos]),
                        pn
                    )
                );
        }
    }
    this.orderTokensByPPT = function(b,pos){
        var tokens = [];
        for(var y=0; y<b.tokens.length; y=y+1)
        {
            for(var x=0; x<b.tokens[y].length; x=x+1)
            {
                var tok = b.tokens[y][x];
                if(tok)
                {
                    tokens.push(
                        new this.pathNode(
                            [y,x],
                            (tok.points+(tok.color==this.color ? this.streak : 0)) / this.lenOfMovesTo(pos,[y,x]),
                            [],
                            undefined
                        )
                    );
                }
            }
        }
        tokens.sort(function(a,b){
            return b.ppt - a.ppt;
        });
        return tokens;
    }
    this.lenOfMovesTo = function(cur,pos)
    {
        return Math.abs(cur[0]-pos[0])+Math.abs(cur[1]-pos[1])+1;
    }
    this.startAndGoalToCommand = function (start, goal) {
        var diff = [goal[0] - start[0], goal[1] - start[1]];
        if (diff[0] > 0) { return "RIGHT"; }
        else if (diff[1] > 0) { return "DOWN"; }
        else if (diff[1] < 0) { return "UP"; }
        else if (diff[0] < 0) { return "LEFT"; }
        else { return "EAT"; }
    }
    this.color = 0;
    this.streak = 0;
    this.eatTok = function(b)
    {
        if(b.tokens[this.me.pos[0]][this.me.pos[1]].color==this.color)
        {
            this.streak++;
        }
        else{
            this.streak = 0;
            this.color = b.tokens[this.me.pos[0]][this.me.pos[1]].color;
        }
        this.bestToken = false;
        return "EAT";
    }

    this.recurLen = 6;
    this.include = 4;
    this.recurDown = function(b,pn,level)
    {
        if(level==0) return pn;
        this.addChildren(pn,this.orderTokensByPPT(b,pn.pos));
        var newChilds = [];
        for(var i=0; i<pn.childs.length&&i<this.include; i=i+1)
        {
            newChilds.push(this.recurDown(b,pn.childs[i],level-1));
        }
        pn.childs = newChilds;
        return pn;
    }
    this.findMax = function(pn)
    {
        if(pn.childs)
        {
            var maxList = [];
            for(var i=0; i<pn.childs.length; i=i+1)
                maxList.push(this.findMax(pn.childs[i]));
            maxList.sort(
                function(a,b)
                {
                    return b.ppt-a.ppt;
                }
            );
            return maxList[0];
        }
        return pn;
    }
    this.findMaxList = function(pnList)
    {
        for(var i=0; i<pnList.lenght; i=i+1)
        {
            pnList[i] = this.findMax(pnList[i]);
        }
        pnList.sort(function(a,b){return b.ppt-a.ppt;});
        return pnList[0];
    }
    this.bestToken=false;
    this.yourMove = function(b){
        this.op = player1 ? b.player2 : b.player1;
        this.me = player1 ? b.player1 : b.player2;
        if(this.bestToken)
        {
            if(b.tokens[this.bestToken.pos[0]][this.bestToken.pos[1]]==undefined)
                this.bestToken = false;
        }
        if(!this.bestToken)
        {
            var paths = this.orderTokensByPPT(b,this.me.pos);
            for(var i=0; i<paths.length; i++)
            {
                paths[i] = this.recurDown(b,paths[i],this.recurLen);
            }
            var max = this.findMaxList(paths);
            while(max.par)
            {
                max = max.par;
            }
            this.bestToken = max;
        }
        var move = this.startAndGoalToCommand(this.me.pos,this.bestToken.pos);
        if(move=="EAT") return this.eatTok(b);
        else return move;
    }
}
Biru
sumber
SLaNTbot memperlambat kecepatan belokannya, dan memakan 15% CPU saya ... D: EDIT: Dan juga tidak makan apa-apa?
Mwr247
@ Mwr247 kecepatannya, ya, ia memodelkan ~ 2500 kemungkinan setiap tick. Tetapi untuk masalah makan, saya tidak tahu persis mengapa. Seperti yang saya katakan dalam pertanyaan, itu hanya teleport (alias bergerak beberapa spasi dalam 1 giliran), dan duduk di sana tanpa melakukan apa-apa. Saya memberi peringatan sebelum kembali dan tampaknya memberikan instruksi yang tepat setiap waktu.
Biru
Mungkin ini: "AI Anda harus mengambil kurang dari satu detik untuk bergerak, kalau tidak PASS akan dianggap sebagai pilihan Anda." Saya belum membaca controller, tetapi jika itu mengambil alih satu detik, apakah itu mengasumsikan LULUS?
Mwr247
@ Mwr247 Saya akan memeriksanya, tetapi sepertinya tidak mungkin mengingat bahwa itu membutuhkan <1 detik (atau jadi saya kira) pada mesin saya. Tetap saja, tidak ada salahnya untuk melihatnya. Terima kasih!
Biru
@ Mwr247 Setelah beberapa pengujian lagi, bukan itu. Itu membuat keputusan hampir secepat (setidaknya untuk saya) seperti NaiveAi. Juga, Anda lebih mungkin mengalami teleportasi di peta besar
Biru
1

Naif

Mulai dengan r=0, lihat semua token dengan jarak taksi rjauh dari posisi Anda. Jika ada, pilih satu yang akan memberi Anda skor tertinggi jika Anda mendapatkannya sekarang. Jika tidak, tambah r1 dan coba lagi.

naiveAI = function(player1) {
  this.player1 = player1;
  this.yourMove = function(b) {
    var me;
    if (this.player1) {
      me = b.player1;
    } else {
      me = b.player2;
    }
    var d = 0;
    var tokenP;
    while (tokenP == undefined) {
      var arr = this.findTokensAtDistance(me.pos, d)
      tokenP = this.findBestToken(arr, b.tokens, me);
      d += 1;
    }
    return this.startAndGoalToCommand(me.pos, tokenP);
  }
  this.findTokensAtDistance = function(p, d) {
    if (d == 0) {
      return [
        [p[0], p[1]]
      ];
    }
    var myArr = [];
    for (i = 0; i <= d; i++) {
      myArr[i] = [i, d - i];
    }
    var mySecArr = [];
    for (i = 0; i <= d; i++) {
      mySecArr[i] = [myArr[i][0] + p[0], myArr[i][1] + p[1]];
    }
    mySecArr[mySecArr.length] = [myArr[0][0] + p[0], -myArr[0][1] + p[1]];
    for (i = 1; i < myArr.length - 1; i++) {
      mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], myArr[i][1] + p[1]]
      mySecArr[mySecArr.length] = [myArr[i][0] + p[0], -myArr[i][1] + p[1]]
      mySecArr[mySecArr.length] = [-myArr[i][0] + p[0], -myArr[i][1] + p[1]]
    }
    mySecArr[mySecArr.length] = [-myArr[myArr.length - 1][0] + p[0], myArr[myArr.length - 1][1] + p[1]];
    return mySecArr;
  }
  this.findBestToken = function(arr, t, player) {
    var tokenPos;
    for (i = 0; i < arr.length; i++) {
      if (arr[i][0] >= 0 && arr[i][0] < t.length && arr[i][1] >= 0 && arr[i][1] < t.length) {
        if (t[arr[i][0]][arr[i][1]] != false && ((tokenPos == undefined) || (this.tokenScore(player, t[arr[i][0]][arr[i][1]]) > this.tokenScore(player, t[tokenPos[0]][tokenPos[1]])))) {
          tokenPos = [arr[i][0],
            [arr[i][1]]
          ];
        }
      }
    }
    return tokenPos;
  }
  this.tokenScore = function(player, token) {
    if (player.lastColor == token.color) {
      return player.colorBonus + 1 + token.points;
    } else {
      return token.points;
    }
  }
  this.startAndGoalToCommand = function(start, goal) {
    var diff = [goal[0] - start[0], goal[1] - start[1]];
    if (diff[0] > 0) {
      return "RIGHT";
    } else if (diff[1] > 0) {
      return "DOWN";
    } else if (diff[1] < 0) {
      return "UP";
    } else if (diff[0] < 0) {
      return "LEFT";
    } else {
      return "EAT";
    }
  }
}
Melon Fricative
sumber
1

KindaRandomAI

Setiap belokan, lakukan hal berikut: Jika ada token di posisi Anda, "MAKAN". Jika tidak, bergeraklah ke arah yang layak secara acak, yaitu jika Anda berada di tepi kiri jangan katakan "KIRI".

kindaRandomAI = function(player1) {
    this.player1 = player1;
    this.yourMove = function(b) {
        var me;
        if (this.player1) {
            me = b.player1;
        } else {
            me = b.player2;
        }
        if (b.tokens[me.pos[0]][me.pos[1]] != false) {
            return "EAT";
        } else {
            var dirs = this.getViableDirections(b, me.pos);
            var rand = Math.floor(Math.random() * dirs.length);
            return dirs[rand];
        }
    }
    this.getViableDirections = function(b, p) {
        var dirs = [];
        if (p[0] > 0) {
            dirs.push("LEFT");
        }
        if (p[1] > 0) {
            dirs.push("UP");
        }
        if (p[1] < b.tokens.length - 1) {
            dirs.push("DOWN");
        }
        if (p[0] < b.tokens.length - 1) {
            dirs.push("RIGHT");
        }
        return dirs;
    }
}
Melon Fricative
sumber
-1 tidak sepenuhnya acak
CalculatorFeline
Itu lebih baik!.
CalculatorFeline
1

LazyBot

Hanya makan sesuatu jika dia memunculkannya. Ini tidak memiliki peluang untuk menang, tetapi tantangannya tidak ada, jadi mengapa tidak.

lazyBot = function (player1) {
    this.yourMove = function(b) {
        return "EAT";
    }
}
Bálint
sumber
1
Setiap koth memiliki EmoWolf ...
Blue
3
@ Biru Ini bukan emo 100%, ia mencoba makan.
Bálint
1

MirrorBot

Harus disebut "umpan meriam"

Deskripsi: Memutar lawan dari apa yang dilakukan pemain lain

Dasar Pemikiran: Saya ingin mendapatkan pemrograman yang nyaman di JS lagi. Ini seharusnya tidak menang

Akan mengalahkan: Tidak seorang pun

Akan kalah dari: Semua orang

function mirror(player1) {
    this.hasStarted=false;
    this.player1 = player1;
    this.opl=[0,0];
    this.yourMove = function(b){
        this.op = this.player1 ? b.player2.pos : b.player1.pos;
        out = "EAT";
        console.log(this.op);
        console.log(this.opl);
        if(this.hasStarted){
            if(this.opl[0] < this.op[0]) out = "RIGHT";
            if(this.opl[0] > this.op[0]) out = "LEFT";
            if(this.opl[1] < this.op[1]) out = "UP";
            if(this.opl[1] > this.op[1]) out = "DOWN";
        }
        this.opl = [this.op[0],this.op[1]];
        this.hasStarted = true;
        return out;
    }
}
Biru
sumber
Ada beberapa masalah dengan kode Anda. Kanan dan Kiri tidak bertolak belakang, dan definisi fungsi Anda untuk Pindah Anda bukan sintaks yang valid. Kode saya juga rusak sebelumnya, jadi dalam proses mencari dan memperbaiki masalah dalam kode saya, saya memperbaiki kode Anda juga. Anda dapat melihat kode tetap di skrip saya.
Fricative Melon
@FricativeMelon Saya memperbaiki definisi fungsi yang rusak. Saya harus melawan klaim bahwa hak tidak bertentangan.
Biru
0,0 adalah sudut kiri atas, jadi x positif benar dan x negatif kiri. jika x-pos baru nilainya lebih besar daripada x-pos lama, pemain lain bergerak ke kanan, jadi Anda harus bergerak ke kiri, dan sebaliknya. Selain itu, Anda harus menggunakan var out = "EAT";bukan out = "EAT";, karena nanti mendefinisikan variabel global. Sedikit mengalah, baris ketiga dan keempat tidak melakukan apa-apa dan bisa dihapus juga, dan opbisa berupa variabel lokal seperti outalih - alih properti.
Fricative Melon
@FricativeMelon ah, saya mengerti apa yang Anda katakan. Saya telah memperbarui kodenya. Terima kasih!
Biru
Saya memasukkan kode baru Anda ke dalam skrip, dan sekarang berfungsi. Tidak mengalahkan RandomAI :(
Fricative Melon
0

OneTarget

Temukan token yang akan memberikan poin terbanyak dalam waktu paling sedikit dan akan pergi untuk yang itu. Peringkat token warna yang sama sedikit lebih tinggi karena efek kumulatif.

function (player1) {
    this.yourMove = function (b) {
        var me = player1? b.player1: b.player2;
        var him= player1? b.player2: b.player1;
        var x = me.pos[0];
        var y = me.pos[1];
        var maxVal = -1;
        var maxX = 0;
        var maxY = 0;
        for(var i = 0;i < b.tokens.length;i++){
            for(var j = 0;j < b.tokens.length;j++){
                if(b.tokens[i][j]){
                    var dist = Math.abs(x-i) + Math.abs(y-j);
                    var val = this.valueOf(b.tokens[i][j]);
                    val /= (dist + 1);
                    if(val > maxVal){
                        maxVal = val;
                        maxX = i;
                        maxY = j;
                    }
                }
            }
        }
        if(maxY < y)
            return "UP";
        if(maxX < x)
            return "LEFT";
        if(maxY > y)
            return "DOWN";
        if(maxX > x)
            return "RIGHT";
        return "EAT";
    }
    this.valueOf = function(t){
        //how many points would it give you?
        return t.points + (this.lastColor == t.color? 2 * this.colorBonus + 1 : 0);
    }
}
MegaTom
sumber
0

QuantityPlayer

Semua yang diperhatikan QuantityPlayer adalah jumlah titik yang dia makan, bukan nilai atau warna titik-titik itu. Dia tahu bahwa meskipun semua titik berbeda, mereka harus diperlakukan sama.

QuantityBot = function(playernum) {

this.dist = function(token) {
    return (Math.abs(token[0])+Math.abs(token[1]))
}

this.yourMove = function(game_board) {

    board_size = game_board.tokens.length
    board_area = board_size * board_size
    fete = board_size = size * 2

    token_list = []
    count = curr_x = curr_y = 0
    while(count < board_area) {
        if(game_board.tokens[x][y]) {
        token_list.push([x-player.pos[0],y-player.pos[1]])
        }
        count++; x = count % board_size; y = Math.floor(count / size)
    }

    closest_token = token_list[0]
    count = 1
    while(count < token_list.length) {
        curr_token = token_list[count]
        if(dist(curr_token) < dist(closest_token)){closest_token = curr_token}

        count++
    }

    if(dist(closest_token)==0){return 'EAT'}
    else{
    if(closest_token[0] >= closest_token[1]) {if(closest_token[0]<0) {return 'LEFT'} {return 'RIGHT'}}
    else{if(closest_token[1]<0) {return 'UP'} {return 'DOWN'}}
    }

}

}
Benjamin Philippe
sumber