用于tic tac toe的minimax c ++实现

时间:2014-07-17 15:46:03

标签: c++ brute-force minimax

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。 (因为球员交替轮流)。 如果得分>最佳分数然后最佳分数=分数。 ...

MinmoveMaxMove相互递归地相互呼叫,MaxMove最大化值,MinMove最小化它。最后,它返回最佳移动列表。

如果有超过1个最佳动作,则随机选择它们作为计算机的移动。

1 个答案:

答案 0 :(得分:0)

MiniMax中,MinMove(gameBoard, playerTurn)应为MinMove(gameBoard, -playerTurn) MaxMove

当您使用MinMoveMaxMove时,您的评估函数应该是绝对的。我的意思是+infinity XWIN-infinity OWIN。因此,MinMove只能在player == -1和MaxMove player == 1时使用,因此参数变得无用。因此MiniMax只能由player == 1使用。

我已对您的代码进行了一些更改,但它可以正常运行(https://ideone.com/Ihy1SR)。