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