KOTH: Tutti adorano i token


24

In questo gioco due giocatori si sfidano per mangiare il maggior numero di punti, ma c'è una svolta! Mangiare più gettoni in una fila dello stesso colore dà un bonus sempre crescente, ma fai attenzione, o il tuo avversario ostacolerà i tuoi piani mangiando i gettoni che desideri prima che tu possa farlo!

Regole:

  • 1 contro 1
  • n by n board (dimensione casuale tra 5x5 e 15x15)
  • Tu e il tuo avversario apparirete nella stessa cella casuale
  • In tutto il tabellone verranno generati casualmente numeri in alcune celle con valori compresi tra 1-3
  • Verranno generati token 2 * (la larghezza della scheda), ma possono esserci delle sostituzioni, quindi potrebbero essercene meno per caso.
  • Ogni numero sarà di 3 colori: rosso, verde o blu, in formato RGB esadecimale
  • Ad ogni round, il giocatore 1 si muove e il tabellone viene aggiornato, quindi il giocatore 2 si sposta e il tabellone viene aggiornato. Quindi ogni giocatore può dire efficacemente quale mossa ha fatto il giocatore precedente in base al cambiamento nello stato del tabellone. Questo continua fino alla fine del gioco, come descritto più avanti.
  • Hai 6 possibili azioni per un turno: SU, DESTRA, GIÙ, SINISTRA, MANGIARE e PASS
  • I 4 comandi di spostamento sono autoesplicativi e PUOI passare il tuo turno. Se restituisci una mossa senza senso, assumeremo che tu intendessi passare. Se provi a spostarti dal bordo della tavola, non ti muoverai. I bordi non si avvolgono.
  • EAT consuma il numero in cui ci si trova attualmente nello stesso spazio
  • Guadagni tanti punti quanti sono i numeri che consumi
  • Se mangi 2 numeri di fila dello stesso colore, ottieni +1
  • Se mangi 3 numeri di fila dello stesso colore, ottieni +2
  • Se mangi numeri m in una fila dello stesso colore, ottieni + (m-1)
  • Questi bonus vengono aggiunti cumulativamente, quindi ottenere m numeri di fila porta a m * (m-1) / 2 nel bonus totale quando si mangia un colore diverso.
  • Condizioni di fine del gioco:
    • Tutti i numeri vengono consumati
    • Sono trascorsi 4 * (la larghezza del tabellone) senza mangiare in modo efficace (solo dire "MANGIARE" senza gettone dove ti trovi non conta) che si verificano da entrambi i giocatori (qualsiasi gettone è raggiungibile in 2 * (la larghezza) si muove, quindi questo limite sarà superato solo se entrambi i giocatori non hanno in mente un singolo segnalino bersaglio)
  • La tua IA dovrebbe impiegare meno di un secondo per fare una mossa, altrimenti PASS sarà assunto come tua scelta.

Il torneo sarà round robin con un gran numero di round, diciamo 100 o 1000. Viene generata una tavola casuale, e ogni coppia ordinata di giocatori diversi viene eseguita su quella tavola. Al termine del torneo classificheremo le persone in base al punteggio totale. Quindi, anche se sei il giocatore 2 per una partita, il tuo obiettivo è comunque quello di ottenere il maggior numero di punti possibile.

Presentazione AI: la lingua supportata dal mio controller è Javascript. Sono consentiti invii multipli. Tutti inviano un costruttore per un oggetto come questo:

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

L'input player1è un valore booleano che dice se sei il giocatore 1 o no. Il costruttore deve avere la yourMovefunzione, ma può avere anche un numero qualsiasi di funzioni o valori aggiuntivi. Non definire alcuna variabile globale, inseriscile semplicemente come variabile sul tuo oggetto. Una nuova versione del tuo oggetto verrà creata all'inizio di ogni partita e yourMoveverrà chiamata su di essa, con la tavola corrente come input, in ciascuno dei tuoi turni, e dovrebbe restituire una mossa valida.

b, l'input per yourMove, è una copia della scheda corrente, ecco i costruttori, con esempi di input, anche se non puoi chiamarli tu stesso:

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]]
}

L'array token ha "false" per tutti i quadrati vuoti, e i token [a] [b] è il token in x = a, y = b, numerato a partire dall'angolo in alto a sinistra.

Controller: ecco un link al controller in GitHub. È un file html che puoi eseguire per vedere come funzionano il gioco e il round-robin, e viene fornito con due IA, uno casuale che si muove in una direzione casuale ogni turno ma mangia token nella sua posizione e un algoritmo ingenuo che vale il token più vicino che dà il maggior numero di punti. Aggiungerò ogni AI come viene inviato.

Di seguito è riportato un frammento che consente di eseguire il controller sull'intelligenza artificiale predefinita. IA attuali:

  • KindaRandomAI
  • NaiveAI
  • MirrorBot
  • HungryBot


12
Yay, un KOTH! È stato per sempre dall'ultimo.
TheNumberOne

2
D'accordo, mi amo un buon KOTH e questa sembra essere un'ottima premessa. Sono un po 'verde per js, come fa uno stato di gioco persistente tra le mosse se non possiamo salvare i risultati all'interno dell'oggetto del giocatore?
DoctorHeckle,

La larghezza della scheda è passata da qualche parte nella funzione?
TheNumberOne

@BentNeeHumor Sì, la funzione che accetta il valore player1booleano è il costruttore della tua IA, che avrà una yourMovefunzione che accetta la scheda corrente come input, come b.
Fricative Melon,

1
@DylanSp A volte non sono consentiti a causa delle possibilità di collusione, ma in questo caso la collusione avrebbe benefici minimi, quindi consentirò più invii.
Fricative Melon,

Risposte:


4

HungryBot

Utilizza un sistema a punti per aggiungere peso al valore di perseguire ciascun token. Utilizza una varietà di diversi fattori nella sua considerazione e li rivaluta ogni turno per assicurarsi che segua la migliore strategia.

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;
  }
};

Sei un programmatore Python?
CalculatorFeline

@CatsAreFluffy Non proprio ...?
Mwr247,

Pensavo fossi solo perché self:)
CalculatorFeline

Perché l'uso self? Non è thissufficiente?
Conor O'Brien,

2

Bot PATH

Acronimo sta per Pathfinding And Tree Heuristics Bot

EDIT: A partire da ora, ecco le classifiche per gli AI, con i punti

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

Collegamento al controller completo su github

Descrizione: Come NaiveAI, questo bot trova il token più vicino che gli darà il maggior numero di punti. Tuttavia, simula anche i risultati di ciascuna delle sue mosse, fino a 6 volte.

Motivazione: Dato che NaiveAI è già abbastanza buono, ho pensato di migliorarlo. Senza prima guardare il codice (grosso errore).

Beats: Tutti tranne HungryBot Perdi
: Nessuno tranne HungryBot

I problemi:

  • Non è possibile simulare una maggiore sequenza
  • Si blocca durante il calcolo del token migliore
  • Può teletrasportarsi

Ancora non so perché fosse il teletrasporto, ma l'ho risolto. Vecchio video qui: https://youtu.be/BIhSKycF9iA

Codice completo:

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;
    }
}

SLaNTbot sta rallentando la velocità di virata e consumando il 15% della mia CPU ... D: EDIT: E inoltre non mangi nulla?
Mwr247

@ Mwr247 la velocità, sì, modella ~ 2500 possibilità ogni tick. Ma per quanto riguarda il mangiare, non so esattamente perché. Come ho detto nella domanda, si teletrasporta (ovvero sposta più spazi in 1 turno) e si siede lì senza fare nulla. Ho messo un avviso appena prima del ritorno e sembra dare sempre le giuste istruzioni.
Blu

Forse questo: "La tua IA dovrebbe impiegare meno di un secondo per fare una mossa, altrimenti PASS sarà assunto come tua scelta". Non ho letto il controller, ma se impiega più di un secondo, sta assumendo PASS?
Mwr247

@ Mwr247 Lo esaminerò, ma sembra improbabile dato che ci sono voluti <1 secondo (o almeno così pensavo) sulla mia macchina. Tuttavia, non fa mai male a guardare. Grazie!
Blu

@ Mwr247 Dopo alcuni altri test, non è così. Sta prendendo decisioni quasi altrettanto velocemente (almeno per me) di NaiveAi. Inoltre, è più probabile che si verifichi il teletrasporto su grandi mappe
Blue

1

NaiveAI

A partire da r=0, guarda tutti i token a distanza di taxi rdalla tua posizione. Se ce ne sono, scegline uno che ti darebbe il punteggio più alto se lo avessi subito. Altrimenti, aumenta rdi 1 e riprova.

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";
    }
  }
}

1

KindaRandomAI

Ad ogni turno, procedi come segue: Se nella tua posizione è presente un token, "MANGIARE". Altrimenti, muoviti in una direzione percorribile a caso, cioè se sei sul bordo sinistro non dire "SINISTRA".

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;
    }
}

-1 non del tutto casuale
CalculatorFeline

Va meglio!.
CalculatorFeline


1

MirrorBot

Dovrebbe essere chiamato "cannone da foraggio"

Descrizione: sposta l'esatto contrario di quello che ha fatto l'altro giocatore

Motivazione: Volevo tornare a programmare comodamente in JS. Questo non dovrebbe vincere

Batti: nessuno

Perderà a: tutti

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;
    }
}

Ci sono alcuni problemi con il tuo codice. Right e Left non sono opposti e la definizione della funzione per yourMove non è sintassi valida. Anche il mio codice era stato rotto prima, quindi nel processo di ricerca e risoluzione del problema nel mio codice ho risolto anche il tuo codice. Puoi vedere il codice fisso nel mio script.
Fricative Melon

@FricativeMelon Ho corretto la definizione della funzione non funzionante. Devo contrastare l'affermazione secondo cui il diritto non è contrario.
Blu

0,0 è l'angolo in alto a sinistra, quindi x positiva è destra e x negativa è sinistra. se la nuova x-pos ha un valore maggiore rispetto alla vecchia x-pos, l'altro giocatore si muoveva a destra, quindi dovresti muoverti a sinistra e viceversa. Inoltre, dovresti usare var out = "EAT";invece di out = "EAT";, poiché in seguito definisce una variabile globale. Nitticchiando un po ', la terza e la quarta riga non fanno nulla e possono anche essere rimosse e oppossono essere una variabile locale come outinvece di una proprietà.
Fricative Melon

@FricativeMelon ah, ho capito cosa stai dicendo. Ho aggiornato il codice. Grazie!
Blu

Ho inserito il tuo nuovo codice nello script e ora funziona. Non batte RandomAI però :(
Fricative Melon

0

OneTarget

Trova il token che darà il maggior numero di punti nel minor tempo e andrà per quello. Posiziona i token dello stesso colore un po 'più in alto a causa dell'effetto cumulativo.

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);
    }
}

0

QuantityPlayer

Tutto il QuantityPlayer si preoccupa è della quantità di punti che mangia, non del valore o del colore dei punti. Sa che anche se tutti i punti sono diversi, dovrebbero essere trattati allo stesso modo.

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'}}
    }

}

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.