#include "../search.h" #include #include #include bitboard_t get_white_pawn_forwardmoves(moves_t* moves, position_t position) { bitboard_t enemy_bitboard = blacks(position); bitboard_t friendly_pieces = position.bitboards[WHITE_KING] | position.bitboards[WHITE_QUEEN] | position.bitboards[WHITE_ROOK] | position.bitboards[WHITE_BISHOP] | position.bitboards[WHITE_KNIGHT] | position.bitboards[WHITE_PAWN]; bitboard_t friendly_pawns = position.bitboards[WHITE_PAWN]; bitboard_t y = friendly_pieces | enemy_bitboard; bitboard_t x = ~((friendly_pawns << 8) & y) & (friendly_pawns << 8); bitboard_t first_move_x = x & BITMASK_RANK_C; first_move_x |= (first_move_x << 8) & (~y); x |= first_move_x; return x; } bitboard_t get_black_pawn_forwardmoves(moves_t* moves, position_t position) { bitboard_t enemy_bitboard = whites(position); bitboard_t friendly_pieces = position.bitboards[BLACK_KING] | position.bitboards[BLACK_QUEEN] | position.bitboards[BLACK_ROOK] | position.bitboards[BLACK_BISHOP] | position.bitboards[BLACK_KNIGHT] | position.bitboards[BLACK_PAWN]; bitboard_t friendly_pawns = position.bitboards[BLACK_PAWN]; bitboard_t y = friendly_pieces | enemy_bitboard; bitboard_t x = ~((friendly_pawns << 8) & y) & (friendly_pawns << 8); bitboard_t first_move_x = x | BITMASK_RANK_F; first_move_x |= (first_move_x >> 8) & (~y); x |= first_move_x; return x; } void get_pawn_moves(moves_t* moves, position_t position) { assert_valid_position(position); bitboard_t forward_moves; bitboard_t friendly_pawns; if (position.turn == WHITE_TURN) { forward_moves = get_white_pawn_forwardmoves(moves, position); friendly_pawns = position.bitboards[WHITE_PAWN]; } else { forward_moves = get_black_pawn_forwardmoves(moves, position); friendly_pawns = position.bitboards[BLACK_PAWN]; } bitboard_t column_masks[8] = { BITMASK_COLM_1, BITMASK_COLM_2, BITMASK_COLM_3, BITMASK_COLM_4, BITMASK_COLM_5, BITMASK_COLM_6, BITMASK_COLM_7, BITMASK_COLM_8, }; for (int i = 0; i < 8; i++) { bitboard_t item = column_masks[i] & forward_moves; bitboard_t pawns = column_masks[i] & friendly_pawns; int from = __builtin_ctzll(pawns); pawns &= (pawns - 1); int next_from = __builtin_ctzll(pawns); while (item) { int to = __builtin_ctzll(item); if (to > next_from) { from = next_from; pawns &= (pawns - 1); next_from = __builtin_ctzll(pawns); } item &= (item - 1); add_move(moves, from, to); } } if (position.passantable_column != 0) { bitboard_t PASSANT_RANK; int rank_shift; int from_shift; if (position.turn == WHITE_TURN) { PASSANT_RANK = BITMASK_RANK_E; rank_shift = 40; from_shift = -9; } else { PASSANT_RANK = BITMASK_RANK_D; from_shift = 7; rank_shift = 16; } int left = 0, right = 0; if (position.passantable_column > 1) left = position.passantable_column - 1; if (position.passantable_column < 8) right = position.passantable_column + 1; if (left != 0) { bitboard_t MASK = column_masks[left - 1] & friendly_pawns & PASSANT_RANK; if (MASK != 0) { add_move( moves, left + rank_shift + from_shift, position.passantable_column + rank_shift - 1 ); } } if (right != 0) { bitboard_t MASK = column_masks[right - 1] & friendly_pawns & PASSANT_RANK; if (MASK != 0) { add_move( moves, right + rank_shift + from_shift, position.passantable_column + rank_shift - 1 ); } } } }