0

I'm working on an algorithm that evaluates chess positions in C#. Unfortunetly, the implementation is too slow. I have been waiting an hour, but the method still hasn't reached the end, even when value of DEPTH constant is 5. It works with 1, 2 and 3 depth, but not with 4 or 5.

This is my recursive method:

public double AlfaBeta(int depth, double alpha, double beta, bool maximize, Move move)
{
    Chessboard game = (Chessboard)Clone();

    if (move != null)
        if (move.IsLegal(game))
            game.Move(move, false);

    try
    {
        if (depth > DEPTH)
            return game.Evaluate();
    }
    catch
    {
        return maximize ? double.MinValue : 0;
    }

    double bestMove;
    double value;
    List<Move> moves;

    if (maximize)
    {
        moves = game.GetTotalLegalMoves('w');

        if (moves.Count == 0)
            return game.Evaluate();

        bestMove = double.MinValue;

        foreach (Move cMove in moves)
        {
            value = game.AlfaBeta(depth + 1, alpha, beta, false, cMove);
            bestMove = Math.Max(bestMove, value);
            alpha = Math.Max(alpha, bestMove);

            if (beta <= alpha)
                break;
        }
    }
    else
    {
        moves = game.GetTotalLegalMoves('b');

        if (moves.Count == 0)
            return game.Evaluate();

        bestMove = double.MaxValue;

        foreach (Move cMove in moves)
        {
            value = game.AlfaBeta(depth + 1, alpha, beta, true, cMove);
            bestMove = Math.Min(bestMove, value);
            beta = Math.Min(beta, bestMove);

            if (beta <= alpha)
                break;
        }
    }

    return bestMove;
}

Each call of GetTotalLegalMoves method takes 8-10 milliseconds. Evaluate method isn't much faster: it takes 7-8 milliseconds.

Here are these methods:

public List<Move> GetTotalLegalMoves(char w_or_b)
{
    List<Move> moves = new List<Move>();
    int colourAsModulo = w_or_b == 'w' ? 1 : 0;

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            Square piece = squares[i, j];

            if ((int)piece % 2 == colourAsModulo && piece != Square.Empty)
                moves.AddRange(GetLegalMoves(new Vector2(i + 1, j + 1)));
        }
    }

    return moves;
}

private List<Move> GetLegalMoves(Vector2 piece)
{
    List<Move> moves = new List<Move>();

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            Move move = new Move(piece, new Vector2(i + 1, j + 1), 0);
            if(move.IsLegal(this))
                moves.Add(move);
        }
    }

    return moves;
}

I need some way to make my algorithm take less time, even with greater depth, like 20.

Summing up, I want to make it faster.

7
  • 1
    How can we help without the code of GetTotalLegalMoves and Evaluate ?
    – Luuk
    Commented Nov 1 at 20:17
  • Chessboard game = (Chessboard)Clone(); - clone from what? How does the next move down the search tree know to continue on using this local game state? -- Generally, having to wait even minutes for a 5-6 ply chess search suggests you have an infinite loop somewhere. Commented Nov 1 at 20:36
  • @500-InternalServerError, Clone method clones the chessboard in which the AlfaBeta method is called. Commented Nov 1 at 20:46
  • Okay, the code then performs the in-coming move on the clone, got it, but then what about the moves that are generated here, then, and passed in the recursive call - they then start from the same board as was cloned at the current level, no? Commented Nov 1 at 20:50
  • The moves you're talking about are executed on the beggining of the method, after the cloning line (only if they are legal and not equal to null). Also, if I had an infinite loop somewhere, the code wouldn't work with lower depth, but it does. Commented Nov 1 at 21:01

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.