我正在尝试使用minimax算法实现TicTacToe AI。
当轮到AI播放时,我会调用ComputerTurn(它接收电路板状态,一组跟踪方形是X,O还是空的整数)。然后ComputerTurn调用minimax(minimax算法)和win(连续检查3)。
当我运行脚本时,算法总是决定返回最低合法游戏。 IE,只要左上方(方块0)可用,它将始终首先返回它。如果采用该方格,它将返回顶部中间(图块1)等。
我不确定这里发生了什么,我的传统调试技术(Debug.Log或print)导致Unity在我想看的许多点上崩溃。
void ComputerTurn(int[] board)
{
int move = -1;
int score = -2;
int i;
for (i = 0; i < 9; ++i)
{
if (board[i] == 0)
{
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if (tempScore > score)
{
score = tempScore;
move = i;
}
}
}
board[move] = 1;
if (PlayerTurn == 1)
{
//Draw an O
Board[move] = -1;
}
else
{
//Draw an X
Board[move] = 1;
}
//Changes to player's turn
}
int minimax(int[] board, int player)
{
int winner = win(board);
if (winner != 0) return winner * player;
int move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for (i = 0; i < 9; ++i)
{//For all moves,
if (board[i] == 0)
{//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player * -1);
if (thisScore > score)
{
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if (move == -1) return 0;
return score;
}
int win(int[] board)
{
//determines if a player has won, returns 0 otherwise.
int[,] wins = new int[8, 3] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } };
int i;
for (i = 0; i< 8; ++i)
{
if (board[wins[i, 0]] != 0 &&
board[wins[i, 0]] == board[wins[i, 1]] &&
board[wins[i, 0]] == board[wins[i, 2]])
{
return board[wins[i, 2]];
}
}
return 0;
}
答案 0 :(得分:1)
它并不总是返回第一个空单元格。例如,尝试用[0,0,0,-1,0,-1,1,0,1]位置提供它:它不会返回0,而是选择4。您的实现不包含任何错误。
问题在于算法。由于你的体重函数只能得到1,0或-1,你的程序只能看到是否有可能在该回合中获胜,但是看不到强烈动作(高胜利输出)和弱动作之间的任何差异(获胜是可能的,但不太可能)。它可以过滤掉松动的动作,如您所提供的示例所示。
答案 1 :(得分:0)
编辑:如何将其标记为已解决
我发现了发生了什么。
board[move] = 1;
if (PlayerTurn == 1)
{
//Draw an O
Board[move] = -1;
}
else
{
//Draw an X
Board[move] = 1;
}
//Changes to player's turn
实际应该是
Board[move] = 1;
if (PlayerTurn == 1)
{
//Draw a Y
}
else
{
//Draw an X
}
//Change turn
我的球员转身方式也出现了错误。感谢任何看过我问题的人。