极小极大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之外,更喜欢
而不是C
rand()。你的解释帮助我理解了。只有一个问题。。。为什么使用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];
  }