-1

I am trying to create a simple chess AI in C# and have so far been successful to an extent using the minimax algorithm with alpha-beta pruning. However, with the code below it literally takes around 5 seconds for it to evaluate a move at depth 3 and I would like it to be faster if possible. I have been tinkering with it for hours and any change I make to it seems to just break the ai. Any help is greatly appreciated!

private void makeAIMove(Piece[,] board)
{
    Move bestMove;
    int score;

    List<Piece[,]> possiblePositions = getAllPossiblePositions(board, Team.Black);
    List<Move> possibleMoves = getAllPossibleMoves(board, Team.Black);

    bestMove = possibleMoves[0];
    score = evaluatePosition(possiblePositions[0], int.MinValue, int.MaxValue, DEPTH, Team.White);
    if (numTurns > 0)
    {
        for (int i = 1; i < possiblePositions.Count; i++)
        {
            int pos = evaluatePosition(possiblePositions[i], int.MinValue, int.MaxValue, DEPTH, Team.White);
            if (pos >= score)
            {
                bestMove = possibleMoves[i];
                score = pos;
            }
        }
    }
    else
    {
        bestMove = possibleMoves[Random.Range(0, possibleMoves.Count)];
    }
    numTurns += 1;
    updateBoard(bestMove);
}

private int evaluatePosition(Piece[,] board1, int alpha, int beta, int depth, int team)
{
    Piece[,] board = (Piece[,])board1.Clone();
    if (depth == 0)
    {
        return evaluate(board);
    }
    if (team == Team.White)
    {
        List<Move> moves = getAllPossibleMoves(board, team);
        int newBeta = beta;
        foreach (Move moveName in moves)
        {
            fastMove(board, board[moveName.start.y, moveName.start.x], moveName);
            newBeta = Mathf.Min(newBeta, evaluatePosition(board, alpha, beta, depth - 1, oppositeTeam(team)));
            if (newBeta <= alpha) break;
        }
        return newBeta;
    }
    else
    {
        List<Move> moves = getAllPossibleMoves(board, team);
        int newAlpha = alpha;
        foreach (Move moveName in moves)
        {
            fastMove(board, board[moveName.start.y, moveName.start.x], moveName);
            newAlpha = Mathf.Max(newAlpha, evaluatePosition(board, alpha, beta, depth - 1, oppositeTeam(team)));
            if (beta <= newAlpha) break;
        }
        return newAlpha;
    }
}
Qiniso
  • 2,587
  • 1
  • 24
  • 30
jack
  • 1

1 Answers1

0

It is hard to say exactly why since we don't see your entire code but here are a few suggestions on where to start looking:

  1. Your move generation code can be slow. Try to make a perft test on some positions and see how many nodes/s you get. It should be in the millions if you have a well written code.

  2. Your evaluation can be slow. Try to first just do a simple evaluation where you only calculate material for each side.

  3. It is weird that you have "if team == Team.White". Does this mean that you always have the AI to play as black? Use as in the pseudo code instead for alpha/beta where you have the Maximizing player in if statement instead.

  4. You set newBeta = beta in the minimizing player loop (first if statement). Here you should set newBeta = someLargeValue. Same for alpha in the else statement. Also, I think it is better to use the term score in both cases to make it more clear.

  5. You forget to set new alpha and beta values. In the first case it should be something like this:

             newBeta = Mathf.Min(newBeta, evaluatePosition(board, alpha, beta, depth - 1, oppositeTeam(team)));
             if (newBeta <= alpha) break;
             beta = Mathf.Min(beta, newBeta);
    

Please look at pseudo code and try to implement as closely as possible, it will make it more simple: https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning. Also consider make it Negamax instead which will simplify the logic even further: https://en.wikipedia.org/wiki/Negamax. This is a neccesity for making further optimizations down the road.

When you get everything to work as expected you can start doing other things to improve performance such as move ordering and different pruning techniques.

eligolf
  • 1,682
  • 1
  • 6
  • 22