极小极大c++;tic-tac-toe的实现 void生成移动(int gameBoard[9],列表和移动) { 对于(int i=0;i最佳分数) { 最佳分数=分数; bestMoves.clear(); bestMoves.push_back(movesList.front()); } 否则如果(分数==最佳分数) { bestMoves.push_back(movesList.front()); } gameBoard[movesList.front()]=0; movesList.pop_front(); } index=bestMoves.size(); 如果(索引>0){ 时间秒; 时间(秒); srand((uint32_t)秒); index=rand()%index; } 返回最佳移动[索引]; } 我在C++中创建了一个TIC TAC-TEPS程序,并尝试用穷举搜索树实现一个极大极小算法。 这些是我在一些网站的帮助下使用wiki编写的函数。但人工智能就是不能正常工作,有时根本无法发挥作用
有人能看一下,并请指出,如果有什么错误的逻辑 我认为它是这样工作的:极小极大c++;tic-tac-toe的实现 void生成移动(int gameBoard[9],列表和移动) { 对于(int i=0;i最佳分数) { 最佳分数=分数; bestMoves.clear(); bestMoves.push_back(movesList.front()); } 否则如果(分数==最佳分数) { bestMoves.push_back(movesList.front()); } gameBoard[movesList.front()]=0; movesList.pop_front(); } index=bestMoves.size(); 如果(索引>0){ 时间秒; 时间(秒); srand((uint32_t)秒); index=rand()%index; } 返回最佳移动[索引]; } 我在C++中创建了一个TIC TAC-TEPS程序,并尝试用穷举搜索树实现一个极大极小算法。 这些是我在一些网站的帮助下使用wiki编写的函数。但人工智能就是不能正常工作,有时根本无法发挥作用,c++,brute-force,minimax,C++,Brute Force,Minimax,有人能看一下,并请指出,如果有什么错误的逻辑 我认为它是这样工作的: Minimax:此函数以非常大的-ve数字作为最佳分数开始,目标是最大化该数字。它调用minMove函数。如果新分数>最佳分数,则最佳分数=新分数 MinMove:此函数用于评估游戏板。如果游戏结束,它会返回-无限或+无限,取决于谁赢了。若游戏正在进行,该函数以最大+无穷大值作为最佳分数开始,目标是尽可能地将其最小化。轮到对手玩家时,它调用MaxMove。(因为球员轮流轮换)。 如果得分最佳得分,则最佳得分=得分 Minmov
Minimax
:此函数以非常大的-ve数字作为最佳分数开始,目标是最大化该数字。它调用minMove
函数。如果新分数>最佳分数,则最佳分数=新分数
MinMove
:此函数用于评估游戏板。如果游戏结束,它会返回-无限或+无限,取决于谁赢了。若游戏正在进行,该函数以最大+无穷大值作为最佳分数开始,目标是尽可能地将其最小化。轮到对手玩家时,它调用MaxMove
。(因为球员轮流轮换)。
如果得分<最佳得分,则最佳得分=得分
MaxMove
:此函数用于评估游戏板。如果游戏结束,它会返回-无限或+无限,取决于谁赢了。若游戏正在进行,这个函数以最小无穷大值作为最佳分数开始,目标是尽可能地使其最大化。轮到对手玩家时,它调用MinMove
。(因为球员轮流轮换)。
如果得分>最佳得分,则最佳得分=得分
Minmove
和maxmmove
相互递归调用,maxmmove
最大化值和Minmove
最小化值。最后,它返回可能的最佳移动列表
如果有超过1个最佳移动,则随机选取其中一个作为计算机的移动 在
MiniMax
中,MinMove(gameBoard,playerTurn)
应该是MinMove(gameBoard,-playerTurn)
就像在MaxMove
中一样
当您使用MinMove
和maxmmove
时,您的求值函数应该是绝对的。我的意思是+infinity
对于XWIN
和-infinity
用于OWIN
。因此,MinMove
只能在player==1
时使用,而maxmmove只能在player==1
时使用,因此该参数变得无用。因此MiniMax
只能由player==1
使用
我对您的代码做了一些更改,它可以工作()。[OT]:您应该只调用一次
srand((uint32_t)secs)代码>(主要)。除了不每次播种prng之外,更喜欢
而不是Crand()。你的解释帮助我理解了。只有一个问题。。。为什么使用MaxMove返回-ve?是因为O是一个最小化的玩家,它总是会评估-ve,我们需要一个正的分数来与bestScore(在这个例子中是-infinity)进行比较吗?@ChandanPednekar:对不起,我不明白你的问题,你能澄清一下吗?
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];
}