inline U64 compute_hash(struct chess_state *state) { U64 h = 0; U64 tmp = state->all; tmp &= tmp-1; tmp &= tmp-1; tmp &= tmp-1; // use perfect hashing, when there are less than 4 figures on the field if (tmp==0) { int idx; tmp = state->all ^ state->bKing ^ state->bking; h = bitScanForward(tmp); h <<= 6; h|= bitScanForward(state->bKing); h <<= 6; h|= bitScanForward(state->bking); h <<= 1; h|= WTM; } else { h^=compute_piece(state->bQueen, Queen); h^=compute_piece(state->bBishop, Bishop); h^=compute_piece(state->bRook, Rook); h^=compute_piece(state->bPawn, Pawn); h^=compute_piece(state->bKnight, Knight); h^=compute_piece(state->bqueen, queen); h^=compute_piece(state->bbishop, bishop); h^=compute_piece(state->brook, rook); h^=compute_piece(state->bpawn, pawn); h^=compute_piece(state->bknight, knight); h^=zobrist[king-2][bitScanForward(state->bking)]; h^=zobrist[King-2][bitScanForward(state->bKing)]; // h^=compute_piece(state->bKing, King); h^=state->benpas | state->benpas>>24; h^=state->cas<<1 | WTM; } state->key = h; return h; }
void VCTrie64::insert(uint64_t id, uint64_t value){ uint8_t splitPos; uint8_t splitBit; uint64_t* prev; if (size+2 > capacity){ capacity += NEXT_SIZE; nodes = (Node*) realloc(nodes, sizeof(Node)*capacity); queue = (QNode*) realloc(queue, sizeof(QNode)*capacity*2); } uint64_t newNodePos = size; nodes[size++] = Node(id,value); if (newNodePos == 0) return; // It is the root Node* node = &(nodes[rootPos]); prev = &rootPos; splitPos = bitScanForward(value ^ node->value); while(!node->isLeaf && splitPos >= node->splitPos){ splitBit = testBit(value, node->splitPos); prev = &(node->childPos[splitBit]); node = &(nodes[node->childPos[splitBit]]); splitPos = bitScanForward(value ^ node->value); } if (node->isLeaf && node->value == value) // we found a duplicate node->next = newNodePos; else{ if (testBit(value, splitPos)) nodes[size] = Node(splitPos, value, *prev, newNodePos); // There is a 1, newNode is rightChild else nodes[size] = Node(splitPos, node->value, newNodePos, *prev); // There is a 0, newNode is leftChild *prev = size; // The previous reference is now the new tree node size++; } }
static inline U64 compute_piece(U64 positions, enum piece_t piece) { U64 pos; int idx; U64 ret=0; piece-=2; //adjust smallest piece to 0 coordinate //piece=0; while (positions) { pos=positions&(0-positions); idx = bitScanForward(pos); ret^=zobrist[piece][idx]; positions^=pos; } return ret; }
int gen_king_moves(move_t mv[]) { BITBOARD bb_king_dst = 0; BITBOARD bb_castle_kingside = 0; BITBOARD bb_castle_queenside = 0; bool can_castle_kingside = true; bool can_castle_queenside = true; int dst_castle_kingside = 0; int dst_castle_queenside = 0; move_t m; unsigned long src_idx = -1; unsigned long dst_idx = -1; int mv_idx = 0; // There are no legal king moves to make if the king // isn't on the board //assert((bb_white_king > 0) && (bb_black_king > 0)); if ((bb_white_king == 0) || (bb_black_king == 0)) { return 0; } if (white_to_move) { // get the square that the king is on src_idx = bitScanForward(bb_white_king); // for moves, any square that's not a white piece bb_king_dst = bb_legal_king_moves[src_idx] & (~bb_white_pieces); bb_castle_kingside = bb_white_castle_kingside; bb_castle_queenside = bb_white_castle_queenside; can_castle_kingside = white_can_castle_kingside; can_castle_queenside = white_can_castle_queenside; dst_castle_kingside = DST_WHITE_KINGSIDE; dst_castle_queenside = DST_WHITE_QUEENSIDE; m.piece = WK; } else { // get the square that the king is on src_idx = bitScanForward(bb_black_king); // for moves, any square that's not a black piece bb_king_dst = bb_legal_king_moves[src_idx] & (~bb_black_pieces); bb_castle_kingside = bb_black_castle_kingside; bb_castle_queenside = bb_black_castle_queenside; can_castle_kingside = black_can_castle_kingside; can_castle_queenside = black_can_castle_queenside; dst_castle_kingside = DST_BLACK_KINGSIDE; dst_castle_queenside = DST_BLACK_QUEENSIDE; m.piece = BK; } m.white_to_move = white_to_move; m.ply = ply; m.move_no = move_no; m.epsquare = epsquare; m.src = src_idx; m.white_can_castle_kingside = white_can_castle_kingside; m.white_can_castle_queenside = white_can_castle_queenside; m.black_can_castle_kingside = black_can_castle_kingside; m.black_can_castle_queenside = black_can_castle_queenside; while (bb_king_dst > 0) { //m.src = src_idx; dst_idx = bitScanForward(bb_king_dst); m.dst = dst_idx; m.capture = chessboard[dst_idx]; // is there a better way to handle if it's a capture? bb_king_dst = bb_king_dst & (~bb_squares[dst_idx]); mv[mv_idx++] = m; } if (can_castle_kingside) { if (!(bb_castle_kingside & bb_all_pieces)) { m.dst = dst_castle_kingside; m.capture = 0; mv[mv_idx++] = m; } } if (can_castle_queenside) { if (!(bb_castle_queenside & bb_all_pieces)) { m.dst = dst_castle_queenside; m.capture = 0; mv[mv_idx++] = m; } } // if white_to_move then black made the last move if (white_to_move) { black_can_castle_kingside = false; black_can_castle_queenside = false; } else { white_can_castle_kingside = false; white_can_castle_queenside = false; } return mv_idx; }