KOTH: Mọi người đều thích mã thông báo


24

Trong trò chơi này, hai người chơi cạnh tranh để ăn nhiều token đáng giá nhất, nhưng có một sự thay đổi! Ăn nhiều mã thông báo trong một hàng cùng màu mang lại một phần thưởng ngày càng tăng, nhưng xem ra, hoặc đối thủ của bạn sẽ cản trở kế hoạch của bạn bằng cách ăn các mã thông báo bạn muốn trước khi bạn có thể!

Quy tắc:

  • 1 so với 1
  • n by n board (kích thước ngẫu nhiên trong khoảng từ 5x5 đến 15x15)
  • Bạn và đối thủ của bạn sẽ sinh sản trong cùng một ô ngẫu nhiên
  • Trong suốt bảng sẽ có các số được tạo ngẫu nhiên trong một số ô có giá trị từ 1-3
  • Mã thông báo 2 * (chiều rộng của bảng) sẽ được tạo, nhưng có thể có phần ghi đè, do đó có thể có ít hơn một cách tình cờ.
  • Mỗi số sẽ là một trong 3 màu: Đỏ, Xanh lục hoặc Xanh lam, ở định dạng hex hex
  • Mỗi vòng, người chơi 1 di chuyển và bảng được cập nhật, sau đó người chơi 2 di chuyển và bảng được cập nhật. Vì vậy, mỗi người chơi có thể nói một cách hiệu quả những gì người chơi trước đó đã thực hiện dựa trên sự thay đổi trạng thái của bảng. Điều này tiếp tục cho đến khi trò chơi kết thúc, như được mô tả sau.
  • Bạn có 6 hành động có thể cho một lượt: LÊN, ĐÚNG, XUỐNG, TRÁI, ĂN và PASS
  • 4 lệnh di chuyển là tự giải thích và bạn CÓ THỂ vượt qua lượt của mình. Nếu bạn trả lại một động thái vô nghĩa, chúng tôi sẽ cho rằng bạn có nghĩa là vượt qua. Nếu bạn cố gắng di chuyển ra khỏi cạnh của bảng, bạn sẽ không di chuyển. Các cạnh không bọc.
  • ĂN tiêu thụ số bạn hiện đang ở trong cùng một không gian như
  • Bạn đạt được nhiều điểm như số lượng bạn tiêu thụ
  • Nếu bạn ăn 2 số liên tiếp cùng màu, bạn sẽ có +1
  • Nếu bạn ăn 3 số liên tiếp cùng màu, bạn sẽ có +2
  • Nếu bạn ăn số m trong một hàng cùng màu, bạn sẽ có + (m-1)
  • Những phần thưởng này được thêm vào tích lũy, do đó, việc nhận được số m liên tiếp dẫn đến tổng số m * (m-1) / 2 trong thời gian bạn ăn một màu khác nhau.
  • Điều kiện kết thúc trò chơi:
    • Tất cả số lượng được tiêu thụ
    • Các lượt 4 * (chiều rộng của bảng) đã trôi qua mà không có cách ăn hiệu quả (chỉ cần nói EAT, không có mã thông báo mà bạn không đếm được) xảy ra bởi một trong hai người chơi (bất kỳ mã thông báo nào cũng có thể truy cập được trong 2 * (chiều rộng) di chuyển, do đó, giới hạn này sẽ chỉ bị vượt qua nếu cả hai người chơi không có mã thông báo mục tiêu duy nhất)
  • AI của bạn sẽ mất ít hơn một giây để thực hiện di chuyển, PASS khác sẽ được coi là lựa chọn của bạn.

Giải đấu sẽ diễn ra vòng tròn với số lượng lớn các vòng, ví dụ 100 hoặc 1000. Một bảng ngẫu nhiên được tạo ra và mỗi cặp người chơi khác nhau được đặt hàng sẽ được chạy trên bảng đó. Sau khi giải đấu hoàn thành, chúng tôi sẽ xếp hạng mọi người theo tổng số điểm của họ. Vì vậy, ngay cả khi bạn là người chơi 2 cho một trò chơi, mục tiêu của bạn vẫn là kiếm được càng nhiều điểm càng tốt.

Gửi AI: Ngôn ngữ mà bộ điều khiển của tôi hỗ trợ là Javascript. Nhiều bài nộp được cho phép. Mọi người gửi một hàm tạo cho một đối tượng như thế này:

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

Đầu vào player1là một boolean cho biết bạn có phải là người chơi 1 hay không. yourMoveHàm tạo của bạn phải có hàm, nhưng nó cũng có thể có bất kỳ số lượng hàm hoặc giá trị bổ sung nào. Đừng xác định bất kỳ biến toàn cục nào, chỉ cần đặt chúng làm biến trên đối tượng của bạn. Một phiên bản mới của đối tượng của bạn sẽ được tạo vào đầu mỗi trận đấu và yourMovesẽ được gọi trên đó, với bảng hiện tại là đầu vào, trên mỗi lượt của bạn và sẽ trả về một nước đi hợp lệ.

b, đầu vào yourMove, là một bản sao của bảng hiện tại, đây là các hàm tạo, với các ví dụ đầu vào, mặc dù bạn không thể tự gọi chúng:

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

Mảng mã thông báo có "false" cho bất kỳ ô vuông trống nào và mã thông báo [a] [b] là mã thông báo tại x = a, y = b, được đánh số bắt đầu từ góc trên bên trái.

Trình điều khiển: Đây là một liên kết đến bộ điều khiển trong GitHub. Đó là một tệp html mà bạn có thể chạy để xem cách trò chơi và trò chơi vòng tròn hoạt động, và nó đi kèm với hai AI, một AI ngẫu nhiên di chuyển theo hướng ngẫu nhiên mỗi lượt nhưng ăn token ở vị trí của nó và thuật toán ngây thơ đi cho mã thông báo gần nhất cung cấp nhiều điểm nhất. Tôi sẽ thêm vào mỗi AI khi nó được gửi.

Dưới đây là đoạn trích cho phép bạn chạy bộ điều khiển trên AI mặc định. AI hiện tại:

  • KindaRandomAI
  • NaiveAI
  • MirrorBot
  • Đói


12
Yay, một KOTH! Nó đã được mãi mãi kể từ lần cuối cùng.
TheNumberOne

2
Đồng ý, tôi yêu tôi một KOTH tốt và đây dường như là một tiền đề tuyệt vời. Tôi hơi xanh với js, làm thế nào để một người chơi duy trì trạng thái giữa các lần di chuyển nếu chúng ta không thể lưu kết quả trong đối tượng người chơi?
DoctorHeckle

Là chiều rộng bảng thông qua bất cứ nơi nào vào chức năng?
TheNumberOne

@BentNeeHumor Có, hàm nhận trong player1boolean là hàm tạo cho AI của bạn, sẽ có một yourMovehàm lấy bảng hiện tại làm đầu vào, như b.
Dưa ma sát

1
@DylanSp Đôi khi họ không được phép do khả năng thông đồng, nhưng trong trường hợp này, thông đồng sẽ có lợi ích tối thiểu, vì vậy tôi sẽ cho phép nhiều lần gửi.
Dưa ma sát

Câu trả lời:


4

Đói

Sử dụng một hệ thống điểm để thêm trọng số vào giá trị của việc theo đuổi từng mã thông báo. Sử dụng nhiều yếu tố khác nhau trong việc xem xét và đánh giá lại chúng mỗi lượt để đảm bảo chiến lược tốt nhất.

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

Bạn có phải là lập trình viên Python?
Máy

@CatsAreFluffy Không thực sự ...?
Mwr247

Chỉ cần nghĩ rằng bạn là bởi vì self:)
Máy

Tại sao nên sử dụng self? Không thisđủ sao?
Conor O'Brien

2

Bot PATH

Từ viết tắt của từ Pathfinding And Tree Heuristic Bot

EDIT: Hiện tại, đây là bảng xếp hạng cho các AI, với các điểm

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

Liên kết đến bộ điều khiển hoàn chỉnh trên github

Mô tả: Giống như NaiveAI, bot này tìm thấy mã thông báo gần nhất sẽ cung cấp cho nó nhiều điểm nhất. Tuy nhiên, nó cũng mô phỏng kết quả của mỗi lần di chuyển của nó, tối đa 6 lần.

Đặt vấn đề: Bởi vì NaiveAI đã khá tốt rồi, mặc dù tôi sẽ làm cho nó tốt hơn. Không nhìn vào mã đầu tiên (sai lầm lớn).

Nhịp đập: Tất cả ngoại trừ HungryBot
Không thích: Không ngoại trừ HungryBot

Các vấn đề:

  • Không thể mô phỏng vệt tăng
  • Treo trong khi tính toán mã thông báo tốt nhất
  • Có thể dịch chuyển tức thời

Tôi vẫn không biết tại sao nó lại dịch chuyển tức thời, nhưng tôi đã sửa nó. Video cũ tại đây: https://youtu.be/BIhSKycF9iA

Mã đầy đủ:

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 đang làm chậm tốc độ quay xuống và ăn hết 15% CPU của tôi ... D: EDIT: Và cũng không ăn gì?
Mwr247

@ Mwr247 tốc độ, vâng, nó mô hình ~ 2500 khả năng mỗi tích tắc. Nhưng đối với việc ăn uống, tôi không biết chính xác tại sao. Giống như tôi đã nói trong câu hỏi, nó chỉ dịch chuyển tức thời (còn gọi là di chuyển nhiều khoảng trống trong 1 lượt) và ngồi đó không làm gì cả. Tôi đặt một cảnh báo ngay trước khi trở về và dường như nó đang đưa ra những chỉ dẫn đúng đắn mỗi lần.
Màu xanh

Có thể điều này: "AI của bạn sẽ mất ít hơn một giây để di chuyển, PASS khác sẽ được coi là lựa chọn của bạn." Tôi chưa đọc bộ điều khiển, nhưng nếu nó chiếm một giây, nó có giả sử PASS không?
Mwr247

@ Mwr247 Tôi sẽ xem xét điều đó, nhưng có vẻ như không chắc chắn rằng nó đã mất <1 giây (hoặc tôi cũng vậy) trên máy của tôi. Tuy nhiên, không bao giờ đau để nhìn. Cảm ơn bạn!
Màu xanh

@ Mwr247 Sau một số thử nghiệm nữa, đó không phải là nó. Nó đang đưa ra quyết định gần như nhanh chóng (ít nhất là đối với tôi) như NaiveAi. Ngoài ra, bạn có nhiều khả năng trải nghiệm dịch chuyển tức thời trên các bản đồ lớn
Blue

1

NaiveAI

Bắt đầu với r=0, nhìn vào tất cả các mã thông báo với khoảng cách taxi rtừ vị trí của bạn. Nếu có bất kỳ, chọn một trong đó sẽ cho bạn điểm cao nhất nếu bạn có nó ngay bây giờ. Nếu không, tăng thêm r1 và thử lại.

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

Mỗi lượt, hãy làm như sau: Nếu có mã thông báo ở vị trí của bạn, "ĂN". Mặt khác, di chuyển theo hướng khả thi ngẫu nhiên, tức là nếu bạn ở cạnh trái, đừng nói "TRÁI".

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 không hoàn toàn ngẫu nhiên
CalculatorFeline

Cái đó tốt hơn!.
Máy

1

LazyBot

Chỉ ăn một cái gì đó nếu anh ấy sinh sản trên đó. Điều này không có cơ hội để chiến thắng, nhưng thử thách không có một trong số này, vậy tại sao không.

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

1
Mỗi koth đều có EmoWolf ...
Blue

3
@Blue Không phải là 100% emo, nó cố ăn.
Bálint


1

MirrorBot

Nên gọi là "bia đỡ đạn"

Mô tả: Di chuyển hoàn toàn ngược lại với những gì người chơi khác đã làm

Đặt vấn đề: Tôi muốn có được lập trình thoải mái trong JS một lần nữa. Điều này không nên chiến thắng

Sẽ đánh bại: Không ai

Sẽ thua: Mọi người

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

Có một vài vấn đề với mã của bạn. Phải và trái không ngược nhau và định nghĩa hàm của bạn cho cú pháp của bạn không phải là cú pháp hợp lệ. Mã của tôi cũng bị hỏng trước đó, vì vậy trong quá trình tìm và sửa lỗi trong mã của tôi, tôi cũng đã sửa mã của bạn. Bạn có thể nhìn vào mã cố định trong kịch bản của tôi.
Dưa ma sát

@FricativeMelon Tôi đã sửa định nghĩa hàm bị hỏng. Tôi phải chống lại tuyên bố rằng quyền không ngược lại.
Màu xanh

0,0 là góc trên cùng bên trái, vì vậy dương x là phải và x âm trái. nếu x-pos mới có giá trị lớn hơn x-pos cũ, thì người chơi khác di chuyển sang phải, vì vậy bạn nên di chuyển sang trái và ngược lại. Ngoài ra, bạn nên sử dụng var out = "EAT";thay vì out = "EAT";, vì sau này xác định một biến toàn cục. Nitpicking một chút, dòng thứ ba và thứ tư không làm gì cả và cũng có thể được loại bỏ, và opcó thể là một biến cục bộ như outthay vì một thuộc tính.
Dưa ma sát

@FricativeMelon ah, tôi hiểu những gì bạn đang nói. Tôi đã cập nhật mã. Cảm ơn bạn!
Màu xanh

Tôi đặt mã mới của bạn vào tập lệnh và nó đang hoạt động. Không đánh bại RandomAI mặc dù :(
Fricative Melon

0

Nhắm mục tiêu

Tìm mã thông báo sẽ cho nhiều điểm nhất trong thời gian ít nhất và sẽ đi cho mã đó. Xếp hạng mã thông báo cùng màu cao hơn một chút vì hiệu ứng tích lũy.

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

Số lượng

Tất cả các Số lượng quan tâm là số lượng các chấm anh ta ăn, không phải giá trị hoặc màu sắc của các chấm. Anh ta biết rằng mặc dù tất cả các dấu chấm là khác nhau, chúng nên được đối xử như nhau.

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

}

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.