CPW-Engine quiescence

Home * Engines * CPW-Engine * Quiescence


 * 1) include "stdafx.h"
 * 2) include "0x88_math.h"

extern bool time_over;

int Quiesce(int alpha, int beta) {

if (!time_over && !(sd.nodes & 0x3FF)) time_over = time_stop;

if (time_over) return 0;

sd.nodes++; sd.q_nodes++;

/* get a "stand pat" score */ int val = eval(alpha, beta, 1); int stand_pat = val;

/* check if stand-pat score causes a beta cutoff */ if (val >= beta) return beta;

/* check if stand-pat score may become a new alpha */ if (alpha < val) alpha = val;

/********************************************************************* *  We have taken into account rhe stand pat score, and it didn't let * * us  come to a definite conclusion about the position. So we must * * do a real search. * *********************************************************************/

smove movelist[256]; U8 mcount = movegen_qs(movelist);

for (U8 i = 0; i < mcount; i++) {

movegen_sort(mcount, movelist, i);

if (movelist[i].piece_cap == KING) return INF;

/*****************************************************************   *  Delta cutoff - a move guarentees the score well below alpha,  * * so  there's no point in searching it. This heuristic is not  * * used  in the endgame, because of the  insufficient  material  * * issues and special endgame evaluation heuristics. *   *****************************************************************/

if ((stand_pat + e.PIECE_VALUE[movelist[i].piece_cap] + 200 < alpha) &&     (b.PieceMaterial[!b.stm] - e.PIECE_VALUE[movelist[i].piece_cap] > e.ENDGAME_MAT) &&      (!move_isprom(movelist[i]))) continue;

/*****************************************************************   *  badCapture replaces a cutoff based on the  Static Exchange  * * Evaluation,  marking  the place where it ought to  be  coded. *   *  Nevertheless, it saves quite a few nodes. *   *****************************************************************/

if (badCapture(movelist[i])     && !move_canSimplify(movelist[i])      && !move_isprom(movelist[i])      ) continue;

/*****************************************************************   *  Cutoffs  misfired, so the move in question can turn out well. *   *  Let us try it, then. *   *****************************************************************/

move_make(movelist[i]);

val = -Quiesce(-beta, -alpha);

move_unmake(movelist[i]);

if (time_over) return 0;

if (val > alpha) { if (val >= beta) return beta;

alpha = val; } }  return alpha; }

int badCapture(smove move) {

/* captures by pawn do not lose material */ if (move.piece_from == PAWN) return 0;

/* Captures "lower takes higher" (as well as BxN) are good by definition. */ if (e.PIECE_VALUE[move.piece_cap] >= e.PIECE_VALUE[move.piece_from] - 50) return 0;

/************************************************************************** *   When the enemy piece is defended by a pawn, in the quiescence search  * *  we  will  accept rook takes minor, but not minor takes pawn. ( More  *  *   exact  version  should accept B/N x P if (a) the pawn  is  the  sole  *  *   defender and (b) there is more than one attacker.                     *  **************************************************************************/

if (pawnRecapture(b.color[move.from], move.to) &&   e.PIECE_VALUE[move.piece_cap] + 200 - e.PIECE_VALUE[move.piece_from] < 0) return 1;

/* if a capture is not processed, it cannot be considered bad */ return 0; }

int pawnRecapture(U8 capturers_color, char sq) {

if (capturers_color == WHITE) { if ((IS_SQ(sq + NW) && isPiece(BLACK, PAWN, sq + NW)) ||     (IS_SQ(sq + NE) && isPiece(BLACK, PAWN, sq + NE))) return 1; } else { if ((IS_SQ(sq + SW) && isPiece(WHITE, PAWN, sq + SW)) ||     (IS_SQ(sq + SE) && isPiece(WHITE, PAWN, sq + SE))) return 1; } return 0; } Up one Level