This is a two-fold question. I have put together a simple chess engine which performs Alpha-Beta search followed by Quiescence search at the end. Quiescence search is impacting the performance. The question is, is it an acceptable performance impact? If not, then what should be done to remedy this problem?
The performance impact is given in the figures below.
Note that these stats were considered in middle of a game. The FEN is:
r3k2r/pb2qpbp/1pn1pnp1/2PpP3/2B2B2/2N2N2/PPPQ1PPP/R3K2R w KQkq - 0 1
Without Quiescence:
- 6 plies in 82,069 ms (~82 secs)
- 5 plies in 5,298 ms (~5.3 secs)
With Quiescence:
- 5 plies in 83,502 ms (~83 secs)
I haven't done stats for 6 plies using quiescence search, but wouldn't mind calculating it if need be.
The key thing to note is that adding quiescence search is equivalent to searching an extra ply. Is this normal?
The Alpha-Beta and Quiescence routines in C# are listed below. They are based on chess programming wiki.
public static int AlphaBeta(Board board, int alpha, int beta, int depthLeft, int side)
{
if (depthLeft == 0)
{
return Quiescence(board, side, alpha, beta);
}
List<Move> moves = board.GenerateMoves(side);
//nodesCount += moves.Count;
BoardState state;
int score;
int oppositeSide = -1 * side;
for (int i = 0; i < moves.Count; i++)
{
state = board.GetCurrentBoardState();
if (!board.MakeMove(moves[i]))
{
continue;
}
score = -AlphaBeta(board, -beta, -alpha, depthLeft - 1, oppositeSide);
board.RestoreState(state);
if (score >= beta)
{
return beta;
}
if (score > alpha)
{
alpha = score;
}
}
return alpha;
}
Quiescence:
private static int Quiescence(Board board, int side, int alpha, int beta)
{
int standingPat = Evaluation.EvaluateFromPerspectiveOf(board, side);
if (standingPat >= beta)
{
return beta;
}
if (alpha < standingPat)
{
alpha = standingPat;
}
int oppositeSide = -1 * side;
List<Move> moves = board.GenerateMoves(side);
int score;
BoardState state;
for (int i = 0; i < moves.Count; i++)
{
if (!board.IsCaptureMove(moves[i]))
{
continue;
}
//nodesCount++;
state = board.GetCurrentBoardState();
if (!board.MakeMove(moves[i]))
{
continue;
}
score = -Quiescence(board, oppositeSide, -beta, -alpha);
board.RestoreState(state);
if (score >= beta)
{
return beta;
}
if (score > alpha)
{
alpha = score;
}
}
return alpha;
}