2

I am trying to write AI algorithm using MinMax to checkers game. Everything was fine before final test... The computer chooses any piece and after that he is coming to my guys. He really wants to die fast. Here is my code:

public MoveAndPoints MinMax(Dictionary<int, Field> gameBoard, string myColor, Boolean maximizingPlayer, int depth)
    {
        MoveAndPoints bestValue = new MoveAndPoints();
        if (0 == depth)
        {
            return new MoveAndPoints(((myColor == enemyColor) ? 1 : -1) * evaluateGameBoard(gameBoard, myColor), bestValue.move);
        }
            
        MoveAndPoints val = new MoveAndPoints();
        if (maximizingPlayer)
        {
            bestValue.points = int.MinValue;
            foreach (Move move in GetPossibleMoves(gameBoard, myColor))
            {
                gameBoard = ApplyMove(gameBoard, move);
                bestValue.move = move;
                val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), false, depth - 1);
                bestValue.points = Math.Max(bestValue.points, val.points);
                gameBoard = RevertMove(gameBoard, move);
            }
            return bestValue;
        }
        else
        {
            bestValue.points = int.MaxValue;
            foreach (Move move in GetPossibleMoves(gameBoard, myColor))
            {
                gameBoard = ApplyMove(gameBoard, move);
                val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), true, depth - 1);
                bestValue.points = Math.Min(bestValue.points, val.points);
                gameBoard = RevertMove(gameBoard, move);
            }
            return bestValue;
        }
    }

This is my heuretic:

public int evaluateGameBoard(Dictionary<int, Field> gameBoard, string color)
{
    return Extend.GetNumberOfPieces(gameBoard, color) - Extend.GetNumberOfPieces(gameBoard, Extend.GetEnemyPlayerColor(color));
}

For example, I have that scenario:

enter image description here


Instead of move any other place he is choosing to die:

enter image description here

If i choose death myself he only kills me because of fact that he must because this is his only move. Can someone help me fix this? I think problem is inside MinMax. I am almost sure this is not very problematic but i really can not find it :(

Here is depth 3 for my tree: enter image description here

Brarord
  • 611
  • 5
  • 18

1 Answers1

1

I don't have all your code, so I can't verify these completely. But, I believe at least one of your problems is that you are mixing the colors between the players. In your MinMax calls you are passing the same color for both positions:

Here is the call inside the maximizing player:

val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), false, depth - 1);

Here is the other call:

val = MinMax(gameBoard, Extend.GetEnemyPlayerColor(myColor), true, depth - 1);

You are correctly switching whether you are maximizing or not, but you shouldn't be switching the color between the players.

In practice really want to keep track of who the player is at the root, because all of the evaluations are relative to the player at the root. In that case you'd just pass color through the whole time and never use the enemies color except in the evaluation function.

Nathan S.
  • 5,244
  • 3
  • 45
  • 55
  • Hmm i totally don't get it. I mean why i `shouldn't` switch colors? If i will not then i will simulate the movements only of 1 player without paying attention to where player number 2 will go. Could you explain this a little to me? – Brarord Jul 19 '20 at 09:38
  • @Brarord You have to switch players to get the movement working, but you don't want to switch how you evaluate. That is, the player at the root is doing the search and evaluating from their perspective, so all states should be evaluated from the perspective of the max player at the root. – Nathan S. Jul 19 '20 at 15:32
  • @Brarord I suggest adding another variable `rootColor` which doesn't change, and then use that when calling `evaluateGameBoard`. – Nathan S. Jul 19 '20 at 15:39