Changes

Jump to: navigation, search

CPW-Engine quiescence

4,207 bytes added, 16:30, 18 December 2018
Created page with "'''Home * Engines * CPW-Engine * Quiescence''' <pre> #include "stdafx.h" #include "0x88_math.h" extern bool time_over; int Quiesce(int alpha, int bet..."
'''[[Main Page|Home]] * [[Engines]] * [[CPW-Engine]] * Quiescence'''

<pre>

#include "stdafx.h"
#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;
}
</pre>
'''[[CPW-Engine|Up one Level]]'''

Navigation menu