【发布时间】:2020-10-21 21:07:01
【问题描述】:
我制作了一个 tic tac toe discord 机器人来和(对抗)我玩 tic tac toe。该算法工作得很好,但它似乎从来没有阻止我或赢得胜利,即使我试图做到。我已经尝试了很多调试,我真的不认为有什么问题,我只是觉得我的逻辑有点不对劲。这是我的 MiniMax 函数。
function MINIMAX(Board, Depth, MaximizingScore, CTS) {
var value = 0;
var score = EvaluateBoard(Board);
if (score == 10) {
return score;
}
// If Minimizer has won the game
// return his/her evaluated score
if (score == -10) {
return score;
}
if(IsTerminalState(Board) && CTS) {
return 0;
}
var PossibleMoves = FindPossibleMoves(Board);
if(MaximizingScore) {
//When AI is calculated
var BestVal = -1000;
for(var i = 0; i < PossibleMoves.length; i++) {
var Ii = PossibleMoves[i];
Board[Ii] = "X";
BestVal = Math.max(BestVal, MINIMAX(Board, Depth + 1, !MaximizingScore, true));
Board[Ii] = "N"
}
return BestVal;
} else {
//When Player is calculated
var BestVal = 1000;
for(var i = 0; i < PossibleMoves.length; i++) {
var Ii = PossibleMoves[i];
Board[Ii] = "O";
BestVal = Math.min(BestVal, MINIMAX(Board, Depth + 1, !MaximizingScore, true));
Board[Ii] = "N"
}
return BestVal;
}
}
我使用类似的功能来找到可能的最佳移动。这里是:
function FindBestMove(Board) {
var bestVal = -1000;
var bestMove = 0;
var PossibleMoves = FindPossibleMoves(Board);
for(var i = 0; i < PossibleMoves.length; i++) {
var Ii = PossibleMoves[i];
Board[Ii] = "X";
moveVal = MINIMAX(Board, 0, false, false);
console.log(moveVal);
Board[Ii] = "N"
if(moveVal > bestVal) {
bestMove = Ii;
bestVal = moveVal;
}
}
return bestMove;
}
我查看了多个网站,它们似乎都使用相同的算法。我不知道我的逻辑有什么问题,但我做了一点调试,发现 Minimax 几乎总是返回 -10。我认为问题在于它为每个值发送-10,它只是选择它可以放入某些东西的第一个空间(因为它不能将最大值设置得更高,因为-10!> -10。)但是什么我需要一点帮助是为什么它认为阻止或获胜与失败一样值得。这是它返回的值的屏幕截图。
它偶尔会返回 0,但不是很频繁。
我并不是在寻找代码,我只是想看看我的算法出了什么问题。抱歉,如果这篇文章有点糟糕,我只是不确定到底出了什么问题。我已经调试了很长时间,以至于我不知道还能做什么。谢谢=)
哦,这是我遇到的问题的代码 sn-p。如果你把这个 AI 放在几乎任何这样的情况下,我们都会得到相同的结果。
console.log(FindBestMove(["O", "X", "N", "X", "X", "O", "N", "O", "X"]));//2 would be the 3nd element in the array. This would not be ideal because we would want to block X in this case, so this results in a loose.
function calculateWinX(gamearr) {
//HORIZONTAL
if(gamearr[0]=="X" && gamearr[1]=="X" && gamearr[2]=="X") {return true}
if(gamearr[3]=="X" && gamearr[4]=="X" && gamearr[5]=="X") {return true}
if(gamearr[6]=="X" && gamearr[7]=="X" && gamearr[8]=="X") {return true}
//VERTICAL
if(gamearr[2]=="X" && gamearr[5]=="X" && gamearr[8]=="X") {return true}
if(gamearr[1]=="X" && gamearr[4]=="X" && gamearr[7]=="X") {return true}
if(gamearr[0]=="X" && gamearr[3]=="X" && gamearr[6]=="X") {return true}
//DIAGONAL
if(gamearr[0]=="X" && gamearr[4]=="X" && gamearr[8]=="X") {return true}
if(gamearr[6]=="X" && gamearr[4]=="X" && gamearr[2]=="X") {return true}
return false;
}
function calculateWinO(gamearr) {
//HORIZONTAL
if(gamearr[0]=="O" && gamearr[1]=="O" && gamearr[2]=="O") {return true}
if(gamearr[3]=="O" && gamearr[4]=="O" && gamearr[5]=="O") {return true}
if(gamearr[6]=="O" && gamearr[7]=="O" && gamearr[8]=="O") {return true}
//VERTICAL
if(gamearr[2]=="O" && gamearr[5]=="O" && gamearr[8]=="O") {return true}
if(gamearr[1]=="O" && gamearr[4]=="O" && gamearr[7]=="O") {return true}
if(gamearr[0]=="O" && gamearr[3]=="O" && gamearr[6]=="O") {return true}
//DIAGONAL
if(gamearr[0]=="O" && gamearr[4]=="O" && gamearr[8]=="O") {return true}
if(gamearr[6]=="O" && gamearr[4]=="O" && gamearr[2]=="O") {return true}
return false;
}
function IsTerminalState(gamearr) {
return !gamearr.includes("N");
}
function FindPossibleMoves(gamearr) {
var PossibleMoves = [];
for(var i = 0; i < 9; i++) {
if(gamearr[i]==="N") {
PossibleMoves.push(i);
}
}
return PossibleMoves;
}
function EvaluateBoard(gamearr) {
if(calculateWinO(gamearr)) {
return 10;
}
if(calculateWinX(gamearr)) {
return -10;
}
}
function MINIMAX(Board, Depth, MaximizingScore, CTS) {
var value = 0;
var score = EvaluateBoard(Board);
if (score == 10) {
return score;
}
// If Minimizer has won the game
// return his/her evaluated score
if (score == -10) {
return score;
}
if(IsTerminalState(Board) && CTS) {
return 0;
}
var PossibleMoves = FindPossibleMoves(Board);
if(MaximizingScore) {
//When AI is calculated
var BestVal = -1000;
for(var i = 0; i < PossibleMoves.length; i++) {
var Ii = PossibleMoves[i];
Board[Ii] = "X";
BestVal = Math.max(BestVal, MINIMAX(Board, Depth + 1, !MaximizingScore, true));
Board[Ii] = "N"
}
return BestVal;
} else {
//When Player is calculated
var BestVal = 1000;
for(var i = 0; i < PossibleMoves.length; i++) {
var Ii = PossibleMoves[i];
Board[Ii] = "O";
BestVal = Math.min(BestVal, MINIMAX(Board, Depth + 1, !MaximizingScore, true));
Board[Ii] = "N"
}
return BestVal;
}
}
function FindBestMove(Board) {
var bestVal = -1000;
var bestMove = 0;
var PossibleMoves = FindPossibleMoves(Board);
for(var i = 0; i < PossibleMoves.length; i++) {
var Ii = PossibleMoves[i];
Board[Ii] = "X";
moveVal = MINIMAX(Board, 0, false, false);
console.log(moveVal);
Board[Ii] = "N"
if(moveVal > bestVal) {
bestMove = Ii;
bestVal = moveVal;
}
}
return bestMove;
}
【问题讨论】:
-
请做一个可运行的例子,否则很难帮你找到你的逻辑缺陷
-
@IvanD 这是一个不和谐的机器人,我不知道如何制作一个可运行的示例,因为它只是发送消息和东西。我会尝试举个例子,但可能需要一点时间 =)
-
例如模拟输出到
console.logs :) -
@IvanD 完成了 sn-p。
标签: javascript tic-tac-toe minimax