void generate_moves(int gameBoard[9], list<int> &moves)
{
for (int i = 0; i < 9; i++)
{
if (gameBoard[i] == 0){
moves.push_back(i);
}
}
}
int evaluate_position(int gameBoard[9], int playerTurn)
{
state currentGameState = checkWin(gameBoard);
if (currentGameState != PLAYING)
{
if ((playerTurn == 1 && currentGameState == XWIN) || (playerTurn == -1 && currentGameState == OWIN))
return +infinity;
else if ((playerTurn == -1 && currentGameState == XWIN) || (playerTurn == 1 && currentGameState == OWIN))
return -infinity;
else if (currentGameState == DRAW)
return 0;
}
return -1;
}
int MinMove(int gameBoard[9], int playerTurn)
{
//if (checkWin(gameBoard) != PLAYING) { return evaluate_board(gameBoard); };
int pos_val = evaluate_position(gameBoard, playerTurn);
if (pos_val != -1) return pos_val;
int bestScore = +infinity;
list<int> movesList;
generate_moves(gameBoard, movesList);
while (!movesList.empty())
{
gameBoard[movesList.front()] = playerTurn;
int score = MaxMove(gameBoard, playerTurn*-1);
if (score < bestScore)
{
bestScore = score;
}
gameBoard[movesList.front()] = 0;
movesList.pop_front();
}
return bestScore;
}
int MaxMove(int gameBoard[9], int playerTurn)
{
//if (checkWin(gameBoard) != PLAYING) { return evaluate_board(gameBoard); };
int pos_val = evaluate_position(gameBoard, playerTurn);
if (pos_val != -1) return pos_val;
int bestScore = -infinity;
list<int> movesList;
generate_moves(gameBoard, movesList);
while (!movesList.empty())
{
gameBoard[movesList.front()] = playerTurn;
int score = MinMove(gameBoard, playerTurn*-1);
if (score > bestScore)
{
bestScore = score;
}
gameBoard[movesList.front()] = 0;
movesList.pop_front();
}
return bestScore;
}
int MiniMax(int gameBoard[9], int playerTurn)
{
int bestScore = -infinity;
int index = 0;
list<int> movesList;
vector<int> bestMoves;
generate_moves(gameBoard, movesList);
while (!movesList.empty())
{
gameBoard[movesList.front()] = playerTurn;
int score = MinMove(gameBoard, playerTurn);
if (score > bestScore)
{
bestScore = score;
bestMoves.clear();
bestMoves.push_back(movesList.front());
}
else if (score == bestScore)
{
bestMoves.push_back(movesList.front());
}
gameBoard[movesList.front()] = 0;
movesList.pop_front();
}
index = bestMoves.size();
if (index > 0) {
time_t secs;
time(&secs);
srand((uint32_t)secs);
index = rand() % index;
}
return bestMoves[index];
}
我用C ++创建了一个tic tac toe程序,并尝试使用详尽的搜索树实现MiniMax算法。 这些是我使用wiki并在某些网站的帮助下编写的函数。但人工智能只是不能正常工作,有时根本不会发挥作用。
有人可以看看,请指出逻辑是否有问题?
这就是我认为它的工作方式:
Minimax
:此功能以非常大的-ve数作为最佳分数开始,目标是最大化该数字。它调用minMove
函数。如果新得分>最佳分数,然后最佳分数=新分数......
MinMove
:此功能评估游戏板。如果游戏超过那么它会返回-infinity或+ infinity,具体取决于谁赢了。如果游戏正在进行,此功能将以最大+无穷大值作为最佳分数开始,目标是尽可能减少它。它与对手玩家的回合调用MaxMove
。 (因为球员交替轮流)。
如果得分<最佳分数然后最佳分数=分数。 ...
MaxMove
:此功能评估游戏板。如果游戏超过那么它会返回-infinity或+ infinity,具体取决于谁赢了。如果游戏正在进行,则此功能以最小-infinity值作为最佳分数开始,目标是尽可能地最大化它。它与对手玩家的回合调用MinMove
。 (因为球员交替轮流)。
如果得分>最佳分数然后最佳分数=分数。 ...
Minmove
和MaxMove
相互递归地相互呼叫,MaxMove
最大化值,MinMove
最小化它。最后,它返回最佳移动列表。
如果有超过1个最佳动作,则随机选择它们作为计算机的移动。
答案 0 :(得分:0)
在MiniMax
中,MinMove(gameBoard, playerTurn)
应为MinMove(gameBoard, -playerTurn)
MaxMove
。
当您使用MinMove
和MaxMove
时,您的评估函数应该是绝对的。我的意思是+infinity
XWIN
和-infinity
OWIN
。因此,MinMove
只能在player == -1
和MaxMove player == 1
时使用,因此参数变得无用。因此MiniMax
只能由player == 1
使用。
我已对您的代码进行了一些更改,但它可以正常运行(https://ideone.com/Ihy1SR)。