Search code examples
c#algorithmartificial-intelligenceminimaxalpha-beta-pruning

Understanding the Minimax Algorithm


I am trying to create an AI opponent for a two player 8x8 board game. After a research I found Minimax algorithm handy enough to do the job. The AI opponent I am creating will play against an other AI opponent or Human.

I have a doubt in understanding the minimax algorithm.

I am trying to create just ONE AI opponent but the explanations found on web says that I need to write code for both players(Minimum player and Maximum player) as I understand from the pseudo code below.

MinMax (GamePosition game) {
  return MaxMove (game);
}

MaxMove (GamePosition game) {
  if (GameEnded(game)) {
    return EvalGameState(game);
  }
  else {
    best_move < - {};
    moves <- GenerateMoves(game);
    ForEach moves {
       move <- MinMove(ApplyMove(game));
       if (Value(move) > Value(best_move)) {
          best_move < - move;
       }
    }
    return best_move;
  }
}

MinMove (GamePosition game) {
  best_move <- {};
  moves <- GenerateMoves(game);
  ForEach moves {
     move <- MaxMove(ApplyMove(game));
     if (Value(move) > Value(best_move)) {
        best_move < - move;
     }
  }

  return best_move;
}

I can further understand that Maximum player will be the AI I am going to develop and the minimum player is the opponent.

My question is why I have to write code for both Minimum and Maximum player to return the best move ?

The pseudo code given below is based on C#.

Thanks in advance.


Solution

  • You just have to search the best solution in worst scenario for both players that why it's call minmax, you don't need more then that:

    function minimax( node, depth )     
       if node is a terminal node or depth <= 0:        
           return the heuristic value of node  
    
       α = -∞    
       foreach child in node:          
          α = max( a, -minimax( child, depth-1 ) )  
    
       return α
    

    node is a game position, child in node is the next move (from list of all available moves), depth is what maximum move to search of both players together.

    You probably can't run all the possible moves on board 8x8 (depend how many options of next move you have) for example if each your you have 8 different possible moves and the game end after 40 moves (should be the worst case) then you get 8^40 positions. Computer will take tens years or even much more to solve it, that why you need the depth parameter and the use heuristic function (for example random forest tree) to know how good the game position without check all the options.

    A bit better algorithm for minmax is Alpha-Beta pruning that finish the search once he found his goal (β parameter):

    function negamax( node, depth, α, β, color )  
       if node is a terminal node or depth = 0     
           return color * the heuristic value of node  
    
       foreach child of node          
           value = -negamax( child, depth-1, -β, -α, -color )  
    
       if value ≥ β                
          return value /** Alpha-Beta cut-off */  
    
      if value ≥ α       
         α = value              
    
      return α
    

    Better to thy use first a game without a lot of positions (for example tic tac toe).