protected int zwSearch(ChessTreeNode node)
{
if (node.IsZeroDepth())
{
return(this.Quiescence(node.GetNextQuiescenceZW()));
}
nodesSearched += 1;
var player = this.gameProvider.PlayerBoards[node.PlayerIndex];
var opponent = this.gameProvider.PlayerBoards[1 - node.PlayerIndex];
bool wasKingInCheck = player.IsUnderAttack(player.King.GetSquare(), opponent);
Color currPlayerColor = player.FigureColor;
var movesArray = player.GetMoves(
opponent,
this.gameProvider.History.GetLastMove(),
MovesMask.AllMoves);
this.gameProvider.FilterMoves(movesArray, currPlayerColor);
if (movesArray.Size == 0)
{
this.allocator.ReleaseLast();
if (wasKingInCheck)
{
return(-Evaluator.MateValue + ply);
}
else
{
return(0);
}
}
int score = -Evaluator.MateValue;
bool needsPromotion;
var moves = movesArray.InnerArray;
for (int i = 0; i < movesArray.Size; ++i)
{
var move = moves[i];
this.gameProvider.ProcessMove(move, player.FigureColor);
++ply;
needsPromotion = (int)move.Type >= (int)MoveType.Promotion;
if (needsPromotion)
{
this.gameProvider.PromotePawn(
currPlayerColor,
move.To,
move.Type.GetPromotionFigure());
}
score = -zwSearch(node.GetNextZW());
this.gameProvider.CancelLastMove(currPlayerColor);
--ply;
if (score >= node.Beta)
{
this.allocator.ReleaseLast();
return(node.Beta);
}
}
this.allocator.ReleaseLast();
return(node.Beta - 1);
}