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));
}