summaryrefslogtreecommitdiff
path: root/BitB.py
blob: 5bba19983dde604cd121a30f9487423ad12ab97f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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))