예제 #1
0
파일: search2.c 프로젝트: zwegner/zct
/**
moves_are_connected():
This function is used for LMR, testing if a reduced move actually contained a
threat. The function tests if the move that refuted null move was connected to
the first move. This idea is from Tord Romstad.
Created 101707; last modified 101807
**/
BOOL moves_are_connected(MOVE move_1, MOVE move_2)
{
	if (move_1 == NULL_MOVE || move_2 == NULL_MOVE)
		return FALSE;
	if (MOVE_TO(move_1) == MOVE_FROM(move_2))
		return TRUE;
	if (MOVE_FROM(move_1) == MOVE_TO(move_2))
		return TRUE;
	if (MASK(MOVE_FROM(move_1)) & in_between_bb[MOVE_FROM(move_2)]
		[MOVE_TO(move_2)])
		return TRUE;
	return FALSE;
}
예제 #2
0
파일: sort.cpp 프로젝트: ageneau/scid
static int history_index(int move, const board_t * board) {

   int index;
   
   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(!move_is_tactical(move,board));

   index = PIECE_TO_12(board->square[MOVE_FROM(move)]) * 64 + SQUARE_TO_64(MOVE_FROM(move)) * 64 + SQUARE_TO_64(MOVE_TO(move));
   
   ASSERT(index>=0&&index<HistorySize);

   return index;
}
예제 #3
0
static bool capture_is_good(int move, const board_t * board) {

   int piece, capture;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(MOVE_IS_TACTICAL(move,board));

   // special cases

   if (MOVE_IS_EN_PASSANT(move)) return true;
   if (MOVE_IS_UNDER_PROMOTE(move)) return false; // REMOVE ME?

   // captures and queen promotes

   capture = board->square[MOVE_TO(move)];

   if (capture != Empty) {

      // capture

      ASSERT(move_is_capture(move,board));

      if (MOVE_IS_PROMOTE(move)) return true; // promote-capture

      piece = board->square[MOVE_FROM(move)];
      if (VALUE_PIECE(capture) >= VALUE_PIECE(piece)) return true;
   }

   return see_move(move,board,0) >= 0;
}
예제 #4
0
static int mvv_lva(int move, const board_t * board) {

   int piece, capture, promote;
   int value;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(move_is_tactical(move,board));

   if (MOVE_IS_EN_PASSANT(move)) { // en-passant capture

      value = 5; // PxP

   } else if ((capture = board->square[MOVE_TO(move)]) != Empty) { // normal capture

      piece = board->square[MOVE_FROM(move)];

      value = PIECE_ORDER(capture) * 6 - PIECE_ORDER(piece) + 5;
      ASSERT(value>=0&&value<30);

   } else { // promote

      ASSERT(MOVE_IS_PROMOTE(move));

      promote = move_promote(move);

      value = PIECE_ORDER(promote) - 5;
      ASSERT(value>=-4&&value<0);
   }

   ASSERT(value>=-4&&value<+30);

   return value;
}
예제 #5
0
void str_CSA_move( char *str, unsigned int move )
{
  int type_c = MOVE_TYPE( move );
  int type   = type_c & ~mask_piece_color;
  int from   = MOVE_FROM( move );
  int to     = MOVE_TO( move );
  int prom   = MOVE_PROMOTE( move );

  if( from == move_drop )
    {
      snprintf( str, 7, "%d%d%d%d%s",
                0, 0,
                5-( to%5),    ( to/5   +1 ),
                ch_piece_csa[ type ] );
    }
  else if( prom )
    {
      snprintf( str, 7, "%d%d%d%d%s",
                5-( from%5 ), ( from/5 +1 ),
                5-( to%5),    ( to/5   +1 ),
                ch_piece_csa[ type + m_promote ] );
    }
  else
    {
      snprintf( str, 7, "%d%d%d%d%s",
                5-( from%5 ), ( from/5 +1 ),
                5-( to%5),    ( to/5   +1 ),
                ch_piece_csa[ type ] );    
    }
  return;
}
예제 #6
0
bool pseudo_is_legal(int move, board_t * board) {

    int me, opp;
    int from, to;
    int piece;
    bool legal;
    int king;
    undo_t undo[1];

    ASSERT(move_is_ok(move));
    ASSERT(board!=NULL);

    // init

    me = board->turn;
    opp = COLOUR_OPP(me);

    from = MOVE_FROM(move);
    to = MOVE_TO(move);

    piece = board->square[from];
    ASSERT(COLOUR_IS(piece,me));

    // slow test for en-passant captures

    if (MOVE_IS_EN_PASSANT(move)) {

        move_do(board,move,undo);
        legal = !IS_IN_CHECK(board,me);
        move_undo(board,move,undo);

        return legal;
    }

    // king moves (including castle)

    if (PIECE_IS_KING(piece)) {

        legal = !is_attacked(board,to,opp);

        if (DEBUG) {
            ASSERT(board->square[from]==piece);
            board->square[from] = Empty;
            ASSERT(legal==!is_attacked(board,to,opp));
            board->square[from] = piece;
        }

        return legal;
    }

    // pins

    if (is_pinned(board,from,me)) {
        king = KING_POS(board,me);
        return DELTA_INC_LINE(king-to) == DELTA_INC_LINE(king-from); // does not discover the line
    }

    return true;
}
예제 #7
0
/*
    Undoes a move on a board.
*/
void undo_move(board_t* board, move_t move) {
    #define UNDO_CASTLE(color, king_side_from, king_side_to, queen_side_from, queen_side_to) \
        if (to_square > from_square) { UPDATE_CASTLE_BITBOARDS(color, color##_ROOK, king_side_from, king_side_to); } \
        else { UPDATE_CASTLE_BITBOARDS(color, color##_ROOK, queen_side_from, queen_side_to); }

    #define UNDO_CAPTURE(other_color, square_offset) int captured_square = to_square; \
                if (IS_ENPASSANT(move)) { \
                    captured_square += square_offset; \
                } \
                board->color_bitboard[other_color] |= SQUARE_MASK[captured_square]; \
                board->piece_bitboard[captured_piece] |= SQUARE_MASK[captured_square]; \
                board->pieces[captured_square] = captured_piece;

    #define UNDO_PROMOTION(pawn) board->piece_bitboard[promotion_piece] ^= SQUARE_MASK[to_square]; \
                board->piece_bitboard[pawn] |= SQUARE_MASK[to_square];

    board->state_index--;
    board->can_castle = board->state[board->state_index].can_castle;
    board->passed_square = board->state[board->state_index].passed_square;
    board->fifty_move_rule_counter = board->state[board->state_index].fifty_move_rule_counter;
    board->material[WHITE] = board->state[board->state_index].material[WHITE];
    board->material[BLACK] = board->state[board->state_index].material[BLACK];
    board->hash_key = board->state[board->state_index].hash_key;

    int from_square = MOVE_FROM(move), to_square = MOVE_TO(move), moving_piece = MOVING_PIECE(move), 
        captured_piece = CAPTURED_PIECE(move), promotion_piece = PROMOTION_PIECE(move);
    bitboard_t from_to_bitboard = SQUARE_MASK[from_square] | SQUARE_MASK[to_square];

    board->pieces[from_square] = moving_piece;
    board->pieces[to_square] = EMPTY;

    if (board->to_move == BLACK) {
        board->color_bitboard[WHITE] ^= from_to_bitboard;

        if (IS_CASTLE(move)) { UNDO_CASTLE(WHITE, H1, F1, A1, D1); }
        if (IS_PROMOTION(move)) { UNDO_PROMOTION(WHITE_PAWN); }
        if (captured_piece) {  UNDO_CAPTURE(BLACK, -8); }

        if (moving_piece == WHITE_KING) board->king_position[WHITE] = from_square;
        else board->piece_bitboard[moving_piece] ^= from_to_bitboard;

        board->to_move = WHITE;
    } else {
        board->color_bitboard[BLACK] ^= from_to_bitboard;

        if (IS_CASTLE(move)) { UNDO_CASTLE(BLACK, H8, F8, A8, D8); }
        if (IS_PROMOTION(move)) { UNDO_PROMOTION(BLACK_PAWN); }
        if (captured_piece) {  UNDO_CAPTURE(WHITE, 8); }

        if (moving_piece == BLACK_KING) board->king_position[BLACK] = from_square;
        else board->piece_bitboard[moving_piece] ^= from_to_bitboard;

        board->to_move = BLACK;
    }

    board->all_pieces_bitboard = board->color_bitboard[WHITE] | board->color_bitboard[BLACK];
}
예제 #8
0
void move_undo(int move, const undo_t * undo) {

   int me;
   int from, to;
   int piece,pos;

   
   ASSERT(move_is_ok(move));
   ASSERT(undo!=NULL);

   // init

   me = undo->turn;

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   piece = Square[to];
   pos=piece & 31;


   ASSERT(COLOUR_IS(piece,me));
   
   Square[from]=piece;
   Piece[pos]=from;

   BitRanks[from>>4] ^= g_BitRankMask[from];
   BitFiles[from & 0xf]^= g_BitFileMask[from];
 
  
   if(undo->capture)//吃子更新
   {
	   Square[to]=undo->capture_piece;
	   Piece[undo->capture_piece & 31]=to;
       
	   Piece_size[PIECE_COLOUR(undo->capture_piece)]++;
	   Number[PieceTo32[undo->capture_piece & 31]]++;
        
   }else
   { 
	   Square[to]=Empty;

	   BitRanks[to>>4] ^= g_BitRankMask[to];
	   BitFiles[to&0xf]^= g_BitFileMask[to];
   }
   
   Turn = undo->turn;

   Opening = undo->opening;
   Endgame = undo->endgame;

   Key = undo->key;
   Lock = undo->lock;

   Sp--;
}
예제 #9
0
int see(Move_t move, Board_t *board) {
    Board_t temp_board = *global_board();
    Board_t *ptr = &temp_board;
    
    int attacking_piece = MOVE_PIECE(move);
    int captured_piece;
    int gain[32];
    int depth = 0;
    int from = MOVE_FROM(move);
    int to = MOVE_TO(move);
    
    if (ENEMY_PAWNS(ptr) & SQ_MASK(to))
        captured_piece = PAWN;
    else if (ENEMY_KNIGHTS(ptr) & SQ_MASK(to))
        captured_piece = KNIGHT;
    else if (ENEMY_BISHOPS(ptr) & SQ_MASK(to))
        captured_piece = BISHOP;
    else if (ENEMY_ROOKS(ptr) & SQ_MASK(to))
        captured_piece = ROOK;
    else if (ENEMY_QUEENS(ptr) & SQ_MASK(to))
        captured_piece = QUEEN;
    else
        captured_piece = 0;
        
    gain[0] = Piece_Values[captured_piece];
    
    if (MOVE_IS_EN_PASSANT(move))
        gain[0] = Piece_Values[PAWN];
    
    do {
        make_quick_move_on_board(ptr, from, to, captured_piece, attacking_piece);
        
        captured_piece = attacking_piece;
        depth++;
        gain[depth] = Piece_Values[captured_piece] - gain[depth-1];
        
        if (MAX(-gain[depth-1], gain[depth]) < 0)
            break;
        
        attacking_piece = get_least_valuable_attacker(ptr, to, &from);
        
    } while (attacking_piece);
    
    while (--depth)
        gain[depth-1] = -MAX(-gain[depth-1], gain[depth]);
    
    return gain[0];
}
예제 #10
0
bool move_is_check(int move, board_t * board) {

    undo_t undo[1];
    bool check;
    int me, opp, king;
    int from, to, piece;

    ASSERT(move_is_ok(move));
    ASSERT(board!=NULL);

    // slow test for complex moves

    if (MOVE_IS_SPECIAL(move)) {

        move_do(board,move,undo);
        check = IS_IN_CHECK(board,board->turn);
        move_undo(board,move,undo);

        return check;
    }

    // init

    me = board->turn;
    opp = COLOUR_OPP(me);
    king = KING_POS(board,opp);

    from = MOVE_FROM(move);
    to = MOVE_TO(move);
    piece = board->square[from];
    ASSERT(COLOUR_IS(piece,me));

    // direct check

    if (PIECE_ATTACK(board,piece,to,king)) return true;

    // indirect check

    if (is_pinned(board,from,opp)
            && DELTA_INC_LINE(king-to) != DELTA_INC_LINE(king-from)) {
        return true;
    }

    return false;
}
예제 #11
0
static unsigned int history_index(int move, const board_t * board) {

   unsigned int index;
   
   int move_from = MOVE_FROM(move);
   int piece_12  = PIECE_TO_12(board->square[move_from]);
   
   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);
   
   ASSERT(!move_is_tactical(move,board));
   
// index = PIECE_TO_12(board->square[MOVE_FROM(move)]) *     64                                       + SQUARE_TO_64(MOVE_TO(move)); fruit 2.1
// index = PIECE_TO_12(board->square[MOVE_FROM(move)]) * (64*64) + SQUARE_TO_64(MOVE_FROM(move)) * 64 + SQUARE_TO_64(MOVE_TO(move)); Toga II 1.2.1 (corrected?).  
   
   index = 64 * piece_12  +  SQUARE_TO_64(MOVE_TO(move)); // fruit 2.1 and Toga II 1.4beta5c
   
   
   ASSERT(index >= 0 && index < HistorySize);
   
   return index;
}
예제 #12
0
void move_undo(board_t * board, int move, const undo_t * undo) {

   int me;
   int from, to;
   int piece, pos;
   int rook;

   ASSERT(board!=NULL);
   ASSERT(move_is_ok(move));
   ASSERT(undo!=NULL);

   // init

   me = undo->turn;

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   piece = board->square[to];
   ASSERT(COLOUR_IS(piece,me));

   // castle

   if (MOVE_IS_CASTLE(move)) {

      rook = Rook64 | COLOUR_FLAG(me); // HACK

      if (to == G1) {
         square_move(board,F1,H1,rook,false);
      } else if (to == C1) {
         square_move(board,D1,A1,rook,false);
      } else if (to == G8) {
         square_move(board,F8,H8,rook,false);
      } else if (to == C8) {
         square_move(board,D8,A8,rook,false);
      } else {
         ASSERT(false);
      }
   }

   // move the piece backward

   if (MOVE_IS_PROMOTE(move)) {

      // promote

      ASSERT(piece==move_promote(move));
      square_clear(board,to,piece,false);

      piece = PAWN_MAKE(me);
      pos = undo->pawn_pos;

      square_set(board,from,piece,pos,false);

   } else {

      // normal move

      square_move(board,to,from,piece,false);
   }

   // put the captured piece back

   if (undo->capture) {
      square_set(board,undo->capture_square,undo->capture_piece,undo->capture_pos,false);
   }

   // update board info

   board->turn = undo->turn;
   board->flags = undo->flags;
   board->ep_square = undo->ep_square;
   board->ply_nb = undo->ply_nb;

   board->cap_sq = undo->cap_sq;

   board->opening = undo->opening;
   board->endgame = undo->endgame;

   board->key = undo->key;
   board->pawn_key = undo->pawn_key;
   board->material_key = undo->material_key;

   // update key stack

   ASSERT(board->sp>0);
   board->sp--;

   // debug

   ASSERT(board_is_ok(board));
   ASSERT(board_is_legal(board));
}
예제 #13
0
파일: see.cpp 프로젝트: Distrotech/gnuchess
int see_move(int move, const board_t * board) {

   int att, def;
   int from, to;
   alists_t alists[1];
   int value, piece_value;
   int piece, capture;
   alist_t * alist;
   int pos;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   // init

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   // move the piece

   piece_value = 0;

   piece = board->square[from];
   ASSERT(piece_is_ok(piece));

   att = PIECE_COLOUR(piece);
   def = COLOUR_OPP(att);

   // promote

   if (MOVE_IS_PROMOTE(move)) {
      ASSERT(PIECE_IS_PAWN(piece));
      piece = move_promote(move);
      ASSERT(piece_is_ok(piece));
      ASSERT(COLOUR_IS(piece,att));
   }

   piece_value += VALUE_PIECE(piece);

   // clear attacker lists

   ALIST_CLEAR(alists->alist[Black]);
   ALIST_CLEAR(alists->alist[White]);

   // find hidden attackers

   alists_hidden(alists,board,from,to);

   // capture the piece

   value = 0;

   capture = board->square[to];

   if (capture != Empty) {

      ASSERT(piece_is_ok(capture));
      ASSERT(COLOUR_IS(capture,def));

      value += VALUE_PIECE(capture);
   }

   // promote

   if (MOVE_IS_PROMOTE(move)) {
      value += VALUE_PIECE(piece) - ValuePawn;
   }

   // en-passant

   if (MOVE_IS_EN_PASSANT(move)) {
      ASSERT(value==0);
      ASSERT(PIECE_IS_PAWN(board->square[SQUARE_EP_DUAL(to)]));
      value += ValuePawn;
      alists_hidden(alists,board,SQUARE_EP_DUAL(to),to);
   }

   // build defender list

   alist = alists->alist[def];

   alist_build(alist,board,to,def);
   if (alist->size == 0) return value; // no defender => stop SEE

   // build attacker list

   alist = alists->alist[att];

   alist_build(alist,board,to,att);

   // remove the moved piece (if it's an attacker)

   for (pos = 0; pos < alist->size && alist->square[pos] != from; pos++)
      ;

   if (pos < alist->size) alist_remove(alist,pos);

   // SEE search

   value -= see_rec(alists,board,def,to,piece_value);

   return value;
}
예제 #14
0
bool move_is_pseudo( int move, board_t *board )
{

	int me, opp;
	int from, to;
	int piece, capture;

	ASSERT(move_is_ok(move));
	ASSERT(board != NULL);
	// init

	me = board->turn;
	opp = COLOUR_OPP(board->turn);

	// from

	from = MOVE_FROM(move);
	ASSERT(SQUARE_IS_OK(from));

	piece = board->square[from];	
	if(INDEX_TO_COLOUR(piece) != me)
		return false;

	// to
	to = MOVE_TO(move);
	ASSERT(SQUARE_IS_OK(to));

	capture = board->square[to];	
	if( INDEX_TO_COLOUR(capture) == me )
		return false;

	// move 
	switch(INDEX_TO_PIECE(piece))
	{
	case RedKing:
		if(KING_IN_CITY(to) && KLegalDt[to - from + 256]) return true;
		if(EQUAL_FILE(from, to) && INDEX_TO_PIECE(capture) == BlackKing)
		{
			int row=SQUARE_RANK(from) - 3;
			int col=SQUARE_FILE(from) - 3;
			if(FileCapMin[row][board->file[col]] + col == to) return true;
		}

		return false;

	case BlackKing:
		if(KING_IN_CITY(to) && KLegalDt[to - from + 256]) return true;
		if(EQUAL_FILE(from, to) && INDEX_TO_PIECE(capture) ==RedKing)
		{
			int row=SQUARE_RANK(from) - 3;
			int col=SQUARE_FILE(from) - 3;
			if(FileCapMax[row][board->file[col]] + col == to) return true;
		}

		return false;

	case RedAdvisor:
	case BlackAdvisor:
		if(ADVISOR_IN_CITY(to) && ALegalDt[to - from + 256]) return true;
		return false;

	case RedBishop:
	case BlackBishop:
		if(BISHOP_IN_CITY(to) &&
			BLegalDt[to - from + 256] &&
			board->square[(to + from) >> 1] == PieceNone)//
			return true;
		return false;

	case RedKnight:
	case BlackKnight:
		if(NLegalDt[to - from + 256] && board->square[from + NLegalDt[to - from + 256]] == PieceNone)//
			return true;
		return false;

	case RedRook:
	case BlackRook:
		if(capture)
		{
			if(EQUAL_FILE(from, to))
			{
				int row=SQUARE_RANK(from) - 3;
				int col=SQUARE_FILE(from) - 3;
				if(FileCapMax[row][board->file[col]] + col == to || FileCapMin[row][board->file[col]] + col == to)
					return true;
			}
			else if(EQUAL_RANK(from, to))
			{
				int row=SQUARE_RANK(from) - 3;
				int col=SQUARE_FILE(from) - 3;
				if(RankCapMax[col][board->rank[row]] + (row << 4) == to ||
					RankCapMin[col][board->rank[row]] + (row << 4) == to)
					return true;
			}

		}
		else
		{
			int row=SQUARE_RANK(from) - 3;
			int col=SQUARE_FILE(from) - 3;
			int to_row = SQUARE_RANK(to) - 3;
			int to_col = SQUARE_FILE(to) - 3;
			int rowbit = board->rank[row];
			int colbit = board->file[col];
			if(EQUAL_FILE(from, to))
			{
				//if(FileNonCapMin[row][board->file[col]] + col <= to && to <= FileNonCapMax[row][board->file[col]] + col)
                if(PinNb[row][to_row][colbit] == 0)
					return true;
			}
			else if(EQUAL_RANK(from, to))
			{
				//if(RankNonCapMin[col][board->rank[row]] + (row << 4) <= to && to <= RankNonCapMax[col][board->rank[row]] + (row << 4))
				 if(PinNb[col][to_col][rowbit] == 0)
				    return true;
			}

		}

		return false;

	case RedCannon:
	case BlackCannon:
		if(capture)
		{
			if(EQUAL_RANK(from, to))
			{
				int row=SQUARE_RANK(from) - 3;
				int col=SQUARE_FILE(from) - 3;
				if(CannonRankCapMax[col][board->rank[row]] + (row << 4) == to ||
					CannonRankCapMin[col][board->rank[row]] + (row << 4) == to)
					return true;
			}
			else if(EQUAL_FILE(from, to))
			{
				int row=SQUARE_RANK(from) - 3;
				int col=SQUARE_FILE(from) - 3;
				if(CannonFileCapMax[row][board->file[col]] + col == to ||
					CannonFileCapMin[row][board->file[col]] + col == to)
					return true;
			}
		}
		else
		{
			int row=SQUARE_RANK(from) - 3;
			int col=SQUARE_FILE(from) - 3;
			int to_row = SQUARE_RANK(to) - 3;
			int to_col = SQUARE_FILE(to) - 3;
			int rowbit = board->rank[row];
			int colbit = board->file[col];

			if(EQUAL_RANK(from, to))
			{
				//if(RankNonCapMin[col][board->rank[row]] + (row << 4) <= to && to <= RankNonCapMax[col][board->rank[row]] + (row << 4))
				if(PinNb[col][to_col][rowbit] == 0)
					return true;
			}
			else if(EQUAL_FILE(from, to))
			{
				//if(FileNonCapMin[row][board->file[col]] + col <= to&& to <= FileNonCapMax[row][board->file[col]] + col)
				if(PinNb[row][to_row][colbit] == 0)
					return true;
			}
		}

		return false;

	case BlackPawn:

		if((from + 16) == to) return true;
		if(SQUARE_COLOUR(from) == Red)
		{
			if((from - 1) == to || (from + 1) == to)
				return true;
		}

		return false;

	case RedPawn:

		if((from - 16) == to) return true;
		if(SQUARE_COLOUR(from) == Black)
		{
			if((from - 1) == to || (from + 1) == to)
				return true;
		}

	default:
		return false;
	}


	return false;
}
예제 #15
0
void adjust_history_table(Move_t move, int depth, int color) {
    if (History_Table[color][MOVE_FROM(move)][MOVE_TO(move)] == -VALUE_INFINITE)
        History_Table[color][MOVE_FROM(move)][MOVE_TO(move)] = depth * depth;
    else
        History_Table[color][MOVE_FROM(move)][MOVE_TO(move)] += depth * depth;
}
예제 #16
0
       bool capture_is_good(int move, const board_t * board, bool in_pv) {
#else
static bool capture_is_good(int move, const board_t * board, bool in_pv) {
#endif

   int piece, capture;
   int see_value; // WHM 11/22/08

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(move_is_tactical(move,board));

   // special cases

   if (MOVE_IS_EN_PASSANT(move)) return true;
   if (move_is_under_promote(move)) return false; // REMOVE ME?  Keep, looks good to me.  WHM;
// if (MOVE_IS_PROMOTE(move)) return true; // WHM; promote-to-queen, measures a little weaker
//                                                 too many garbage lines going nuts.
   
   // captures and queen promotes
   capture = board->square[MOVE_TO(move)];
   piece = board->square[MOVE_FROM(move)];

   if (capture != Empty) {

      // capture

      ASSERT(move_is_capture(move,board));

      if (MOVE_IS_PROMOTE(move)) return true; // capture a piece on Rank8 and promote to queen
      
      if (VALUE_PIECE(capture) >= VALUE_PIECE(piece)) return true;
   }


// return see_move(move,board) >= 0; WHM 11/22/08

// WHM 11/22/08 START

   see_value = see_move(move,board);
   if (see_value >= 0) return true;

   if (TryNodePVQueenPromotes) {
      if (in_pv && MOVE_IS_PROMOTE(move)) {
          ASSERT(!move_is_under_promote(move));
          return true; // WHM:
      }
   }
   
   if (TryKingAttackSacs || TryKingBoxSacs || TryPasserSacs) {
      if (in_pv  &&  see_value > -ValueBishop  &&  capture != Empty) {
         ASSERT(COLOUR_IS(capture,COLOUR_OPP(board->turn)));
         // king attack sacs.  
         if (TryKingAttackSacs) {
            if (narrow_piece_attack_king(board, piece, MOVE_TO(move), KING_POS(board,COLOUR_OPP(board->turn)))) {
               return true;
            }
         }
         // sacrifice attacks around the narrow/close king box can be examined more fully.  Rybka lessons.  
         if (TryKingBoxSacs) {
            if (DISTANCE(MOVE_TO(move),KING_POS(board,COLOUR_OPP(board->turn))) <= 1) {
               return true;
            }
         }
         // passer sacrifices...
         if (TryPasserSacs) {
            if (PIECE_IS_PAWN(capture) && PAWN_RANK(MOVE_TO(move),COLOUR_OPP(board->turn)) >= Rank6) {
               return true;
            }
         }
      }
   } // WHM 11/22/08 END
   
   
   return false;
}
예제 #17
0
int get_history_score(Move_t move, int color) {
    return History_Table[color][MOVE_FROM(move)][MOVE_TO(move)];
}
예제 #18
0
void move_do(board_t * board, int move, undo_t * undo) {

   int me, opp;
   int from, to;
   int piece, pos, capture;
   int old_flags, new_flags;
   int delta;
   int sq;
   int pawn, rook;

   ASSERT(board!=NULL);
   ASSERT(move_is_ok(move));
   ASSERT(undo!=NULL);

   ASSERT(board_is_legal(board));

   // initialise undo

   undo->capture = false;

   undo->turn = board->turn;
   undo->flags = board->flags;
   undo->ep_square = board->ep_square;
   undo->ply_nb = board->ply_nb;

   undo->cap_sq = board->cap_sq;

   undo->opening = board->opening;
   undo->endgame = board->endgame;

   undo->key = board->key;
   undo->pawn_key = board->pawn_key;
   undo->material_key = board->material_key;

   // init

   me = board->turn;
   opp = COLOUR_OPP(me);

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   piece = board->square[from];
   ASSERT(COLOUR_IS(piece,me));

   // update key stack

   ASSERT(board->sp<StackSize);
   board->stack[board->sp++] = board->key;

   // update turn

   board->turn = opp;
   board->key ^= RANDOM_64(RandomTurn);

   // update castling rights

   old_flags = board->flags;
   new_flags = old_flags & CastleMask[from] & CastleMask[to];

   board->flags = new_flags;
   board->key ^= Castle64[new_flags^old_flags]; // HACK

   // update en-passant square

   if ((sq=board->ep_square) != SquareNone) {
      board->key ^= RANDOM_64(RandomEnPassant+SQUARE_FILE(sq)-FileA);
      board->ep_square = SquareNone;
   }

   if (PIECE_IS_PAWN(piece)) {

      delta = to - from;

      if (delta == +32 || delta == -32) {
         pawn = PAWN_MAKE(opp);
         if (board->square[to-1] == pawn || board->square[to+1] == pawn) {
            board->ep_square = (from + to) / 2;
            board->key ^= RANDOM_64(RandomEnPassant+SQUARE_FILE(to)-FileA);
         }
      }
   }

   // update move number (captures are handled later)

   board->ply_nb++;
   if (PIECE_IS_PAWN(piece)) board->ply_nb = 0; // conversion

   // update last square

   board->cap_sq = SquareNone;

   // remove the captured piece

   sq = to;
   if (MOVE_IS_EN_PASSANT(move)) sq = SQUARE_EP_DUAL(sq);

   if ((capture=board->square[sq]) != Empty) {

      ASSERT(COLOUR_IS(capture,opp));
      ASSERT(!PIECE_IS_KING(capture));

      undo->capture = true;
      undo->capture_square = sq;
      undo->capture_piece = capture;
      undo->capture_pos = board->pos[sq];

      square_clear(board,sq,capture,true);

      board->ply_nb = 0; // conversion
      board->cap_sq = to;
   }

   // move the piece

   if (MOVE_IS_PROMOTE(move)) {

      // promote

      undo->pawn_pos = board->pos[from];

      square_clear(board,from,piece,true);

      piece = move_promote(move);

      // insert the promote piece in MV order

      for (pos = board->piece_size[me]; pos > 0 && piece > board->square[board->piece[me][pos-1]]; pos--) // HACK
         ;

      square_set(board,to,piece,pos,true);

      board->cap_sq = to;

   } else {

      // normal move

      square_move(board,from,to,piece,true);
   }

   // move the rook in case of castling

   if (MOVE_IS_CASTLE(move)) {

      rook = Rook64 | COLOUR_FLAG(me); // HACK

      if (to == G1) {
         square_move(board,H1,F1,rook,true);
      } else if (to == C1) {
         square_move(board,A1,D1,rook,true);
      } else if (to == G8) {
         square_move(board,H8,F8,rook,true);
      } else if (to == C8) {
         square_move(board,A8,D8,rook,true);
      } else {
         ASSERT(false);
      }
   }

   // debug

   ASSERT(board_is_ok(board));
}
예제 #19
0
void move_do(int move, undo_t * undo) {

   int me, opp;
   int from, to;
   int piece, capture,pos;
   int piece_key;

   
   ASSERT(undo!=NULL);

   //ASSERT(board_is_legal(board));

   // initialise undo

   undo->capture = false;
   undo->turn = Turn;
   undo->opening = Opening;
   undo->endgame = Endgame;
   undo->key = Key;
   undo->lock = Lock;

   // init

   me = Turn;
   opp =COLOUR_OPP(me);

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   piece = Square[from];
   if(piece==0)
	   printf("Error move piece %x\n ",move);
   pos=piece & 31;
   // update key stack
   Stack[Sp++] = Lock;

   // update turn

   Turn = opp;
   Key ^= g_ZobristKeyPlayer;
   Lock ^= g_ZobristLockPlayer;

   piece_key=PieceToKey32[pos];


   if ((capture=Square[to]) != Empty) {

      undo->capture = true;
      undo->capture_square = to;
      undo->capture_piece = capture;
      
	  //吃掉的子进行清除
	  Piece[capture & 31]=0;
	  Piece_size[PIECE_COLOUR(capture)]--;

	  Number[PieceTo32[capture & 31]]--;

	  Key ^= g_ZobristKeyTable[piece_key][to];
      Lock ^= g_ZobristLockTable[piece_key][to];

   }else
   {
       //没有吃子,只更新位行、位列
	   BitRanks[to>>4] ^= g_BitRankMask[to];
       BitFiles[to & 0xf] ^= g_BitFileMask[to];
   }

   Square[from] = Empty;

   Square[to] = piece;
   
   Piece[pos] = to;

   BitRanks[from>>4] ^= g_BitRankMask[from];
   BitFiles[from & 0xf] ^= g_BitFileMask[from];

   if (piece_key < 5) {
        Opening +=g_PST[piece_key][to] - g_PST[piece_key][from];
 	    Endgame +=g_PST[piece_key+5][to] - g_PST[piece_key+5][from];
    } else {
	    Opening -=g_PST[piece_key-5][254 - to] - g_PST[piece_key-5][254 - from];
	    Endgame -=g_PST[piece_key][254 - to]   - g_PST[piece_key][254 - from];
    }
 
   Key ^= g_ZobristKeyTable[piece_key][to] ^ g_ZobristKeyTable[piece_key][from];
   Lock ^= g_ZobristLockTable[piece_key][to] ^ g_ZobristLockTable[piece_key][from];
   
   // move the piece
}
예제 #20
0
bool move_is_pseudo(int move, board_t * board) {

    int me, opp;
    int from, to;
    int piece, capture;
    int inc, delta;

    ASSERT(move_is_ok(move));
    ASSERT(board!=NULL);

    ASSERT(!board_is_check(board));

    // special cases

    if (MOVE_IS_SPECIAL(move)) {
        return move_is_pseudo_debug(move,board);
    }

    ASSERT((move&~07777)==0);

    // init

    me = board->turn;
    opp = COLOUR_OPP(board->turn);

    // from

    from = MOVE_FROM(move);
    ASSERT(SQUARE_IS_OK(from));

    piece = board->square[from];
    if (!COLOUR_IS(piece,me)) return false;

    ASSERT(piece_is_ok(piece));

    // to

    to = MOVE_TO(move);
    ASSERT(SQUARE_IS_OK(to));

    capture = board->square[to];
    if (COLOUR_IS(capture,me)) return false;

    // move

    if (PIECE_IS_PAWN(piece)) {

        if (SQUARE_IS_PROMOTE(to)) return false;

        inc = PAWN_MOVE_INC(me);
        delta = to - from;
        ASSERT(delta_is_ok(delta));

        if (capture == Empty) {

            // pawn push

            if (delta == inc) return true;

            if (delta == (2*inc)
                    && PAWN_RANK(from,me) == Rank2
                    && board->square[from+inc] == Empty) {
                return true;
            }

        } else {

            // pawn capture

            if (delta == (inc-1) || delta == (inc+1)) return true;
        }

    } else {

        if (PIECE_ATTACK(board,piece,from,to)) return true;
    }

    return false;
}
예제 #21
0
/*
    Plays a move on a board. The move is assumed to be legal. 
*/
void make_move(board_t* board, move_t move) {
    #define MAKE_CASTLE(color, removed_castle_bits, king_side_from, king_side_to, queen_side_from, queen_side_to) \
        board->can_castle &= removed_castle_bits; \
        if (to_square > from_square) { \
            UPDATE_CASTLE_BITBOARDS(color, color##_ROOK, king_side_to, king_side_from); \
            board->hash_key ^= (hash_keys.keys[king_side_to][color##_ROOK] ^ hash_keys.keys[king_side_from][color##_ROOK]); \
        } else { \
            UPDATE_CASTLE_BITBOARDS(color, color##_ROOK, queen_side_to, queen_side_from); \
            board->hash_key ^= (hash_keys.keys[queen_side_to][color##_ROOK] ^ hash_keys.keys[queen_side_from][color##_ROOK]); }

    #define MAKE_CAPTURE(other_color, square_offset) int captured_square = to_square; \
                if (IS_ENPASSANT(move)) { \
                    captured_square += square_offset; \
                    board->pieces[captured_square] = EMPTY; } \
                board->color_bitboard[other_color] ^= SQUARE_MASK[captured_square]; \
                board->piece_bitboard[captured_piece] ^= SQUARE_MASK[captured_square]; \
                board->fifty_move_rule_counter = 0; \
                board->material[other_color] -= MATERIAL_VALUE[captured_piece]; \
                board->hash_key ^= hash_keys.keys[captured_square][captured_piece];

    #define MAKE_PAWN_MOVE(color, square_offset) \
                if ((from_square^to_square) == 16) { \
                    board->passed_square = (to_square - square_offset); \
                    board->hash_key ^= hash_keys.en_passant_targets[board->passed_square]; }\
                if (IS_PROMOTION(move)) { \
                    board->pieces[to_square] = promotion_piece; \
                    board->piece_bitboard[color##_PAWN] ^= SQUARE_MASK[to_square]; \
                    board->piece_bitboard[promotion_piece] |= SQUARE_MASK[to_square]; \
                    board->material[color] += MATERIAL_VALUE[promotion_piece] - 1; \
                    board->hash_key ^= (hash_keys.keys[to_square][color##_PAWN] ^ hash_keys.keys[to_square][promotion_piece]); } \
                board->fifty_move_rule_counter = 0;

    board->state[board->state_index].move = move;
    board->state[board->state_index].can_castle = board->can_castle;
    board->state[board->state_index].passed_square = board->passed_square;
    board->state[board->state_index].fifty_move_rule_counter = board->fifty_move_rule_counter;
    board->state[board->state_index].material[WHITE] = board->material[WHITE];
    board->state[board->state_index].material[BLACK] = board->material[BLACK];
    board->state[board->state_index].hash_key = board->hash_key;

    board->fifty_move_rule_counter++;
    if (board->passed_square) board->hash_key ^= hash_keys.en_passant_targets[board->passed_square];
    board->passed_square = 0;

    int from_square = MOVE_FROM(move), to_square = MOVE_TO(move), moving_piece = MOVING_PIECE(move), 
        captured_piece = CAPTURED_PIECE(move), promotion_piece = PROMOTION_PIECE(move);
    bitboard_t from_to_bitboard = SQUARE_MASK[from_square] | SQUARE_MASK[to_square];

    board->pieces[from_square] = EMPTY;
    board->pieces[to_square] = moving_piece;
    board->hash_key ^= (hash_keys.keys[from_square][moving_piece] ^ hash_keys.keys[to_square][moving_piece]);

    if (board->to_move == WHITE) {
        board->color_bitboard[WHITE] ^= from_to_bitboard;

        if (IS_CASTLE(move)) { MAKE_CASTLE(WHITE, 0xC, H1, F1, A1, D1); }
        if (captured_piece) { MAKE_CAPTURE(BLACK, -8); }
        if (moving_piece == WHITE_PAWN) { MAKE_PAWN_MOVE(WHITE, 8); }

        if (moving_piece == WHITE_KING) board->king_position[WHITE] = to_square;
        else board->piece_bitboard[moving_piece] ^= from_to_bitboard;

        board->to_move = BLACK;
    } else {
        board->color_bitboard[BLACK] ^= from_to_bitboard;

        if (IS_CASTLE(move)) { MAKE_CASTLE(BLACK, 0x3, H8, F8, A8, D8); }
        if (captured_piece) { MAKE_CAPTURE(WHITE, 8); }
        if (moving_piece == BLACK_PAWN) { MAKE_PAWN_MOVE(BLACK, -8); }

        if (moving_piece == BLACK_KING) board->king_position[BLACK] = to_square;
        else board->piece_bitboard[moving_piece] ^= from_to_bitboard;

        board->to_move = WHITE;
    }

    board->hash_key ^= hash_keys.side;
    board->can_castle &= FROM_SQUARE_CASTLING_RIGHTS_MASK[from_square];
    if (board->can_castle != board->state[board->state_index].can_castle) {
        if ((board->can_castle & WHITE_CASTLE_OO) != (board->state[board->state_index].can_castle & WHITE_CASTLE_OO)) board->hash_key ^= hash_keys.white_king_side_castle;
        if ((board->can_castle & WHITE_CASTLE_OOO) != (board->state[board->state_index].can_castle & WHITE_CASTLE_OOO)) board->hash_key ^= hash_keys.white_queen_side_castle;
        if ((board->can_castle & BLACK_CASTLE_OO) != (board->state[board->state_index].can_castle & BLACK_CASTLE_OO)) board->hash_key ^= hash_keys.black_king_side_castle;
        if ((board->can_castle & BLACK_CASTLE_OOO) != (board->state[board->state_index].can_castle & BLACK_CASTLE_OOO)) board->hash_key ^= hash_keys.black_queen_side_castle;
    }
    board->all_pieces_bitboard = board->color_bitboard[WHITE] | board->color_bitboard[BLACK];
    board->state_index++;
}