/* --------------------------------------------------------------------------------------- void generate_moves(CHESS_STATE *current_state) purpose: the search tree function - gets all child states for a given state. NOTE: this function simply gets all moves for an immediate chess state using bitboard maths etc. It _may_ include illegal moves (eg if king is left exposed. Such illegal moves are filtered out using iterative deepening function (see later in source), using flg_is_illegal flag on node. --------------------------------------------------------------------------------------- */ void generate_moves(CHESS_STATE *current_state) { bitboard pieces=0; // bitboard of pieces under investigation bitboard piece; // bitboard of single piece COLOR_ENUM color = (current_state->flg_is_white_move) ? BB_WHITE : BB_BLACK; COLOR_ENUM opponent_color = (current_state->flg_is_white_move) ? BB_BLACK : BB_WHITE; // calculated bitboards int i; // empty and opponents squares cached for performance bitboard empty_squares = EMPTY_BOARD; bitboard opponents_squares = EMPTY_BOARD; for (i=0; i< BB_COUNT; i++) { empty_squares |= current_state->boards[i]; } empty_squares = ~empty_squares; for (i=0; i<6; i++) { opponents_squares |= current_state->boards[opponent_color+i]; } // pawns pawn_moves(current_state,empty_squares); pawn_double_moves(current_state,empty_squares); en_passant_moves(current_state); pawn_capture_moves(current_state,empty_squares, opponents_squares); //knight fp_cached_move_mask knight_func = &cached_knight_move_mask; simple_move_mask_moves(current_state, BB_KNIGHT, knight_func, empty_squares, opponents_squares); //king fp_cached_move_mask king_func = &cached_king_move_mask; simple_move_mask_moves(current_state, BB_KING, king_func, empty_squares, opponents_squares); // rook fp_cached_sliding_move_mask rook_func = &cached_rook_move_mask; sliding_moves(current_state,empty_squares,opponents_squares,BB_ROOK,rook_func); // bishop fp_cached_sliding_move_mask bishop_func = &cached_bishop_move_mask; sliding_moves(current_state,empty_squares,opponents_squares,BB_BISHOP,bishop_func); // queen sliding_moves(current_state,empty_squares,opponents_squares,BB_QUEEN,rook_func); sliding_moves(current_state,empty_squares,opponents_squares,BB_QUEEN,bishop_func); }
void gen_moves(const board& b, piece_colour pc, move* movelist, int& num_moves) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { row_col rc(i, j); square s = b.get(rc); if (pc == get_piece_colour(s)) { piece_type pt = get_piece_type(s); switch (pt) { case NONE: assert(0); // only here if square contains one of our pieces break; case PAWN: pawn_moves(pc, rc, b, movelist, num_moves); break; case KNIGHT: knight_moves(pc, rc, b, movelist, num_moves); break; case BISHOP: bishop_moves(pc, rc, b, movelist, num_moves); break; case ROOK: rook_moves(pc, rc, b, movelist, num_moves); break; case KING: king_moves(pc, rc, b, movelist, num_moves); break; case QUEEN: queen_moves(pc, rc, b, movelist, num_moves); break; } } } } }
/* * return the non-eat (simple) moves. * curr = starting coordinate of the move * max_step = length of maximal possible step (1 for man, BOARD_SIZE for king) * in case of an error - return error_moves */ moves get_simple_moves(settings * set, cord curr){ char piece = board_piece(set->board, curr); int color = which_color(piece); int type = tolower(piece); moves all_simple_moves = { 0 }; switch (type) { case PAWN: return pawn_moves(set, curr, color); case BISHOP: return bishop_moves(set, curr, color, FALSE); case ROOK: return rook_moves(set, curr, color, FALSE); case KNIGHT: return knight_moves(set, curr, color); case QUEEN: return queen_moves(set, curr, color, FALSE); case KING: return king_moves(set, curr, color); default: return all_simple_moves; } }
/* return the set of all squares the given piece is able to move to, without * considering a king left in check */ uint64_t generate_moves(Game *game, int tile) { Board *board = &(game->board); int colour = !(board->b[WHITE][OCCUPIED] & (1ull << tile)); int type = board->mailbox[tile]; uint64_t moves = 0; uint64_t blockers; switch(type) { case PAWN: moves = pawn_moves(board, tile); int x = tile % 8, y = tile / 8; if((game->ep == x + 1 || game->ep == x - 1) && (y == 4 - colour)) moves |= 1ull << ((5 - colour * 3) * 8 + game->ep); break; case KNIGHT: moves = knight_moves[tile]; break; case BISHOP: moves = bishop_moves(board, tile); break; case ROOK: moves = rook_moves(board, tile); break; case QUEEN: moves = bishop_moves(board, tile) | rook_moves(board, tile); break; case KING: moves = king_moves[tile]; /* queenside castling */ if(game->can_castle[colour][QUEENSIDE]) { blockers = ((1ull << (tile - 1)) | (1ull << (tile - 2)) | (1ull << (tile - 3))) & board->occupied; /* if there are no pieces in the way and no intermediate tiles are * threatened, add the move */ if(!blockers && !is_threatened(board, tile) && !is_threatened(board, tile - 1) && !is_threatened(board, tile - 2)) moves |= 1ull << (tile - 2); } /* kingisde castling */ if(game->can_castle[colour][KINGSIDE]) { blockers = ((1ull << (tile + 1)) | (1ull << (tile + 2))) & board->occupied; /* if there are no pieces in the way and no intermediate tiles are * threatened, add the move */ if(!blockers && !is_threatened(board, tile) && !is_threatened(board, tile + 1) && !is_threatened(board, tile + 2)) moves |= 1ull << (tile + 2); } break; } /* return the moves, removing the final tile if it ended on our own * colour. */ return moves & ~board->b[colour][OCCUPIED]; }