Search Unity

Minimax implementation problem

Discussion in 'Scripting' started by HamzaEzzRa, Feb 27, 2020.

  1. HamzaEzzRa

    HamzaEzzRa

    Joined:
    Sep 9, 2019
    Posts:
    2
    I'm trying to make a board game similar to chess, but I can't figure out a correct way to implement the minimax search algorithm for the AI movement. Two days in, this is what I came up with:

    Code (CSharp):
    1.  
    2.     public void MoveAI()
    3.     {
    4.         if (Preserve.againstAI)  //Verify if playing against AI
    5.         {
    6.             Tuple<BasePiece, Cell, int> minimaxTuple = MiniMax(3, int.MinValue, int.MaxValue, false);
    7.             real = true;  //Basically saying that the next move is going to be physically applied to the board (pieces change position);
    8.             minimaxTuple.Item1.targetCell = minimaxTuple.Item2;
    9.             minimaxTuple.Item1.Move();  //Applying the best move given by minimax
    10.             SwitchSides(Color.black);  // Whites turn
    11.         }
    12.     }
    13.  
    14.     public Tuple<BasePiece, Cell, int> MiniMax(int depth, int alpha, int beta, bool maximizingPlayer)
    15.     {
    16.         real = false;  //Pieces movement doesn't appear physically in the board, but they change cells
    17.         if (depth == 0 || CheckMat() || CheckNull())  // CheckNull checks if a draw occurs
    18.         {
    19.             return new Tuple<BasePiece, Cell, int>(null, null, BasePiece.numberOfWhitePieces - BasePiece.numberOfBlackPieces);
    20.         }
    21.         if (maximizingPlayer)
    22.         {
    23.             bool found = false;
    24.             int maxEval = int.MinValue;
    25.             for (int j = 0; j < allWhites.Count; j++)  //Checks all white pieces
    26.             {
    27.                 allWhites[j].CheckPathing();  //Checks every possible move for this piece and adds it to the higlightedCells list
    28.                 for (int i = 0; i < allWhites[j].highlightedCells.Count; i++)
    29.                 {
    30.                     allWhites[j].targetCell = allWhites[j].highlightedCell[i];
    31.                     allWhites[j].Move();
    32.                     int eval = MiniMax(depth - 1, alpha, beta, false).Item3;
    33.                     UIElement.Undo();  // Pieces go back to the previous board state before previous Move() call
    34.                     maxEval = eval > maxEval ? eval : maxEval;
    35.                     alpha = eval > alpha ? eval : alpha;
    36.                     if (beta <= alpha)
    37.                     {
    38.                         found = true;
    39.                         break;
    40.                     }
    41.                 }
    42.                 if (found)
    43.                 {
    44.                     break;
    45.                 }
    46.             }
    47.             return new Tuple<BasePiece, Cell, int>(actualPiece, actualCell, maxEval);
    48.         }
    49.         else
    50.         {
    51.             bool found = false;
    52.             int minEval = int.MaxValue;
    53.             for (int j = 0; j < allBlacks.Count; j++)
    54.             {
    55.                 allBlacks[j].CheckPathing();
    56.                 for (int i = 0; i < allBlacks[j].highlightedCells.Count; i++)
    57.                 {
    58.                     allBlacks[j].targetCell = allWhites[j].highlightedCell[i];
    59.                     allBlacks[j].Move();
    60.                     int eval = MiniMax(depth - 1, alpha, beta, true).Item3;
    61.                     UIElement.Undo();
    62.                     minEval = eval < minEval ? eval : minEval;
    63.                     beta = eval < beta ? eval : beta;
    64.                     if (beta <= alpha)
    65.                     {
    66.                         found = true;
    67.                         break;
    68.                     }
    69.                 }
    70.                 if (found)
    71.                 {
    72.                     break;
    73.                 }
    74.             }
    75.             return new Tuple<BasePiece, Cell, int>(actualPiece, actualCell, minEval);
    76.         }
    77.     }
    78.  
    The result is quite messy and I end up with a bunch of pieces moving and duplicating (?) even after using a boolean (real) to keep the pieces from physically moving in the board within the minimax call. Any help is really appreciated.