0

I'm currently making a chess AI, and I've made all the basic elements (e.g. a board representation, minimax algorithm with alpha-beta, etc.), but it's still pretty slow. I've seen that ordering the moves before you pass them into the minimax speeds up the algorithm significantly, but when I implemented this, I saw no significant boost in speed. Is my implementation of these algorithms wrong?

Here's my code:

public static double Minimax(Chess_Game game, int depth, double alpha, double beta)
{
    if (depth == 0)
    {
        return EvalPositionBasic(game, false);
    }
    List<int[][]> moves = game.AllMoves(game.color);
    if (moves.Count == 0)
    {
        return EvalPositionBasic(game, true);
    }
    OrderMoves(moves, game);
    if (game.color)
    {
        double maxEval = double.MinValue;
        foreach (int[][] move in moves)
        {
            if (move == null) continue;
            game.Move(move[0], move[1]);
            double eval = Minimax(game, depth - 1, alpha, beta);
            game.UnMove();
            maxEval = Math.Max(eval, maxEval);
            alpha = Math.Max(alpha, eval);
            if (beta <= alpha)
                break;
        }
        return maxEval;
    }
    else
    {
        double maxEval = double.MaxValue;
        foreach (int[][] move in moves)
        {
            if (move == null) continue;
            game.Move(move[0], move[1]);
            double eval = Minimax(game, depth - 1, alpha, beta);
            game.UnMove();
            maxEval = Math.Min(eval, maxEval);
            beta = Math.Min(beta, eval);
            if (beta <= alpha)
                break;
        }
        return maxEval;
    }
}
public static double OrderingEvaluation(Chess_Game game, int[][] move)
{
    double eval = 0;
    int start = game.board[move[0][1]][move[0][0]];
    int end = game.board[move[1][1]][move[1][0]];
    if (end != 0)
    {
        eval += 10 * Value(end) - Value(start);
    }
    if (game.color)
    {
        if (game.blackPawnAttackedArr.Last()[move[1][1]][move[1][0]] == 1)
            eval += Value(start);
    }
    else
    {
        if (game.whitePawnAttackedArr.Last()[move[1][1]][move[1][0]] == 1)
            eval += Value(start);
    }
    return eval;
}
public static void OrderMoves(List<int[][]> moves, Chess_Game game)
{
    moves.Sort((a, b) =>
        OrderingEvaluation(game, b).CompareTo(OrderingEvaluation(game, a)));
}
public static int[][] GenMove(Chess_Game game, int depth)
{
    List<double> evals = new List<double>();
    List<int[][]> moves = new List<int[][]>();
    List<int[][]> plausible = new List<int[][]>();
    List<int[][]> legalMoves = game.AllMoves(game.color);
    OrderMoves(legalMoves, game);
    foreach (int[][] item in legalMoves)
    {
        if (item == null)
        {
            continue;
        }
        game.Move(item[0], item[1]);
        evals.Add(Minimax(game, depth-1, double.MinValue, double.MaxValue));
        moves.Add(item);
        game.UnMove();
    }
    double best;
    if (game.color)
        best = evals.Max();
    else
        best = evals.Min();
    for (int i=0; i<evals.Count; i++)
    {
        if (Math.Abs(evals.ElementAt(i)-best) < 0.1)
            plausible.Add(moves.ElementAt(i));
    }
    Random rnd = new Random();

    return plausible.ElementAt(rnd.Next(plausible.Count));
}
Florian
  • 1,019
  • 6
  • 22
  • It should make a huge difference. Have you checked the list of moves afterwards to see that they are sorting as you expect? I also don't understand your ordering, I assume the first one is for captures, what are the rest? – eligolf May 02 '23 at 09:25

0 Answers0