int board_endgame(const board_t * board) { int endgame; int colour; const sq_t * ptr; int sq, piece; ASSERT(board!=NULL); endgame = 0; for (colour = 0; colour < ColourNb; colour++) { for (ptr = &board->piece[colour][0]; (sq=*ptr) != SquareNone; ptr++) { piece = board->square[sq]; endgame += PST(PIECE_TO_12(piece),SQUARE_TO_64(sq),Endgame); } for (ptr = &board->pawn[colour][0]; (sq=*ptr) != SquareNone; ptr++) { piece = board->square[sq]; endgame += PST(PIECE_TO_12(piece),SQUARE_TO_64(sq),Endgame); } } return endgame; }
int board_opening(const board_t * board) { int opening; int colour; const sq_t * ptr; int sq, piece; ASSERT(board!=NULL); opening = 0; for (colour = 0; colour < ColourNb; colour++) { for (ptr = &board->piece[colour][0]; (sq=*ptr) != SquareNone; ptr++) { piece = board->square[sq]; opening += PST(PIECE_TO_12(piece),SQUARE_TO_64(sq),Opening); } for (ptr = &board->pawn[colour][0]; (sq=*ptr) != SquareNone; ptr++) { piece = board->square[sq]; opening += PST(PIECE_TO_12(piece),SQUARE_TO_64(sq),Opening); } } return opening; }
U64 hash_piece_key(S32 piece, S32 square) { ASSERT(piece_is_ok(piece)); ASSERT(SQUARE_IS_OK(square)); return RANDOM_64(RandomPiece + (PIECE_TO_12(piece) ^ 1) * 64 + SQUARE_TO_64(square)); // HACK: ^1 for PolyGlot book }
void move_eval(const board_t * board, int eval) { int index; int best_value, value; int move; ASSERT(board!=NULL); ASSERT(value_is_ok(eval)); move = board->move; ASSERT(move_is_ok(move)); // exceptions if ((move & (1 << 15)) != 0) return; if (MOVE_TO(move) == board->cap_sq) return; if (MOVE_IS_CASTLE(move)) return; ASSERT(!MOVE_IS_PROMOTE(move)); ASSERT(!MOVE_IS_EN_PASSANT(move)); ASSERT(board->cap_sq==Empty); ASSERT(!board_is_check(board)); index = PIECE_TO_12(board->square[MOVE_TO(move)]) * 64 + SQUARE_TO_64(MOVE_TO(move)); ASSERT(index>=0&&index<HistorySize); if (eval > ValueQueen) { value = ValueQueen; } else if (eval < -ValueQueen) { value = -ValueQueen; } else { value = eval; } best_value = HistEval[index]; ASSERT(best_value<=HistoryEvalMax); ASSERT(best_value>=-HistoryEvalMax); if (value >= best_value) { if (value == HistoryEvalValue) value++; HistEval[index] = value; } else { if (HistEval[index] > -ValueQueen) { if (best_value == HistoryEvalValue+1) { HistEval[index] -= 2; } else { HistEval[index]--; } } } ASSERT(HistEval[index]!=HistoryEvalValue); ASSERT(HistEval[index]<=HistoryEvalMax); ASSERT(HistEval[index]>=-HistoryEvalMax); }
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_TO(move)); ASSERT(index>=0&&index<HistorySize); return index; }
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; }
void history_very_bad(int move, const board_t * board) { int index; ASSERT(move_is_ok(move)); ASSERT(board!=NULL); //if (move_is_tactical(move,board)) return; // history index = PIECE_TO_12(board->square[MOVE_TO(move)]) * 64 + SQUARE_TO_64(MOVE_TO(move)); HistTot[index] += 100; if (HistTot[index] >= HistoryMax) { HistHit[index] = (HistHit[index] + 1) / 2; HistTot[index] = (HistTot[index] + 1) / 2; } ASSERT(HistHit[index]<=HistTot[index]); ASSERT(HistTot[index]<HistoryMax); }
int piece_to_char(int piece) { ASSERT(piece_is_ok(piece)); return PieceString[PIECE_TO_12(piece)]; }
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)); }
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; } }
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)); } }
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]); } }
bool egbb_probe(const board_t * board, int * value) { int i; int sq; int piece; int colour, me; const sq_t * ptr; int counter; int white_king, black_king; int piece_list[4], square_list[4]; ASSERT(board!=NULL); ASSERT(value!=NULL); ASSERT(board_is_ok(board)); ASSERT(!board_is_check(board)); // init if (Egbb->init == 0) return false; if (Egbb->load == 0) return false; ASSERT(board->piece_nb<=Egbb->piece_nb); // init for (i = 0; i < 4; i++) { piece_list[i] = 0; square_list[i] = 0; } Egbb->read_nb++; // king white_king = SQUARE_TO_64(KING_POS(board,White)); black_king = SQUARE_TO_64(KING_POS(board,Black)); counter = 0; for (colour = 0; colour < ColourNb; colour++) { me = colour; // pieces for (ptr = &board->piece[me][1]; (sq=*ptr) != SquareNone; ptr++) { // HACK: no king piece = board->square[sq]; // index ASSERT(counter>=0&&counter<4); piece_list[counter] = TbPiece[PIECE_TO_12(piece)]; square_list[counter] = SQUARE_TO_64(sq); counter++; } // pawns for (ptr = &board->pawn[me][0]; (sq=*ptr) != SquareNone; ptr++) { piece = board->square[sq]; // index ASSERT(counter>=0&&counter<4); piece_list[counter] = TbPiece[PIECE_TO_12(piece)]; square_list[counter] = SQUARE_TO_64(sq); counter++; } } // probe *value = probe_egbb_ptr(board->turn,white_king,black_king,piece_list[0],square_list[0],piece_list[1],square_list[1],piece_list[2],square_list[2]); // score if (*value != ValueError) { Egbb->read_hit++; ASSERT(!value_is_mate(*value)); return true; } return false; }