unsigned long long calculate_zobrist(struct Board * board) { unsigned long long zobristHash = 0; int i; for(i = 0; i < 12; ++i) { bitboard piece = board->pieces[i]; while (piece) { int index = bit_scan_forward(piece); zobristHash ^= pieceKeys[i][index]; piece = clear_lsb(piece); } } if (board->sideToMove == BLACK) { zobristHash ^= blackToMoveKey; } assert(board->castling < 16); zobristHash ^= castlingKeys[board->castling]; if (board->enPassant) { int index = bit_scan_forward(board->enPassant); zobristHash ^= enPassantKeys[index]; } return zobristHash; }
void MoveGenerator::add_moves(U8 from, U64 targets, class MoveList& list, const class Board &board, const U32 flags){ while(targets){ U32 to = bit_scan_forward(targets); U32 capture = board[to]; U32 move = from | (to << 8) | (capture << 24) | flags; list.push(move); targets &= targets - 1; } }
void MoveGenerator::add_king_moves(class MoveList &list, const class Board &board, const int side){ U64 kings = board.bitboards[KING|side]; U64 non_friendly = ~board.bitboards[side]; while(kings){ U8 from = bit_scan_forward(kings); U64 targets = KING_LOOKUP_TABLE[from] & non_friendly; add_moves(from, targets, list, board, NO_FLAGS); kings &= kings - 1; } }
void MoveGenerator::add_moves_with_diff(int diff, U64 targets, class MoveList& list, const class Board &board, const U32 flags){ while(targets){ U32 to = bit_scan_forward(targets); U32 from = ((U32)(to - diff)) % 64; U32 capture = board[to]; U32 move = from | (to << 8) | flags | (capture << 24); list.push(move); targets &= targets - 1; } }
U64 get_positive_ray_attacks(U64 occupied, enum Direction dir, U64 square) { U64 attacks = ray_attacks[dir][square]; U64 blocker = attacks & occupied; if ( blocker ) { square = bit_scan_forward(blocker); attacks ^= ray_attacks[dir][square]; } return attacks; }
unsigned int perft_perft(Board* board, unsigned int depth) { int i, nperft = 0; Move moves[256]; if (depth == 0) { return 1; } TTEntry* ttentry = get_tt_entry_at_depth(board->zobrist, depth); if (ttentry) { return ttentry->score; } unsigned int numMoves = generate_moves(board, moves); for (i = 0; i < numMoves; ++i) { make_move(board, moves[i]); if ((board->sideToMove == BLACK && !black_attacks_square(board, bit_scan_forward(board->pieces[WHITE_KING]))) || (board->sideToMove == WHITE && !white_attacks_square(board, bit_scan_forward(board->pieces[BLACK_KING])))) { nperft += perft_perft(board, depth - 1); } unmake_move(board, moves[i]); } TTEntry new_entry; new_entry.key = board->zobrist; new_entry.score = nperft; new_entry.depth = depth; put_tt_entry(&new_entry); return nperft; }
void MoveGenerator::add_promotions_with_diff(int diff, U64 targets, class MoveList& list, const class Board &board, const U32 side){ U32 flags = side << 16; // move to third byte while(targets){ U32 to = bit_scan_forward(targets); U32 from = ((U32)(to - diff)) % 64; U32 capture = board[to]; U32 move = from | (to << 8) | flags | (capture << 24) ; list.push(move | (KNIGHT << 16)); list.push(move | (BISHOP << 16)); list.push(move | (ROOK << 16)); list.push(move | (QUEEN << 16)); targets &= targets - 1; } }
int evaluate_piece(bitboard pieces, int* squareValues, int pieceValue) { int score = 0; while(pieces) { int pieceSquare = bit_scan_forward(pieces); score += squareValues[pieceSquare] + pieceValue; pieces = clear_lsb(pieces); } return score; }
inline static int fm_bmp_first_set(struct fm_block* qm, int start) { int bmp_idx; int bit; int r; fm_hash_bitmap_t test_val; fm_hash_bitmap_t v; bmp_idx=start/FM_HASH_BMP_BITS; bit=start%FM_HASH_BMP_BITS; test_val=1UL <<((unsigned long)bit); if (qm->free_bitmap[bmp_idx] & test_val) return start; else if (qm->free_bitmap[bmp_idx] & ~(test_val-1)){ #if 0 test_val<<=1; for (r=bit+1; r<FM_HASH_BMP_BITS; r++, test_val<<=1){ if (qm->free_bitmap[bmp_idx] & test_val) return (start-bit+r); } #endif v=qm->free_bitmap[bmp_idx]>>(bit+1); return start+1+bit_scan_forward((unsigned long)v); }
int movegen(struct Game* game, int move_count) { U64 temp_move, temp_move2, temp_piece; U32 from, to, move; U64 free_squares = game->board[OCCUPIED][0]; if (game->to_move == WHITE) { /***************/ /* WHITE PAWNS */ /***************/ temp_move = step_up(game->board[PAWNS][WHITE]) & free_squares; temp_move2 = temp_move; /* single pushes */ while (temp_move) { to = bit_scan_forward(temp_move); if (to/8 == 7) { /* time for a promotion */ game->move_buffer[move_count++] = create_move(to-8,to,BISHOP_PROMO_FLAG); game->move_buffer[move_count++] = create_move(to-8,to,KNIGHT_PROMO_FLAG); game->move_buffer[move_count++] = create_move(to-8,to,ROOK_PROMO_FLAG); game->move_buffer[move_count++] = create_move(to-8,to,QUEEN_PROMO_FLAG); } else game->move_buffer[move_count++] = create_move(to-8,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* double pushes */ temp_move2 = step_up(temp_move2) & free_squares & rank4; while (temp_move2) { to = bit_scan_forward(temp_move2); game->move_buffer[move_count++] = create_move(to-16,to,DOUBLE_PAWN_PUSH_FLAG); temp_move2 &= temp_move2 - 1; } /* captures */ /* TODO: add en passante capture */ temp_piece = game->board[PAWNS][WHITE]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move = pawn_attacks[WHITE][from] & game->board[PIECES][BLACK]; while (temp_move) { to = bit_scan_forward(temp_move); if (to/8 == 7) { /* time for a promotion */ game->move_buffer[move_count++] = create_move(from,to,BISHOP_PROMO_CAPTURE_FLAG); game->move_buffer[move_count++] = create_move(from,to,KNIGHT_PROMO_CAPTURE_FLAG); game->move_buffer[move_count++] = create_move(from,to,ROOK_PROMO_CAPTURE_FLAG); game->move_buffer[move_count++] = create_move(from,to,QUEEN_PROMO_CAPTURE_FLAG); } else game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /*****************/ /* WHITE KNIGHTS */ /*****************/ temp_piece = game->board[KNIGHTS][WHITE]; while (temp_piece) { from = bit_scan_forward(temp_piece); /* quiets */ temp_move = knight_table[from] & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = knight_table[from] & game->board[PIECES][BLACK]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /*****************/ /* WHITE BISHOPS */ /*****************/ temp_piece = game->board[BISHOPS][WHITE]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move2 = get_bishop_attacks(game->board[OCCUPIED][1], from); /* quiets */ temp_move = temp_move2 & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = temp_move2 & game->board[PIECES][BLACK]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /***************/ /* WHITE ROOKS */ /***************/ temp_piece = game->board[ROOKS][WHITE]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move2 = get_rook_attacks(game->board[OCCUPIED][1], from); /* quiets */ temp_move = temp_move2 & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = temp_move2 & game->board[PIECES][BLACK]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /****************/ /* WHITE QUEENS */ /****************/ temp_piece = game->board[QUEENS][WHITE]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move2 = get_queen_attacks(game->board[OCCUPIED][1], from); /* quiets */ temp_move = temp_move2 & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = temp_move2 & game->board[PIECES][BLACK]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /**************/ /* WHITE KINGS */ /**************/ temp_piece = game->board[KINGS][WHITE]; from = bit_scan_forward(temp_piece); /* quiets */ temp_move = king_table[from] & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = king_table[from] & game->board[PIECES][BLACK]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } /* TODO: add castling moves here after writing is_attacked function */ } else { /* to_move == BLACK */ /***************/ /* BLACK PAWNS */ /***************/ temp_move = step_down(game->board[PAWNS][BLACK]) & free_squares; temp_move2 = temp_move; /* single pushes */ while (temp_move) { to = bit_scan_forward(temp_move); if (to/8 == 0) { /* time for a promotion */ game->move_buffer[move_count++] = create_move(to+8,to,BISHOP_PROMO_FLAG); game->move_buffer[move_count++] = create_move(to+8,to,KNIGHT_PROMO_FLAG); game->move_buffer[move_count++] = create_move(to+8,to,ROOK_PROMO_FLAG); game->move_buffer[move_count++] = create_move(to+8,to,QUEEN_PROMO_FLAG); } else game->move_buffer[move_count++] = create_move(to+8,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* double pushes */ temp_move2 = step_down(temp_move2) & free_squares & rank5; while (temp_move2) { to = bit_scan_forward(temp_move2); game->move_buffer[move_count++] = create_move(to+16,to,DOUBLE_PAWN_PUSH_FLAG); temp_move2 &= temp_move2 - 1; } /* captures */ /* TODO: add en passante capture */ temp_piece = game->board[PAWNS][BLACK]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move = pawn_attacks[BLACK][from] & game->board[PIECES][WHITE]; while (temp_move) { to = bit_scan_forward(temp_move); if (to/8 == 7) { /* time for a promotion */ game->move_buffer[move_count++] = create_move(from,to,BISHOP_PROMO_CAPTURE_FLAG); game->move_buffer[move_count++] = create_move(from,to,KNIGHT_PROMO_CAPTURE_FLAG); game->move_buffer[move_count++] = create_move(from,to,ROOK_PROMO_CAPTURE_FLAG); game->move_buffer[move_count++] = create_move(from,to,QUEEN_PROMO_CAPTURE_FLAG); } else game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /*****************/ /* BLACK KNIGHTS */ /*****************/ temp_piece = game->board[KNIGHTS][BLACK]; while (temp_piece) { from = bit_scan_forward(temp_piece); /* quiets */ temp_move = knight_table[from] & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = knight_table[from] & game->board[PIECES][WHITE]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /*****************/ /* BLACK BISHOPS */ /*****************/ temp_piece = game->board[BISHOPS][BLACK]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move2 = get_bishop_attacks(game->board[OCCUPIED][1], from); /* quiets */ temp_move = temp_move2 & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = temp_move2 & game->board[PIECES][WHITE]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /***************/ /* BLACK ROOKS */ /***************/ temp_piece = game->board[ROOKS][BLACK]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move2 = get_rook_attacks(game->board[OCCUPIED][1], from); /* quiets */ temp_move = temp_move2 & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = temp_move2 & game->board[PIECES][WHITE]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /****************/ /* BLACK QUEENS */ /****************/ temp_piece = game->board[QUEENS][BLACK]; while (temp_piece) { from = bit_scan_forward(temp_piece); temp_move2 = get_queen_attacks(game->board[OCCUPIED][1], from); /* quiets */ temp_move = temp_move2 & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = temp_move2 & game->board[PIECES][WHITE]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } temp_piece &= temp_piece - 1; } /**************/ /* BLACK KINGS */ /**************/ temp_piece = game->board[KINGS][BLACK]; from = bit_scan_forward(temp_piece); /* quiets */ temp_move = king_table[from] & free_squares; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,QUIET_FLAG); temp_move &= temp_move - 1; } /* captures */ temp_move = king_table[from] & game->board[PIECES][WHITE]; while (temp_move) { to = bit_scan_forward(temp_move); game->move_buffer[move_count++] = create_move(from,to,CAPTURE_FLAG); temp_move &= temp_move - 1; } } return move_count; }