Older Version Newer Version

Pawel_Koziol Pawel_Koziol Dec 30, 2014

**[[Home]] * [[Engines]] * [[CPW-Engine]] * Quiescence**

[[code format="cpp"]]

#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;
}
[[code]]
=What links here?= 
[[include page="CPW-Engine_quiescence" component="backlinks" limit="10"]]
**[[CPW-Engine|Up one Level]]**