Spaces:
Sleeping
Sleeping
| """Bitboard utilities (square index: a1=0, h8=63).""" | |
| from __future__ import annotations | |
| RANK_1 = 0x00000000000000FF | |
| RANK_2 = 0x000000000000FF00 | |
| RANK_3 = 0x0000000000FF0000 | |
| RANK_4 = 0x00000000FF000000 | |
| RANK_5 = 0x000000FF00000000 | |
| RANK_6 = 0x0000FF0000000000 | |
| RANK_7 = 0x00FF000000000000 | |
| RANK_8 = 0xFF00000000000000 | |
| FILE_A = 0x0101010101010101 | |
| FILE_B = 0x0202020202020202 | |
| FILE_C = 0x0404040404040404 | |
| FILE_D = 0x0808080808080808 | |
| FILE_E = 0x1010101010101010 | |
| FILE_F = 0x2020202020202020 | |
| FILE_G = 0x4040404040404040 | |
| FILE_H = 0x8080808080808080 | |
| WHITE_SQUARES = 0x55AA55AA55AA55AA | |
| BLACK_SQUARES = 0xAA55AA55AA55AA55 | |
| LONG_DIAGONALS = 0x8142241818244281 | |
| CENTER_SQUARES = 0x0000001818000000 | |
| CENTER_BIG = 0x00003C3C3C3C0000 | |
| LEFT_FLANK = FILE_A | FILE_B | FILE_C | FILE_D | |
| RIGHT_FLANK = FILE_E | FILE_F | FILE_G | FILE_H | |
| FILES = [FILE_A, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H] | |
| RANKS = [RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8] | |
| MIRROR_FILE = (0, 1, 2, 3, 3, 2, 1, 0) | |
| def file_of(sq: int) -> int: | |
| return sq % 8 | |
| def rank_of(sq: int) -> int: | |
| return sq // 8 | |
| def square(rank: int, file: int) -> int: | |
| return rank * 8 + file | |
| def relative_rank_of(colour: int, sq: int) -> int: | |
| return rank_of(sq) if colour == 0 else 7 - rank_of(sq) | |
| def relative_square(colour: int, sq: int) -> int: | |
| return square(relative_rank_of(colour, sq), file_of(sq)) | |
| def relative_square32(colour: int, sq: int) -> int: | |
| return 4 * relative_rank_of(colour, sq) + MIRROR_FILE[file_of(sq)] | |
| def squares_of_matching_colour(sq: int) -> int: | |
| return WHITE_SQUARES if (WHITE_SQUARES >> sq) & 1 else BLACK_SQUARES | |
| def popcount(bb: int) -> int: | |
| return bb.bit_count() | |
| def getlsb(bb: int) -> int: | |
| return (bb & -bb).bit_length() - 1 | |
| def getmsb(bb: int) -> int: | |
| return bb.bit_length() - 1 | |
| def poplsb(bb: int) -> tuple[int, int]: | |
| sq = getlsb(bb) | |
| return sq, bb & (bb - 1) | |
| def several(bb: int) -> bool: | |
| return bb & (bb - 1) != 0 | |
| def only_one(bb: int) -> bool: | |
| return bb != 0 and not several(bb) | |
| def test_bit(bb: int, sq: int) -> bool: | |
| return (bb >> sq) & 1 != 0 | |
| def set_bit(bb: int, sq: int) -> int: | |
| return bb | (1 << sq) | |
| def backmost(colour: int, bb: int) -> int: | |
| return getlsb(bb) if colour == 0 else getmsb(bb) | |
| def frontmost(colour: int, bb: int) -> int: | |
| return getmsb(bb) if colour == 0 else getlsb(bb) | |