Gomoku (5 in a row) Negamax AI not stopping me from winning

65 Views Asked by At

I am working on an AI for Gomoku (5 in a row) but has some issues with the AI not stopping me when I am winning. It just seems to play random moves.

The negamax is basically taken from a connect 4 game I did where the AI seemed to be playing good and stopping me from winning. Here is my code for the AI Negamax function:

private int bestMove;

public int GetBestMove(Gamestate _gamestate, int _maxDepth)
{
    // Run negamax function
    int originalAlpha = -1000000000;
    int originalBeta = 1000000000;
    int score = Negamax(_gamestate, _maxDepth, originalAlpha, originalBeta, _gamestate.playerToMove);

    return bestMove;
}

public int Negamax(Gamestate _gamestate, int depth, int alpha, int beta, int currentPlayer)
{
    // Check for terminal node
    int winningPlayer = _gamestate.GetWinner();
    if (depth == 0 || winningPlayer != -1 || _gamestate.movesMade == _gamestate.size)
    {
        if (winningPlayer != -1)
        {
            if (currentPlayer == winningPlayer)
            {
                return 10000000;
            }
            else
            {
                return -10000000;
            }
        }
        else if (_gamestate.movesMade == _gamestate.size)
        {
            return 0;
        }
        else
        {
            return 0; // Just to test the basic win/loss finding
            //return evaluator.EvaluatePosition(_gamestate);
        }
    }

    // Initialize score and bestMove and loop through all possible moves
    int score = int.MinValue;
    List<int> possibleMoves = _gamestate.possibleMoves;
    bestMove = possibleMoves[0];

    for (int i = 0; i < possibleMoves.Count; i++)
    {
        int move = possibleMoves[i];

        // Make the move, score it, and then unmake the move again
        _gamestate.MakeMove(move);
        int newScore = -Negamax(_gamestate, depth - 1, -beta, -alpha, 1 - currentPlayer);
        _gamestate.UnmakeMove(move);

        if (newScore > score)
        {
            score = newScore;
            bestMove = move;
        }

        alpha = Mathf.Max(alpha, score);
        if (alpha >= beta)
        {
            break;
        }
    }

    return score;
}

** What is wrong **

  • To debug I am playing on a 5x5 board. When I have 4 in a row the AI doesn't play to stop me.
  • The AI seems to play random moves, even if my evalutaion at none terminal nodes just returns 0 for now.

What I have tried

  • I have checked that my GetWinner() function is correct and returns the player that is winning (0 for first player and 1 for the other player)
  • My move generation is simply that I remove the latest played square from a list of all squares when I make a move. And add it again when I unmake a move. So that currently seems to be working fine.
1

There are 1 best solutions below

1
On

Evaluation Function: Make sure it checks not just for a win or loss, but also for the number of 'open-ended' rows of 2, 3, or 4 stones that each player has. This can give your AI the foresight to block your winning moves. Priority Moves: Your AI should prioritize moves that prevent the opponent from winning on the next turn. So, if there’s a spot that completes a row of 4 for you, the AI should see that as a big red flag and move there first. Depth of Search: Sometimes, the AI needs to look a few moves ahead. Ensure that your _maxDepth parameter is sufficient for the AI to project potential wins or losses a few moves down the line. Debugging: Step through the Negamax function with a debugger when you've got four in a row. Watch the scores it generates for moves—there might be a clue there. Remember, the key to a strong AI is in the details of the evaluation. It’s not about the random moves; it’s about the smart ones!

If this advice helps your AI get its game face on, please consider it a win and accept it.

Best of luck, Ali Shahzad