import piece_move_tables import typing bb = { 'P': 0x00FF_0000_0000_0000, 'R': 0x8100_0000_0000_0000, 'N': 0x4200_0000_0000_0000, 'B': 0x2400_0000_0000_0000, 'Q': 0x0800_0000_0008_0000, 'K': 0x1000_0000_0000_0000, 'p': 0x0000_0000_0000_FF00, 'r': 0x0000_0000_0000_0081, 'n': 0x0000_0000_0000_0042, 'b': 0x0000_0000_0000_0024, 'q': 0x0000_0000_0000_0008, 'k': 0x0000_0000_0000_0010, 'ep': 0x0000_0000_0000_0000, } def render_hex(hex_val: int) -> None: if not isinstance(hex_val, int): raise ValueError('Input must be integer.') if hex_val > 0xFFFF_FFFF_FFFF_FFFF: raise ValueError('Input hexadecimal value is too large, must be 64 bits or less.') binary_value = bin(hex_val)[2:].zfill(64) print('\n', end = '') for i in range(0, 64, 8): print(*['\x1b[47m' + bit + '\x1b[0m' if bit == '1' else bit for bit in binary_value[i:i+8]]) def bit_not(bm: int) -> int: return bm ^ 0xFFFF_FFFF_FFFF_FFFF def get_bit(bm: int, idx: int) -> int: return bm & 1 << idx def set_bit(bm: int, idx: int) -> int: return bm | 1 << idx def rm_bit(bm: int, idx: int) -> int: return bm & bit_not(1 << idx) def switch_bit(bm: int, *idxs: int) -> int: for idx in idxs: bm ^= 1 << idx return bm def count_trailing_zeros(bm: int) -> int: return (bm & -bm).bit_length() - 1 def w_pcs() -> int: return bb['P'] | bb['R'] | bb['N'] | bb['B'] | bb['Q'] | bb['Q'] def b_pcs() -> int: return bb['p'] | bb['r'] | bb['n'] | bb['b'] | bb['q'] | bb['k'] def all_pcs() -> int: return w_pcs() ^ b_pcs() def R_mvs(idx: int) -> int: all_pieces = all_pcs() left = piece_move_tables.L_MASK[idx][all_pieces & piece_move_tables.L_BORDER_MASK[idx]] right = piece_move_tables.R_MASK[idx][all_pieces & piece_move_tables.R_BORDER_MASK[idx]] up = piece_move_tables.U_MASK[idx][all_pieces & piece_move_tables.U_BORDER_MASK[idx]] down = piece_move_tables.D_MASK[idx][all_pieces & piece_move_tables.D_BORDER_MASK[idx]] return (left | right | up | down) & bit_not(w_pcs()) def N_mvs(idx) -> int: return piece_move_tables.N_MASK[idx] & bit_not(w_pcs()) def B_mvs(idx: int) -> int: all_pieces = all_pcs() left_up = piece_move_tables.LU_MASK[idx][all_pieces & piece_move_tables.LU_BORDER_MASK[idx]] left_down = piece_move_tables.LD_MASK[idx][all_pieces & piece_move_tables.LD_BORDER_MASK[idx]] right_up = piece_move_tables.RU_MASK[idx][all_pieces & piece_move_tables.RU_BORDER_MASK[idx]] right_down = piece_move_tables.RD_MASK[idx][all_pieces & piece_move_tables.RD_BORDER_MASK[idx]] return (left_up | left_down | right_up | right_down) & bit_not(w_pcs()) def Q_mvs(idx: int) -> int: return R_mvs(idx) | B_mvs(idx) def K_mvs(idx: int) -> int: return piece_move_tables.K_MASK[idx] & bit_not(w_pcs()) def P_mvs(idx: int) -> int: return piece_move_tables.WP_PUSH_MASK[idx] & bit_not(all_pcs()) | piece_move_tables.WP_LEFT_TAKE_MASK[idx] | piece_move_tables.WP_RIGHT_TAKE_MASK[idx] & b_pcs() def r_mvs(idx: int) -> int: all_pieces = all_pcs() left = piece_move_tables.L_MASK[idx][all_pieces & piece_move_tables.L_BORDER_MASK[idx]] right = piece_move_tables.R_MASK[idx][all_pieces & piece_move_tables.R_BORDER_MASK[idx]] up = piece_move_tables.U_MASK[idx][all_pieces & piece_move_tables.U_BORDER_MASK[idx]] down = piece_move_tables.D_MASK[idx][all_pieces & piece_move_tables.D_BORDER_MASK[idx]] return (left | right | up | down) & bit_not(b_pcs()) def n_mvs(idx: int) -> int: return piece_move_tables.N_MASK[idx] & bit_not(b_pcs()) def b_mvs(idx: int) -> int: all_pieces = all_pcs() left_up = piece_move_tables.LU_MASK[idx][all_pieces & piece_move_tables.LU_BORDER_MASK[idx]] left_down = piece_move_tables.LD_MASK[idx][all_pieces & piece_move_tables.LD_BORDER_MASK[idx]] right_up = piece_move_tables.RU_MASK[idx][all_pieces & piece_move_tables.RU_BORDER_MASK[idx]] right_down = piece_move_tables.RD_MASK[idx][all_pieces & piece_move_tables.RD_BORDER_MASK[idx]] return (left_up | left_down | right_up | right_down) & bit_not(b_pcs()) def q_mvs(idx: int) -> int: return r_mvs(idx) | b_mvs(idx) def k_mvs(idx: int) -> int: return piece_move_tables.K_MASK[idx] & bit_not(b_pcs()) def p_mvs(idx) -> int: return piece_move_tables.BP_PUSH_MASK[idx] & bit_not(all_pcs()) | piece_move_tables.BP_LEFT_TAKE_MASK[idx] | piece_move_tables.BP_RIGHT_TAKE_MASK[idx] & w_pcs() def ver_mirr(bm: int) -> int: return (bm & 0x8080_8080_8080_8080) >> 7 | (bm & 0x4040_4040_4040_4040) >> 5 | (bm & 0x2020_2020_2020_2020) >> 3 | (bm & 0x1010_1010_1010_1010) >> 1 | (bm & 0x0808_0808_0808_0808) << 1 | (bm & 0x0404_0404_0404_0404) << 3 | (bm & 0x0202_0202_0202_0202) << 5 | (bm & 0x0101_0101_0101_0101) << 7 def hor_mirr(bm: int) -> int: return (bm & 0xFF00_0000_0000_0000) >> 56 | (bm & 0x00FF_0000_0000_0000) >> 40 | (bm & 0x0000_FF00_0000_0000) >> 24 | (bm & 0x0000_00FF_0000_0000) >> 8 | (bm & 0x0000_0000_FF00_0000) << 8 | (bm & 0x0000_0000_00FF_0000) << 24 | (bm & 0x0000_0000_0000_FF00) << 40 | (bm & 0x0000_0000_0000_00FF) << 56 def bits(bm: int) -> typing.Generator[int, int, None]: for idx in range(64): if bm & 1 << idx: yield 1 << idx render_hex(1 << 33) render_hex(R_mvs(33)) render_hex(1 << 44) render_hex(Q_mvs(44))