我正在为井字游戏中的 minimax 算法苦苦挣扎

问题描述 投票:0回答:0

我目前正在尝试使用 minimax 算法制作井字游戏。我在这个项目中使用带有 p5js 框架的 JavaScript。

这里是 sketch.js 代码:

var rows = 3;
var cols = 3;
var scl = 1;
var board_width = cols * 100 * scl;
var board_height = rows * 100 * scl;
var board;
let player = 'x';
let ai = 'o';
let playerTurn;
let winner;

var resetBtn;

function setup() {
  
  createCanvas(400, 300);

  resetGame();

  resetBtn = createButton("Reset");
  resetBtn.position(320, 50);
  resetBtn.size(60, 20);
}

function draw() {

  resetBtn.mouseClicked(resetGame);

  winner = checkWinner();

  
  if (winner == 'x' || winner == 'o') {
    console.log(winner);
  }
  else if (winner == 't') {
    console.log("Tie");
  }
  else {
    if (playerTurn == false) {
      aiMove();
      playerTurn = true;
    }
  }

  drawBoard();
  
  
}

function mousePressed() {
  if (playerTurn == true) {
    for (let i = 0; i < rows; i++) {
      for (let j = 0; j < cols; j++) {
        if (mouseX > j * 100 && mouseX < (j * 100 + 100) && mouseY > i * 100 && mouseY < (i * 100 + 100)) {
          board[i][j] = player;
          playerTurn = false;
        }
      }
    }
  }
}

function aiMove() {
  let bestScore = -2;
  let score;
  let moveSpot = [];

  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      if (board[i][j] == ' ') {
        board[i][j] = ai;
        score = miniMax(board, false);
        board[i][j] = ' ';
        if (score > bestScore) {
          bestScore = score;
          moveSpot = {i, j};
        }
      }
    }
  }
  board[moveSpot.i][moveSpot.j] = ai;

}

function miniMax(board, isMaximizing) {
  let result = checkWinner();

  if (result == 'x') {
    return -1;
  }
  else if (result == 'o') {
    return 1;
  }
  else if (result == 't') {
    return 0;
  }

  else if (isMaximizing) {
    let bestScore = -2;
    let score;
    for (let i = 0; i < rows; i++) {
      for (let j = 0; j < cols; j++) {
        if (board[i][j] == ' ') {
          board[i][j] = ai;
          score = miniMax(board, false);
          board[i][j] = ' ';
          bestScore = max(score, bestScore);
        }
      }
    }
    return bestScore;
  }
  else {
    let bestScore = 2;
    let score;
    for (let i = 0; i < rows; i++) {
      for (let j = 0; j < cols; j++) {
        if (board[i][j] == ' ') {
          board[i][j] = player;
          score = miniMax(board, true);
          board[i][j] = ' ';
          bestScore = min(score, bestScore);
        }
      }
    }
    return bestScore;
  }

}

function checkWinner() {
  
  let w = null;
  
  if (board[0][0] == 'x' && board[0][1] == 'x' && board[0][2] == 'x' ||
            board[1][0] == 'x' && board[1][1] == 'x' && board[1][2] == 'x' ||
            board[2][0] == 'x' && board[2][1] == 'x' && board[2][2] == 'x' ||
            board[0][0] == 'x' && board[1][0] == 'x' && board[2][0] == 'x' ||
            board[0][1] == 'x' && board[1][1] == 'x' && board[2][1] == 'x' ||
            board[0][2] == 'x' && board[1][2] == 'x' && board[2][2] == 'x' ||
            board[0][0] == 'x' && board[1][1] == 'x' && board[2][2] == 'x' ||
            board[2][0] == 'x' && board[1][1] == 'x' && board[0][2] == 'x') {
                return 'x';
        }
        else if (board[0][0] == 'o' && board[0][1] == 'o' && board[0][2] == 'o' ||
            board[1][0] == 'o' && board[1][1] == 'o' && board[1][2] == 'o' ||
            board[2][0] == 'o' && board[2][1] == 'o' && board[2][2] == 'o' ||
            board[0][0] == 'o' && board[1][0] == 'o' && board[2][0] == 'o' ||
            board[0][1] == 'o' && board[1][1] == 'o' && board[2][1] == 'o' ||
            board[0][2] == 'o' && board[1][2] == 'o' && board[2][2] == 'o' ||
            board[0][0] == 'o' && board[1][1] == 'o' && board[2][2] == 'o' ||
            board[2][0] == 'o' && board[1][1] == 'o' && board[0][2] == 'o') {
                return 'o';
        }

        let full = 0;
        for (let i = 0; i < 3; i++) {
            for (let j = 0; j < 3; j++) {
                if (board[i][j] == 'x' || board[i][j] == 'o') {
                    full ++;
                }
            }
        }

        if (full == 9) {
            return 't';
        }

        return winner;
    
  return w;
}

function drawBoard() {
  // draw board
  stroke(0);
  strokeWeight(7);
  line(board_width / 3, 0, board_width / 3, board_height);
  line(board_width / 3 * 2, 0, board_width / 3 * 2, board_height);
  line(0, board_height / 3, board_width, board_height / 3);
  line(0, board_height / 3 * 2, board_width, board_height / 3 * 2);

  for (let i = 0; i < rows; i++) {
    for (let j = 0; j < cols; j++) {
      if (board[i][j] == 'o') {
        circle(j * 100 + 50, i * 100 + 50, 80);
      }
      else if (board[i][j] == 'x') {
        line(j * 100 + 10, i * 100 + 10, j * 100 + 80, i * 100 + 80);
        line(j * 100 + 80, i * 100 + 10, j * 100 + 10, i * 100 + 80);
      }
    }
  }
}

function resetGame() {
  clear();
  winner = null;
  board = [];
  playerTurn = true;
  background(255);

  for (let i = 0; i < rows; i++) {
    let row = [];
    for (let j = 0; j < cols; j++) {
      row[j] = ' ';
    }
    board.push(row);
  }
}

问题如图所示。作为玩家,如果您先选择位置 2,然后选择位置 4,然后选择位置 6,那么 ai 不会去位置 9 获胜,而是去位置 3。 screenshot

我在本网站的示例中尝试了这种策略:

https://www.freecodecamp.org/news/how-to-make-your-tic-tac-toe-game-unbeatable-by-using-the-minimax-algorithm-9d690bad4b37/

并得到相似的结果。

这是算法实现的问题还是其他什么?

javascript algorithm p5.js tic-tac-toe minimax
© www.soinside.com 2019 - 2024. All rights reserved.