Example #1
0
bool draw_krkr( const board_t *board)
{
	int rrook, brook;
	int rking, bking;

	if(board->piece[PIECE_TO_INDEX(RedRook)] != PieceNone)
		rrook = board->piece[PIECE_TO_INDEX(RedRook)];

	if(board->piece[PIECE_TO_INDEX(RedRook) + 1] != PieceNone)
		rrook = board->piece[PIECE_TO_INDEX(RedRook) + 1];

	if(board->piece[PIECE_TO_INDEX(BlackRook)] != PieceNone)
		brook = board->piece[PIECE_TO_INDEX(RedRook)];

	if(board->piece[PIECE_TO_INDEX(BlackRook) + 1] != PieceNone)
		brook = board->piece[PIECE_TO_INDEX(RedRook) + 1];

	rking = KING_POS(board, Red);
	bking = KING_POS(board, Black);

	if(EQUAL_FILE(rrook, rking) && EQUAL_RANK(brook, bking))
		return true;

    if(SQUARE_FILE(rking) != 0x7 && SQUARE_FILE(bking) != 0x7)
	{
		if(SQUARE_RANK(rking) < 0xa && SQUARE_RANK(bking) > 0x5)
			return true;

	} 

	return false;
}
Example #2
0
static bool is_passed(const board_t * board, int to) { 

   int t2; 
   int me, opp;
   int file, rank;

   me = board->turn; 
   opp = COLOUR_OPP(me);
   file = SQUARE_FILE(to);
   rank = PAWN_RANK(to,me);
 
   t2 = board->pawn_file[me][file] | BitRev[board->pawn_file[opp][file]]; 

   // passed pawns 
   if ((t2 & BitGT[rank]) == 0) { 
 
    if (((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitGT[rank]) == 0) { 
        return true;

       } 
   } 

   return false;
 
}
Example #3
0
static bool kbpk_draw (int wp, int wb, int bk) {

   ASSERT(SQUARE_IS_OK(wp));
   ASSERT(SQUARE_IS_OK(wb));
   ASSERT(SQUARE_IS_OK(bk));

   if (SQUARE_FILE(wp) == FileA
    && DISTANCE(bk,A8) <= 1
    && SQUARE_COLOUR(wb) != SQUARE_COLOUR(A8)) {
      return true;
   }

   return false;
}
Example #4
0
void move_do_null(board_t * board, undo_t * undo) {

   int sq;

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

   ASSERT(board_is_legal(board));
   ASSERT(!board_is_check(board));

   // initialise undo

   undo->turn = board->turn;
   undo->ep_square = board->ep_square;
   undo->ply_nb = board->ply_nb;
   undo->cap_sq = board->cap_sq;
	undo->moving_piece = board->moving_piece;
   undo->key = board->key;

   // update key stack

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

   // update turn

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

   // update en-passant square

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

   // update move number

   board->ply_nb = 0; // HACK: null move is considered as a conversion

   // update last square

   board->cap_sq = SquareNone;
	board->moving_piece = PieceNone256;

   // debug

   ASSERT(board_is_ok(board));
}
Example #5
0
U64 hash_ep_key(S32 square) {

	ASSERT(SQUARE_IS_OK(square));

	return RANDOM_64(RandomEnPassant + SQUARE_FILE(square) - FileA);
}
Example #6
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;
}
Example #7
0
void board_init_list(board_t * board) {

   int sq_64, sq, piece;
   int colour, pos;
   int i, size;
   int square;
   int order;
   int file;

   ASSERT(board!=NULL);

   // init

   for (sq = 0; sq < SquareNb; sq++) {
      board->pos[sq] = -1;
   }

   board->piece_nb = 0;
   for (piece = 0; piece < 12; piece++) board->number[piece] = 0;

   // piece lists

   for (colour = 0; colour < ColourNb; colour++) {

      // piece list

      pos = 0;

      for (sq_64 = 0; sq_64 < 64; sq_64++) {

         sq = SQUARE_FROM_64(sq_64);
         piece = board->square[sq];
         if (piece != Empty && !piece_is_ok(piece)) my_fatal("board_init_list(): illegal position\n");

         if (COLOUR_IS(piece,colour) && !PIECE_IS_PAWN(piece)) {

            if (pos >= 16) my_fatal("board_init_list(): illegal position\n");
            ASSERT(pos>=0&&pos<16);

            board->pos[sq] = pos;
            board->piece[colour][pos] = sq;
            pos++;

            board->piece_nb++;
            board->number[PIECE_TO_12(piece)]++;
         }
      }

      if (board->number[COLOUR_IS_WHITE(colour)?WhiteKing12:BlackKing12] != 1) my_fatal("board_init_list(): illegal position\n");

      ASSERT(pos>=1&&pos<=16);
      board->piece[colour][pos] = SquareNone;
      board->piece_size[colour] = pos;

      // MV sort

      size = board->piece_size[colour];

      for (i = 1; i < size; i++) {

         square = board->piece[colour][i];
         piece = board->square[square];
         order = PIECE_ORDER(piece);

         for (pos = i; pos > 0 && order > PIECE_ORDER(board->square[(sq=board->piece[colour][pos-1])]); pos--) {
            ASSERT(pos>0&&pos<size);
            board->piece[colour][pos] = sq;
            ASSERT(board->pos[sq]==pos-1);
            board->pos[sq] = pos;
         }

         ASSERT(pos>=0&&pos<size);
         board->piece[colour][pos] = square;
         ASSERT(board->pos[square]==i);
         board->pos[square] = pos;
      }

      // debug

      if (DEBUG) {

         for (i = 0; i < board->piece_size[colour]; i++) {

            sq = board->piece[colour][i];
            ASSERT(board->pos[sq]==i);

            if (i == 0) { // king
               ASSERT(PIECE_IS_KING(board->square[sq]));
            } else {
               ASSERT(!PIECE_IS_KING(board->square[sq]));
               ASSERT(PIECE_ORDER(board->square[board->piece[colour][i]])<=PIECE_ORDER(board->square[board->piece[colour][i-1]]));
            }
         }
      }

      // pawn list

      for (file = 0; file < FileNb; file++) {
         board->pawn_file[colour][file] = 0;
      }

      pos = 0;

      for (sq_64 = 0; sq_64 < 64; sq_64++) {

         sq = SQUARE_FROM_64(sq_64);
         piece = board->square[sq];

         if (COLOUR_IS(piece,colour) && PIECE_IS_PAWN(piece)) {

            if (pos >= 8 || SQUARE_IS_PROMOTE(sq)) my_fatal("board_init_list(): illegal position\n");
            ASSERT(pos>=0&&pos<8);

            board->pos[sq] = pos;
            board->pawn[colour][pos] = sq;
            pos++;

            board->piece_nb++;
            board->number[PIECE_TO_12(piece)]++;
            board->pawn_file[colour][SQUARE_FILE(sq)] |= BIT(PAWN_RANK(sq,colour));
         }
      }

      ASSERT(pos>=0&&pos<=8);
      board->pawn[colour][pos] = SquareNone;
      board->pawn_size[colour] = pos;

      if (board->piece_size[colour] + board->pawn_size[colour] > 16) my_fatal("board_init_list(): illegal position\n");
   }

   // last square

   board->cap_sq = SquareNone;

   // PST

   board->opening = board_opening(board);
   board->endgame = board_endgame(board);

   // hash key

   for (i = 0; i < board->ply_nb; i++) board->stack[i] = 0; // HACK
   board->sp = board->ply_nb;

   board->key = hash_key(board);
   board->pawn_key = hash_pawn_key(board);
   board->material_key = hash_material_key(board);

   // legality

   if (!board_is_legal(board)) my_fatal("board_init_list(): illegal position\n");

   // debug

   ASSERT(board_is_ok(board));
}
Example #8
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));
}
Example #9
0
static void square_move(board_t * board, int from, int to, int piece, bool update) {

   int colour;
   int pos;
   int from_64, to_64;
   int piece_12;
   int piece_index;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(from));
   ASSERT(SQUARE_IS_OK(to));
   ASSERT(piece_is_ok(piece));
   ASSERT(update==true||update==false);

   // init

   colour = PIECE_COLOUR(piece);

   pos = board->pos[from];
   ASSERT(pos>=0);

   // from

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

   ASSERT(board->pos[from]==pos);
   board->pos[from] = -1; // not needed

   // to

   ASSERT(board->square[to]==Empty);
   board->square[to] = piece;

   ASSERT(board->pos[to]==-1);
   board->pos[to] = pos;

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      ASSERT(board->piece[colour][pos]==from);
      board->piece[colour][pos] = to;

   } else {

      ASSERT(board->pawn[colour][pos]==from);
      board->pawn[colour][pos] = to;

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(from)] ^= BIT(PAWN_RANK(from,colour));
      board->pawn_file[colour][SQUARE_FILE(to)]   ^= BIT(PAWN_RANK(to,colour));
   }

   // update

   if (update) {

      // init

      from_64 = SQUARE_TO_64(from);
      to_64 = SQUARE_TO_64(to);
      piece_12 = PIECE_TO_12(piece);

      // PST

      board->opening += PST(piece_12,to_64,Opening) - PST(piece_12,from_64,Opening);
      board->endgame += PST(piece_12,to_64,Endgame) - PST(piece_12,from_64,Endgame);

      // hash key

      piece_index = RandomPiece + (piece_12^1) * 64; // HACK: ^1 for PolyGlot book

      hash_xor = RANDOM_64(piece_index+to_64) ^ RANDOM_64(piece_index+from_64);

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;
   }
}
Example #10
0
static void square_set(board_t * board, int square, int piece, int pos, bool update) {

   int piece_12, colour;
   int sq;
   int i, size;
   int sq_64;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(square));
   ASSERT(piece_is_ok(piece));
   ASSERT(pos>=0);
   ASSERT(update==true||update==false);

   // init

   piece_12 = PIECE_TO_12(piece);
   colour = PIECE_COLOUR(piece);

   // square

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

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      // init

      size = board->piece_size[colour];
      ASSERT(size>=0);

      // size

      size++;

      board->piece[colour][size] = SquareNone;
      board->piece_size[colour] = size;

      // stable swap

      ASSERT(pos>=0&&pos<size);

      for (i = size-1; i > pos; i--) {

         sq = board->piece[colour][i-1];

         board->piece[colour][i] = sq;

         ASSERT(board->pos[sq]==i-1);
         board->pos[sq] = i;
      }

      board->piece[colour][pos] = square;

      ASSERT(board->pos[square]==-1);
      board->pos[square] = pos;

   } else {

      // init

      size = board->pawn_size[colour];
      ASSERT(size>=0);

      // size

      size++;

      board->pawn[colour][size] = SquareNone;
      board->pawn_size[colour] = size;

      // stable swap

      ASSERT(pos>=0&&pos<size);

      for (i = size-1; i > pos; i--) {

         sq = board->pawn[colour][i-1];

         board->pawn[colour][i] = sq;

         ASSERT(board->pos[sq]==i-1);
         board->pos[sq] = i;
      }

      board->pawn[colour][pos] = square;

      ASSERT(board->pos[square]==-1);
      board->pos[square] = pos;

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square,colour));
   }

   // material

   ASSERT(board->piece_nb<32);
   board->piece_nb++;;

   ASSERT(board->number[piece_12]<9);
   board->number[piece_12]++;

   // update

   if (update) {

      // init

      sq_64 = SQUARE_TO_64(square);

      // PST

      board->opening += PST(piece_12,sq_64,Opening);
      board->endgame += PST(piece_12,sq_64,Endgame);

      // hash key

      hash_xor = RANDOM_64(RandomPiece+(piece_12^1)*64+sq_64); // HACK: ^1 for PolyGlot book

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;

      // material key

      board->material_key ^= RANDOM_64(piece_12*16+(board->number[piece_12]-1));
   }
}
Example #11
0
static void pawn_comp_info(pawn_info_t * info, const board_t * board) {

   int colour;
   int file, rank;
   int me, opp;
   const sq_t * ptr;
   int sq;
   bool backward, candidate, doubled, isolated, open, passed;
   int t1, t2;
   int n;
   int bits;
   int opening[ColourNb], endgame[ColourNb];
   int flags[ColourNb];
   int file_bits[ColourNb];
   int passed_bits[ColourNb];
   int single_file[ColourNb];

   ASSERT(info!=NULL);
   ASSERT(board!=NULL);

   // pawn_file[]

#if DEBUG
   for (colour = 0; colour < ColourNb; colour++) {

      int pawn_file[FileNb];

      me = colour;

      for (file = 0; file < FileNb; file++) {
         pawn_file[file] = 0;
      }

      for (ptr = &board->pawn[me][0]; (sq=*ptr) != SquareNone; ptr++) {

         file = SQUARE_FILE(sq);
         rank = PAWN_RANK(sq,me);

         ASSERT(file>=FileA&&file<=FileH);
         ASSERT(rank>=Rank2&&rank<=Rank7);

         pawn_file[file] |= BIT(rank);
      }

      for (file = 0; file < FileNb; file++) {
         if (board->pawn_file[colour][file] != pawn_file[file]) my_fatal("board->pawn_file[][]\n");
      }
   }
#endif

   // init

   for (colour = 0; colour < ColourNb; colour++) {

      opening[colour] = 0;
      endgame[colour] = 0;

      flags[colour] = 0;
      file_bits[colour] = 0;
      passed_bits[colour] = 0;
      single_file[colour] = SquareNone;
   }

   // features and scoring

   for (colour = 0; colour < ColourNb; colour++) {

      me = colour;
      opp = COLOUR_OPP(me);

      for (ptr = &board->pawn[me][0]; (sq=*ptr) != SquareNone; ptr++) {

         // init

         file = SQUARE_FILE(sq);
         rank = PAWN_RANK(sq,me);

         ASSERT(file>=FileA&&file<=FileH);
         ASSERT(rank>=Rank2&&rank<=Rank7);

         // flags

         file_bits[me] |= BIT(file);
         if (rank == Rank2) flags[me] |= BackRankFlag;

         // features

         backward = false;
         candidate = false;
         doubled = false;
         isolated = false;
         open = false;
         passed = false;

         t1 = board->pawn_file[me][file-1] | board->pawn_file[me][file+1];
         t2 = board->pawn_file[me][file] | BitRev[board->pawn_file[opp][file]];

         // doubled

         if ((board->pawn_file[me][file] & BitLT[rank]) != 0) {
            doubled = true;
         }

         // isolated and backward

         if (t1 == 0) {

            isolated = true;

         } else if ((t1 & BitLE[rank]) == 0) {

            backward = true;

            // really backward?

            if ((t1 & BitRank1[rank]) != 0) {

               ASSERT(rank+2<=Rank8);

               if (((t2 & BitRank1[rank])
                  | ((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitRank2[rank])) == 0) {

                  backward = false;
               }

            } else if (rank == Rank2 && ((t1 & BitEQ[rank+2]) != 0)) {

               ASSERT(rank+3<=Rank8);

               if (((t2 & BitRank2[rank])
                  | ((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitRank3[rank])) == 0) {

                  backward = false;
               }
            }
         }

         // open, candidate and passed

         if ((t2 & BitGT[rank]) == 0) {

            open = true;

            if (((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitGT[rank]) == 0) {

               passed = true;
               passed_bits[me] |= BIT(file);

            } else {

               // candidate?

               n = 0;

               n += BIT_COUNT(board->pawn_file[me][file-1]&BitLE[rank]);
               n += BIT_COUNT(board->pawn_file[me][file+1]&BitLE[rank]);

               n -= BIT_COUNT(BitRev[board->pawn_file[opp][file-1]]&BitGT[rank]);
               n -= BIT_COUNT(BitRev[board->pawn_file[opp][file+1]]&BitGT[rank]);

               if (n >= 0) {

                  // safe?

                  n = 0;

                  n += BIT_COUNT(board->pawn_file[me][file-1]&BitEQ[rank-1]);
                  n += BIT_COUNT(board->pawn_file[me][file+1]&BitEQ[rank-1]);

                  n -= BIT_COUNT(BitRev[board->pawn_file[opp][file-1]]&BitEQ[rank+1]);
                  n -= BIT_COUNT(BitRev[board->pawn_file[opp][file+1]]&BitEQ[rank+1]);

                  if (n >= 0) candidate = true;
               }
            }
         }

		 // outposts

		 if (me == White) {
			if (SQUARE_IS_OK(sq+15)) {
		       if (WEAK_SQUARE_BLACK(sq+15)) opening[White] += OutpostMatrix[White][SQUARE_TO_64(sq+15)];
			   else opening[White] += (OutpostMatrix[White][SQUARE_TO_64(sq+15)]+1)/2;
			}
			if (SQUARE_IS_OK(sq+17)) {
		       if (WEAK_SQUARE_BLACK(sq+17)) opening[White] += OutpostMatrix[White][SQUARE_TO_64(sq+17)];
			   else opening[White] += (OutpostMatrix[White][SQUARE_TO_64(sq+17)]+1)/2;
			}
		 } else {
            if (SQUARE_IS_OK(sq-15)) {
		       if (WEAK_SQUARE_WHITE(sq-15)) opening[Black] += OutpostMatrix[Black][SQUARE_TO_64(sq-15)];
			   else opening[Black] += (OutpostMatrix[Black][SQUARE_TO_64(sq-15)]+1)/2;
			}
			if (SQUARE_IS_OK(sq-17)) {
		       if (WEAK_SQUARE_WHITE(sq-17)) opening[Black] += OutpostMatrix[Black][SQUARE_TO_64(sq-17)];
			   else opening[Black] += (OutpostMatrix[Black][SQUARE_TO_64(sq-17)]+1)/2;
			}
		 }

         // score

         if (doubled) {
            opening[me] -= DoubledOpening;
            endgame[me] -= DoubledEndgame;
         }

         if (isolated) {
            if (open) {
               opening[me] -= IsolatedOpeningOpen;
               endgame[me] -= IsolatedEndgame;
            } else {
               opening[me] -= IsolatedOpening;
               endgame[me] -= IsolatedEndgame;
            }
         }

         if (backward) {
            if (open) {
               opening[me] -= BackwardOpeningOpen;
               endgame[me] -= BackwardEndgame;
            } else {
               opening[me] -= BackwardOpening;
               endgame[me] -= BackwardEndgame;
            }
         }

         if (candidate) {
            opening[me] += quad(CandidateOpeningMin,CandidateOpeningMax,rank);
            endgame[me] += quad(CandidateEndgameMin,CandidateEndgameMax,rank);
         }

         // this was moved to the dynamic evaluation

/*
         if (passed) {
            opening[me] += quad(PassedOpeningMin,PassedOpeningMax,rank);
            endgame[me] += quad(PassedEndgameMin,PassedEndgameMax,rank);
         }
*/
      }
   }

   // store info

   info->opening = ((opening[White] - opening[Black]) * PawnStructureWeight) / 256;
   info->endgame = ((endgame[White] - endgame[Black]) * PawnStructureWeight) / 256;

   for (colour = 0; colour < ColourNb; colour++) {

      me = colour;
      opp = COLOUR_OPP(me);

      // draw flags

      bits = file_bits[me];

      if (bits != 0 && (bits & (bits-1)) == 0) { // one set bit

         file = BIT_FIRST(bits);
         rank = BIT_FIRST(board->pawn_file[me][file]);
         ASSERT(rank>=Rank2);

         if (((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitGT[rank]) == 0) {
            rank = BIT_LAST(board->pawn_file[me][file]);
            single_file[me] = SQUARE_MAKE(file,rank);
         }
      }

      info->flags[colour] = flags[colour];
      info->passed_bits[colour] = passed_bits[colour];
      info->single_file[colour] = single_file[colour];
   }
}
Example #12
0
bool recog_draw(const board_t * board, int ThreadId) {

   material_info_t mat_info[1];

   ASSERT(board!=NULL);

   // material

   if (board->piece_nb > 4) return false;

   material_get_info(mat_info,board,ThreadId);

   if ((mat_info->flags & DrawNodeFlag) == 0) return false;

   // recognisers

   if (false) {

   } else if (mat_info->recog == MAT_KK) {

      // KK

      return true;

   } else if (mat_info->recog == MAT_KBK) {

      // KBK (white)

      return true;

   } else if (mat_info->recog == MAT_KKB) {

      // KBK (black)

      return true;

   } else if (mat_info->recog == MAT_KNK) {

      // KNK (white)

      return true;

   } else if (mat_info->recog == MAT_KKN) {

      // KNK (black)

      return true;

   } else if (mat_info->recog == MAT_KPK) {

      // KPK (white)

      int me, opp;
      int wp, wk, bk;

      me = White;
      opp = COLOUR_OPP(me);

      wp = board->pawn[me][0];
      wk = KING_POS(board,me);
      bk = KING_POS(board,opp);

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wk = SQUARE_FILE_MIRROR(wk);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kpk_draw(wp,wk,bk,board->turn)) {
         return true;
      }

   } else if (mat_info->recog == MAT_KKP) {

      // KPK (black)

      int me, opp;
      int wp, wk, bk;

      me = Black;
      opp = COLOUR_OPP(me);

      wp = SQUARE_RANK_MIRROR(board->pawn[me][0]);
      wk = SQUARE_RANK_MIRROR(KING_POS(board,me));
      bk = SQUARE_RANK_MIRROR(KING_POS(board,opp));

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wk = SQUARE_FILE_MIRROR(wk);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kpk_draw(wp,wk,bk,COLOUR_OPP(board->turn))) {
         return true;
      }

   } else if (mat_info->recog == MAT_KBKB) {

      // KBKB

      int wb, bb;

      wb = board->piece[White][1];
      bb = board->piece[Black][1];

      if (SQUARE_COLOUR(wb) == SQUARE_COLOUR(bb)) { // bishops on same colour
         return true;
      }

   } else if (mat_info->recog == MAT_KBPK) {

      // KBPK (white)

      int me, opp;
      int wp, wb, bk;

      me = White;
      opp = COLOUR_OPP(me);

      wp = board->pawn[me][0];
      wb = board->piece[me][1];
      bk = KING_POS(board,opp);

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wb = SQUARE_FILE_MIRROR(wb);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kbpk_draw(wp,wb,bk)) return true;

   } else if (mat_info->recog == MAT_KKBP) {

      // KBPK (black)

      int me, opp;
      int wp, wb, bk;

      me = Black;
      opp = COLOUR_OPP(me);

      wp = SQUARE_RANK_MIRROR(board->pawn[me][0]);
      wb = SQUARE_RANK_MIRROR(board->piece[me][1]);
      bk = SQUARE_RANK_MIRROR(KING_POS(board,opp));

      if (SQUARE_FILE(wp) >= FileE) {
         wp = SQUARE_FILE_MIRROR(wp);
         wb = SQUARE_FILE_MIRROR(wb);
         bk = SQUARE_FILE_MIRROR(bk);
      }

      if (kbpk_draw(wp,wb,bk)) return true;

   } else {

      ASSERT(false);
   }

   return false;
}
Example #13
0
static bool kpk_draw(int wp, int wk, int bk, int turn) {

   int wp_file, wp_rank;
   int wk_file;
   int bk_file, bk_rank;

   ASSERT(SQUARE_IS_OK(wp));
   ASSERT(SQUARE_IS_OK(wk));
   ASSERT(SQUARE_IS_OK(bk));
   ASSERT(COLOUR_IS_OK(turn));

   ASSERT(SQUARE_FILE(wp)<=FileD);

   wp_file = SQUARE_FILE(wp);
   wp_rank = SQUARE_RANK(wp);

   wk_file = SQUARE_FILE(wk);

   bk_file = SQUARE_FILE(bk);
   bk_rank = SQUARE_RANK(bk);

   if (false) {

   } else if (bk == wp+16) {

      if (wp_rank <= Rank6) {

         return true;

      } else {

         ASSERT(wp_rank==Rank7);

         if (COLOUR_IS_WHITE(turn)) {
            if (wk == wp-15 || wk == wp-17) return true;
         } else {
            if (wk != wp-15 && wk != wp-17) return true;
         }
      }

   } else if (bk == wp+32) {

      if (wp_rank <= Rank5) {

         return true;

      } else {

         ASSERT(wp_rank==Rank6);

         if (COLOUR_IS_WHITE(turn)) {
            if (wk != wp-1 && wk != wp+1) return true;
         } else {
            return true;
         }
      }

   } else if (wk == wp-1 || wk == wp+1) {

      if (bk == wk+32 && COLOUR_IS_WHITE(turn)) { // opposition
         return true;
      }

   } else if (wk == wp+15 || wk == wp+16 || wk == wp+17) {

      if (wp_rank <= Rank4) {
         if (bk == wk+32 && COLOUR_IS_WHITE(turn)) { // opposition
            return true;
         }
      }
   }

   // rook pawn

   if (wp_file == FileA) {

      if (DISTANCE(bk,A8) <= 1) return true;

      if (wk_file == FileA) {
         if (wp_rank == Rank2) wp_rank++; // HACK
         if (bk_file == FileC && bk_rank > wp_rank) return true;
      }
   }

   return false;
}
Example #14
0
static void square_clear(board_t * board, int square, int piece, bool update) {

   int pos, piece_12, colour;
   int sq;
   int i, size;
   int sq_64;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(square));
   ASSERT(piece_is_ok(piece));
   ASSERT(update==true||update==false);

   // init

   pos = board->pos[square];
   ASSERT(pos>=0);

   piece_12 = PIECE_TO_12(piece);
   colour = PIECE_COLOUR(piece);

   // square

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

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      // init

      size = board->piece_size[colour];
      ASSERT(size>=1);

      // stable swap

      ASSERT(pos>=0&&pos<size);

      ASSERT(board->pos[square]==pos);
      board->pos[square] = -1;

      for (i = pos; i < size-1; i++) {

         sq = board->piece[colour][i+1];

         board->piece[colour][i] = sq;

         ASSERT(board->pos[sq]==i+1);
         board->pos[sq] = i;
      }

      // size

      size--;

      board->piece[colour][size] = SquareNone;
      board->piece_size[colour] = size;

   } else {

      // init

      size = board->pawn_size[colour];
      ASSERT(size>=1);

      // stable swap

      ASSERT(pos>=0&&pos<size);

      ASSERT(board->pos[square]==pos);
      board->pos[square] = -1;

      for (i = pos; i < size-1; i++) {

         sq = board->pawn[colour][i+1];

         board->pawn[colour][i] = sq;

         ASSERT(board->pos[sq]==i+1);
         board->pos[sq] = i;
      }

      // size

      size--;

      board->pawn[colour][size] = SquareNone;
      board->pawn_size[colour] = size;

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square,colour));
   }

   // material

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

   ASSERT(board->number[piece_12]>0);
   board->number[piece_12]--;

   board->piece_material[colour] -= VALUE_PIECE(piece);  // Thomas 
   
   // update

   if (update) {

      // init

      sq_64 = SQUARE_TO_64(square);

      // PST

      board->opening -= PST(piece_12,sq_64,Opening);
      board->endgame -= PST(piece_12,sq_64,Endgame);

      // hash key

      hash_xor = RANDOM_64(RandomPiece+(piece_12^1)*64+sq_64); // HACK: ^1 for PolyGlot book

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;

      // material key

      board->material_key ^= RANDOM_64(piece_12*16+board->number[piece_12]);
   }
}