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.
GetTotalLegalMoves
andEvaluate
?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.Clone
method clones the chessboard in which theAlfaBeta
method is called.