}
// node (move) fails low
return alpha;
}
// quiescenceSearch helps the engine not thow away its pieces because of
// a temporary seemingly good move.
fn quiescenceSearch(self: *@This(), alpha_orig: isize, beta: isize) !isize {
var alpha = alpha_orig;
const evaluation = self.evaluate();
// fail-hard beta cutoff
if (evaluation >= beta) {
// node (move) fails high
return beta;
}
// found a better move
if (evaluation > alpha) {
// PV (principal validation) node
alpha = evaluation;
}
var ml = try MoveList.init(0);
try self.generateMoves(&ml);
for (ml.slice()) |move| {
var bck: GameState = undefined;
self.backup(&bck);
self.ply += 1;
if (!self.makeMove(move, .captures)) {
self.ply -= 1;
self.restore(&bck);
continue;
}
const score = -try self.quiescenceSearch(-beta, -alpha);
self.ply -= 1;
self.restore(&bck);
// fail-hard beta cutoff
if (score >= beta) {
// node (move) fails high
return beta;
}
// found a better move
if (score > alpha) {
// PV (principal validation) node
alpha = score;
}