From e07a195bdd87932b9d00d3d680a9a5a747359566 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 9 Jul 2025 15:50:50 +0200 Subject: initial commit --- gen_piece_move_tables.py | 285 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 gen_piece_move_tables.py (limited to 'gen_piece_move_tables.py') diff --git a/gen_piece_move_tables.py b/gen_piece_move_tables.py new file mode 100644 index 0000000..a0efbf7 --- /dev/null +++ b/gen_piece_move_tables.py @@ -0,0 +1,285 @@ +import typing + +def int_to_hexstr(bm: int) -> str: + if bm > 0xFFFF_FFFF_FFFF_FFFF: + return False + return '0x' + '_'.join(f'{bm:016X}'[i : i + 4] for i in range(0, 16, 4)) + +def fill_bm(bm: int, bits: int) -> int: + filled_bm = 0 + for idx in range(64): + if bm & 1 << idx: + if bits & 1: + filled_bm |= 1 << idx + bits >>= 1 + return filled_bm + +def count_ones(bm: int) -> int: + ctr = 0 + for idx in range(64): + ctr += bm >> idx & 1 + return ctr + +def all_bit_combs(bm: int): + for bit_comb in range(2**count_ones(bm)): + yield fill_bm(bm, bit_comb) + +def n_mvs_mask(idx: int) -> int: + bm = 0 + for dir in (-6, -10, -17, -15, 6, 10, 17, 15): + new_idx = idx + dir + if abs(new_idx%8 - idx%8) < 3 and new_idx in range(64): + bm |= 1 << new_idx + return bm + +def k_mvs_mask(idx: int) -> int: + bm = 0 + for dir in (1, -1, -7, -8, -9, 7, 8, 9): + new_idx = idx + dir + if abs(new_idx%8 - idx%8) < 2 and new_idx in range(64): + bm |= 1 << new_idx + return bm + +def wp_double_push_mask(idx: int) -> int: + if idx // 8 == 6: + return 1 << (idx - 16) + return 0 + +def wp_push_mask(idx: int) -> int: + if not idx // 8 == 0: + return 1 << (idx - 8) + return 0 + +def wp_left_take_mask(idx: int) -> int: + if not idx // 8 == 0 and not idx % 8 == 0: + return 1 << (idx - 9) + return 0 + +def wp_right_take_mask(idx: int) -> int: + if not idx // 8 == 0 and not idx % 8 == 7: + return 1 << (idx - 7) + return 0 + +def bp_double_push_mask(idx: int) -> int: + if idx // 8 == 1: + return 1 << (idx + 16) + return 0 + +def bp_push_mask(idx: int) -> int: + if not idx // 8 == 7: + return 1 << (idx + 8) + return 0 + +def bp_left_take_mask(idx: int) -> int: + if not idx // 8 == 7 and not idx % 8 == 0: + return 1 << (idx + 7) + return 0 + +def bp_right_take_mask(idx: int) -> int: + if not idx // 8 == 7 and not idx % 8 == 7: + return 1 << (idx + 9) + return 0 + +def l_border_slide(idx: int) -> int: + slide_bm = 0 + if idx % 8 == 7: + return slide_bm + while True: + idx += 1 + slide_bm |= 1 << idx + if idx % 8 == 7: + return slide_bm + +def l_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx % 8 == 7: + return slide_bm + while True: + idx += 1 + slide_bm |= 1 << idx + if idx % 8 == 7 or bm & 1 << idx: + return slide_bm + +def r_border_slide(idx: int) -> int: + slide_bm = 0 + if idx % 8 == 0: + return slide_bm + while True: + idx -= 1 + slide_bm |= 1 << idx + if idx % 8 == 0: + return slide_bm + +def r_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx % 8 == 0: + return slide_bm + while True: + idx -= 1 + slide_bm |= 1 << idx + if idx % 8 == 0 or bm & 1 << idx: + return slide_bm + +def u_border_slide(idx: int) -> int: + slide_bm = 0 + if idx // 8 == 7: + return slide_bm + while True: + idx += 8 + slide_bm |= 1 << idx + if idx // 8 == 7: + return slide_bm + +def u_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx // 8 == 7: + return slide_bm + while True: + idx += 8 + slide_bm |= 1 << idx + if idx // 8 == 7 or bm & 1 << idx: + return slide_bm + +def d_border_slide(idx: int) -> int: + slide_bm = 0 + if idx // 8 == 0: + return slide_bm + while True: + idx -= 8 + slide_bm |= 1 << idx + if idx // 8 == 0: + return slide_bm + +def d_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx // 8 == 0: + return slide_bm + while True: + idx -= 8 + slide_bm |= 1 << idx + if idx // 8 == 0 or bm & 1 << idx: + return slide_bm + +def lu_border_slide(idx: int) -> int: + slide_bm = 0 + if idx % 8 == 7 or idx // 8 == 7: + return slide_bm + while True: + idx += 9 + slide_bm |= 1 << idx + if idx % 8 == 7 or idx // 8 == 7: + return slide_bm + +def lu_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx % 8 == 7 or idx // 8 == 7: + return slide_bm + while True: + idx += 9 + slide_bm |= 1 << idx + if idx % 8 == 7 or idx // 8 == 7 or bm & 1 << idx: + return slide_bm + +def ld_border_slide(idx: int) -> int: + slide_bm = 0 + if idx % 8 == 7 or idx // 8 == 0: + return slide_bm + while True: + idx -= 7 + slide_bm |= 1 << idx + if idx % 8 == 7 or idx // 8 == 0: + return slide_bm + +def ld_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx % 8 == 7 or idx // 8 == 0: + return slide_bm + while True: + idx -= 7 + slide_bm |= 1 << idx + if idx % 8 == 7 or idx // 8 == 0 or bm & 1 << idx: + return slide_bm + +def ru_border_slide(idx: int) -> int: + slide_bm = 0 + if idx % 8 == 0 or idx // 8 == 7: + return slide_bm + while True: + idx += 7 + slide_bm |= 1 << idx + if idx % 8 == 0 or idx // 8 == 7: + return slide_bm + +def ru_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx % 8 == 0 or idx // 8 == 7: + return slide_bm + while True: + idx += 7 + slide_bm |= 1 << idx + if idx % 8 == 0 or idx // 8 == 7 or bm & 1 << idx: + return slide_bm + +def rd_border_slide(idx: int) -> int: + slide_bm = 0 + if idx % 8 == 0 or idx // 8 == 0: + return slide_bm + while True: + idx -= 9 + slide_bm |= 1 << idx + if idx % 8 == 0 or idx // 8 == 0: + return slide_bm + +def rd_slide(bm: int, idx: int) -> int: + slide_bm = 0 + if idx % 8 == 0 or idx // 8 == 0: + return slide_bm + while True: + idx -= 9 + slide_bm |= 1 << idx + if idx % 8 == 0 or idx // 8 == 0 or bm & 1 << idx: + return slide_bm + +direction_sliding_func = { + 'L': l_slide, 'R': r_slide, 'U': u_slide, 'D': d_slide, + 'LU': lu_slide, 'LD': ld_slide, 'RU': ru_slide, 'RD': rd_slide, +} +direction_border_sliding_func = { + 'L': l_border_slide, 'R': r_border_slide, 'U': u_border_slide, 'D': d_border_slide, + 'LU': lu_border_slide, 'LD': ld_border_slide, 'RU': ru_border_slide, 'RD': rd_border_slide, +} + +def write_8x8_table(function: typing.Callable[[int], int], file_name: str = '8x8_table.py', tuple_name: str = 'TABLE', overwrite: bool = False) -> None: + f = open(file_name, 'w' if overwrite else 'a') + f.write(tuple_name + ' = (') + for idx in range(64): + if idx % 8 == 0: + f.write('\n ') + f.write(int_to_hexstr(function(idx)) + ', ') + f.write('\n)\n') + +def write_comb_dict(border_func: int, sliding_func: typing.Callable[[int, int], int], file_name: str = 'blocker_comb_table.py', tuple_name: str = 'BLOCKER_COMBS', overwrite: bool = False) -> None: + f = open(file_name, 'w' if overwrite else 'a') + f.write(tuple_name + ' = (') + for idx in range(64): + f.write('\n {') + for ctr, bit_comb in enumerate(all_bit_combs(border_func(idx))): + if ctr % 4 == 0: + f.write('\n ') + f.write(int_to_hexstr(bit_comb) + ': ' + int_to_hexstr(sliding_func(bit_comb, idx)) + ', ') + f.write('\n }, ') + f.write('\n)\n') + +def write_piece_move_tables(file_name: str = 'piece_move_tables.py', overwrite: bool = True) -> None: + if overwrite: + open(file_name, 'w') + func_dict = {'N': n_mvs_mask, 'K': k_mvs_mask, 'WP_DOUBLE_PUSH': wp_double_push_mask, 'WP_PUSH': wp_push_mask, 'WP_LEFT_TAKE': wp_left_take_mask, 'WP_RIGHT_TAKE': wp_right_take_mask, 'BP_DOUBLE_PUSH': bp_double_push_mask, 'BP_PUSH': bp_push_mask, 'BP_LEFT_TAKE': bp_left_take_mask, 'BP_RIGHT_TAKE': bp_right_take_mask} + for piece, func in func_dict.items(): + write_8x8_table(func, file_name, piece + '_MASK') + for direction in ('L', 'R', 'U', 'D', 'LU', 'LD', 'RU', 'RD'): + write_8x8_table(direction_border_sliding_func[direction], file_name, direction + '_BORDER_MASK') + for direction in ('L', 'R', 'U', 'D', 'LU', 'LD', 'RU', 'RD'): + write_comb_dict(direction_border_sliding_func[direction], direction_sliding_func[direction], file_name, direction + '_MASK') + +if __name__ == '__main__': + write_piece_move_tables() \ No newline at end of file -- cgit v1.2.3