module Chess::Bitboard

Extended Modules

Defined in:

chess/bitboard.cr

Constant Summary

A1_BB = 1_u64 << 0
A2_BB = 1_u64 << 8
A3_BB = 1_u64 << 16
A4_BB = 1_u64 << 24
A5_BB = 1_u64 << 32
A6_BB = 1_u64 << 40
A7_BB = 1_u64 << 48
A8_BB = 1_u64 << 56
B1_BB = 1_u64 << 1
B2_BB = 1_u64 << 9
B3_BB = 1_u64 << 17
B4_BB = 1_u64 << 25
B5_BB = 1_u64 << 33
B6_BB = 1_u64 << 41
B7_BB = 1_u64 << 49
B8_BB = 1_u64 << 57
BISHOP_ATTACKS = begin blocker_board = BISHOP_BLOCKER_MASK.each_with_object([] of Array(UInt64)) do |position, res| res << (bitboard_combinations(position)) end move_board = blocker_board.map_with_index do |boards, y| boards.map_with_index do |board, x| generate_sliding_moveboard(y, board, BISHOP_BLOCKER_MASK[y], [->south_east(UInt64), ->north_east(UInt64), ->south_west(UInt64), ->north_west(UInt64)]) end end bishop_attacks = Array(UInt64).new(64 * BISHOP_ROW_SIZE, 0) BISHOP_MAGIC_INDEX.each_with_index do |magic, idx| blocker_board[idx].each_with_index do |el, inner_idx| mult = (el.to_u64 &* magic.to_u64).to_u64 >> BISHOP_SHIFT bishop_attacks[(idx.to_u64 &* BISHOP_ROW_SIZE) + mult] = move_board[idx][inner_idx] end end bishop_attacks end
BISHOP_BLOCKER_MASK = [18049651735527936_u64, 70506452091904_u64, 275415828992_u64, 1075975168_u64, 38021120_u64, 8657588224_u64, 2216338399232_u64, 567382630219776_u64, 9024825867763712_u64, 18049651735527424_u64, 70506452221952_u64, 275449643008_u64, 9733406720_u64, 2216342585344_u64, 567382630203392_u64, 1134765260406784_u64, 4512412933816832_u64, 9024825867633664_u64, 18049651768822272_u64, 70515108615168_u64, 2491752130560_u64, 567383701868544_u64, 1134765256220672_u64, 2269530512441344_u64, 2256206450263040_u64, 4512412900526080_u64, 9024834391117824_u64, 18051867805491712_u64, 637888545440768_u64, 1135039602493440_u64, 2269529440784384_u64, 4539058881568768_u64, 1128098963916800_u64, 2256197927833600_u64, 4514594912477184_u64, 9592139778506752_u64, 19184279556981248_u64, 2339762086609920_u64, 4538784537380864_u64, 9077569074761728_u64, 562958610993152_u64, 1125917221986304_u64, 2814792987328512_u64, 5629586008178688_u64, 11259172008099840_u64, 22518341868716544_u64, 9007336962655232_u64, 18014673925310464_u64, 2216338399232_u64, 4432676798464_u64, 11064376819712_u64, 22137335185408_u64, 44272556441600_u64, 87995357200384_u64, 35253226045952_u64, 70506452091904_u64, 567382630219776_u64, 1134765260406784_u64, 2832480465846272_u64, 5667157807464448_u64, 11333774449049600_u64, 22526811443298304_u64, 9024825867763712_u64, 18049651735527936_u64] of UInt64
BISHOP_MAGIC_INDEX = [9079923922700290_u64, 149183129234965010_u64, 9226046195162613120_u64, 480762027793449984_u64, 1487811299508256_u64, 2307056880421339232_u64, 4629859304975893376_u64, 18142109648896_u64, 37387708162056_u64, 96869864921243713_u64, 43981002392608_u64, 72092918030565376_u64, 1154610632230731780_u64, 38338881694744588_u64, 4683748011057221640_u64, 4504858338010112_u64, 9038638440777760_u64, 9304439167180105744_u64, 2254621741556746_u64, 74384335439924480_u64, 9042392251373568_u64, 149709681332224_u64, 4707396873546137640_u64, 2317243846440003584_u64, 9516158858184163848_u64, 598753073693192_u64, 1154047679400054048_u64, 6918659325632188544_u64, 145135576883216_u64, 1153064475545568288_u64, 4755907863443145216_u64, 1154082726359597096_u64, 9605608762282016_u64, 9033589681554057_u64, 1297072427887494148_u64, 567352429379840_u64, 2543187579240480_u64, 4611768024385994768_u64, 324822956685430797_u64, 4983235255461741648_u64, 158331285045777_u64, 1201834996274496_u64, 1152959988059080832_u64, 5533051390283_u64, 35321881038864_u64, 307382220652315204_u64, 150941644596707456_u64, 147884382636288_u64, 36112366349321217_u64, 2342153428313088128_u64, 13909653597169190920_u64, 594756704174874632_u64, 1356225878480289792_u64, 13744444866630_u64, 315255568904388608_u64, 5012796656602614800_u64, 18693039906816_u64, 9511642004037042690_u64, 8865416610048_u64, 2449959306465380352_u64, 300617547333585985_u64, 3461106476012015748_u64, 9223936414889545920_u64, 1155490308574691330_u64] of UInt64
BISHOP_ROW_SIZE = 1 << MAX_BISHOP_BITS
BISHOP_SHIFT = 64 - MAX_BISHOP_BITS
BLACK_KING_CASTLE_BLOCK_BB = F8_BB | G8_BB
BLACK_PAWN_ATTACKS = Array(UInt64).new(64) do |i| black_pawns_attacks(1_u64 << i) end
BLACK_QUEEN_CASTLE_BLOCK_BB = (B8_BB | C8_BB) | D8_BB
BLACK_SQUARES = 12273903644374837845_u64
C1_BB = 1_u64 << 2
C2_BB = 1_u64 << 10
C3_BB = 1_u64 << 18
C4_BB = 1_u64 << 26
C5_BB = 1_u64 << 34
C6_BB = 1_u64 << 42
C7_BB = 1_u64 << 50
C8_BB = 1_u64 << 58
D1_BB = 1_u64 << 3
D2_BB = 1_u64 << 11
D3_BB = 1_u64 << 19
D4_BB = 1_u64 << 27
D5_BB = 1_u64 << 35
D6_BB = 1_u64 << 43
D7_BB = 1_u64 << 51
D8_BB = 1_u64 << 59
E1_BB = 1_u64 << 4
E2_BB = 1_u64 << 12
E3_BB = 1_u64 << 20
E4_BB = 1_u64 << 28
E5_BB = 1_u64 << 36
E6_BB = 1_u64 << 44
E7_BB = 1_u64 << 52
E8_BB = 1_u64 << 60
F1_BB = 1_u64 << 5
F2_BB = 1_u64 << 13
F3_BB = 1_u64 << 21
F4_BB = 1_u64 << 29
F5_BB = 1_u64 << 37
F6_BB = 1_u64 << 45
F7_BB = 1_u64 << 53
F8_BB = 1_u64 << 61
FILE_A_BB = 72340172838076673_u64
FILE_B_BB = 144680345676153346_u64
FILE_C_BB = 289360691352306692_u64
FILE_D_BB = 578721382704613384_u64
FILE_E_BB = 1157442765409226768_u64
FILE_F_BB = 2314885530818453536_u64
FILE_G_BB = 4629771061636907072_u64
FILE_H_BB = 9259542123273814144_u64
FILES = Array[FILE_A_BB, FILE_B_BB, FILE_C_BB, FILE_D_BB, FILE_E_BB, FILE_F_BB, FILE_G_BB, FILE_H_BB]
G1_BB = 1_u64 << 6
G2_BB = 1_u64 << 14
G3_BB = 1_u64 << 22
G4_BB = 1_u64 << 30
G5_BB = 1_u64 << 38
G6_BB = 1_u64 << 46
G7_BB = 1_u64 << 54
G8_BB = 1_u64 << 62
H1_BB = 1_u64 << 7
H2_BB = 1_u64 << 15
H3_BB = 1_u64 << 23
H4_BB = 1_u64 << 31
H5_BB = 1_u64 << 39
H6_BB = 1_u64 << 47
H7_BB = 1_u64 << 55
H8_BB = 1_u64 << 63
KING_ATTACKS = Array(UInt64).new(64) do |i| kings_attacks(1_u64 << i) end
KNIGHT_ATTACKS = Array(UInt64).new(64) do |i| knights_attacks(1_u64 << i) end
MAX_BISHOP_BITS = 9
MAX_ROOK_BITS = 12

Magic bitboards

PAWN_ATTACKS = BLACK_PAWN_ATTACKS + WHITE_PAWN_ATTACKS
PROMOTION_RANKS = RANK_1_BB | RANK_8_BB
RANK_1_BB = 255_u64
RANK_2_BB = 65280_u64
RANK_3_BB = 16711680_u64
RANK_4_BB = 4278190080_u64
RANK_5_BB = 1095216660480_u64
RANK_6_BB = 280375465082880_u64
RANK_7_BB = 71776119061217280_u64
RANK_8_BB = 18374686479671623680_u64
RANKS = Array[RANK_1_BB, RANK_2_BB, RANK_3_BB, RANK_4_BB, RANK_5_BB, RANK_6_BB, RANK_7_BB, RANK_8_BB]
ROOK_ATTACKS = begin blocker_board = ROOK_BLOCKER_MASK.each_with_object([] of Array(UInt64)) do |position, res| res << (bitboard_combinations(position)) end move_board = blocker_board.map_with_index do |boards, y| boards.map_with_index do |board, x| generate_sliding_moveboard(y, board, ROOK_BLOCKER_MASK[y], [->south(UInt64), ->north(UInt64), ->east(UInt64), ->west(UInt64)]) end end rook_attacks = Array(UInt64).new(64 * ROOK_ROW_SIZE, 0) ROOK_MAGIC_INDEX.each_with_index do |magic, idx| blocker_board[idx].each_with_index do |el, inner_idx| mult = (el.to_u64 &* magic.to_u64).to_u64 >> ROOK_SHIFT rook_attacks[(idx.to_u64 &* ROOK_ROW_SIZE) + mult] = move_board[idx][inner_idx] end end rook_attacks end
ROOK_BLOCKER_MASK = [282578800148862_u64, 565157600297596_u64, 1130315200595066_u64, 2260630401190006_u64, 4521260802379886_u64, 9042521604759646_u64, 18085043209519166_u64, 36170086419038334_u64, 282578800180736_u64, 565157600328704_u64, 1130315200625152_u64, 2260630401218048_u64, 4521260802403840_u64, 9042521604775424_u64, 18085043209518592_u64, 36170086419037696_u64, 282578808340736_u64, 565157608292864_u64, 1130315208328192_u64, 2260630408398848_u64, 4521260808540160_u64, 9042521608822784_u64, 18085043209388032_u64, 36170086418907136_u64, 282580897300736_u64, 565159647117824_u64, 1130317180306432_u64, 2260632246683648_u64, 4521262379438080_u64, 9042522644946944_u64, 18085043175964672_u64, 36170086385483776_u64, 283115671060736_u64, 565681586307584_u64, 1130822006735872_u64, 2261102847592448_u64, 4521664529305600_u64, 9042787892731904_u64, 18085034619584512_u64, 36170077829103616_u64, 420017753620736_u64, 699298018886144_u64, 1260057572672512_u64, 2381576680245248_u64, 4624614895390720_u64, 9110691325681664_u64, 18082844186263552_u64, 36167887395782656_u64, 35466950888980736_u64, 34905104758997504_u64, 34344362452452352_u64, 33222877839362048_u64, 30979908613181440_u64, 26493970160820224_u64, 17522093256097792_u64, 35607136465616896_u64, 9079539427579068672_u64, 8935706818303361536_u64, 8792156787827803136_u64, 8505056726876686336_u64, 7930856604974452736_u64, 6782456361169985536_u64, 4485655873561051136_u64, 9115426935197958144_u64] of UInt64
ROOK_MAGIC_INDEX = [72075465405235232_u64, 2323857820041084992_u64, 4683748149309784072_u64, 148645177324605440_u64, 36037661999301696_u64, 2450030765862552577_u64, 36046947555542018_u64, 144116294097059878_u64, 4622980213142794241_u64, 9230128278126764544_u64, 11818729687302014984_u64, 22553191937744900_u64, 40541197303283776_u64, 618682308299456516_u64, 3412971090888212_u64, 36169536126320896_u64, 1765411192441933830_u64, 18647854647085056_u64, 7574492104589313024_u64, 2310346644292632708_u64, 72066392431001792_u64, 11673683177443951266_u64, 155376936997391428_u64, 90076528167239692_u64, 9232383922992652305_u64, 288793672454537252_u64, 5418599863304448_u64, 2305895811609789440_u64, 9016021251784960_u64, 3377725507125453_u64, 282714209124353_u64, 9297694729015656512_u64, 4656794032713771008_u64, 4611694883777544224_u64, 1157988080093758464_u64, 1152925903224307736_u64, 9281937173836202496_u64, 1200946282758148_u64, 72059793868595296_u64, 450518432153076992_u64, 11529237174855958528_u64, 36275087762018320_u64, 23714404361183236_u64, 1310549724948860928_u64, 74336065615300736_u64, 9313444579426763776_u64, 1411807327703050_u64, 1158832479692423177_u64, 4630831818732536840_u64, 44289988116996_u64, 2359967848379973696_u64, 5633897631580224_u64, 1153802213437640736_u64, 2307252583456047488_u64, 9571248858763552_u64, 72066939892023840_u64, 13582286465306657_u64, 684828893424656657_u64, 576813008341700865_u64, 288800000486424578_u64, 9223389633336068097_u64, 108651557221832761_u64, 4683762442944648708_u64, 1407376536125971_u64] of UInt64
ROOK_ROW_SIZE = 1 << MAX_ROOK_BITS
ROOK_SHIFT = 64 - MAX_ROOK_BITS
SQUARE_BB = Array(UInt64).new(64) do |idx| 1_u64 << idx.to_u64 end
SQUARE_STRING = Array(String).new(64) do |square| ("" + ('a' + (file(square)))) + ('1' + (rank(square))) end
WHITE_KING_CASTLE_BLOCK_BB = F1_BB | G1_BB
WHITE_PAWN_ATTACKS = Array(UInt64).new(64) do |i| white_pawns_attacks(1_u64 << i) end
WHITE_QUEEN_CASTLE_BLOCK_BB = (B1_BB | C1_BB) | D1_BB
WHITE_SQUARES = 6172840429334713770_u64

Instance Method Summary

Instance Method Detail

def bishop_attacks(square : Number, occupancy) #

[View source]
def bishop_attacks(square : Square, occupancy) #

[View source]
def bitboard_combinations(bb) #

[View source]
def black_pawn_attacks(square : Number) #

[View source]
def black_pawn_attacks(square : Square) #

[View source]
def black_pawns_attacks(bb) #

[View source]
def black_pawns_moves(bb, uint64) #

[View source]
def east(bb) #

[View source]
def file(square : Number) #

[View source]
def file(square : Square) #

[View source]
def generate_sliding_moveboard(square, board, blocker, directions) #

[View source]
def king_attacks(square : Number) #

[View source]
def king_attacks(square : Square) #

[View source]
def kings_attacks(bb) #

[View source]
def knight_attacks(square : Number) #

[View source]
def knight_attacks(square : Square) #

[View source]
def knights_attacks(bb) #

[View source]
def more_than_one?(bb) #

[View source]
def north(bb) #

[View source]
def north_east(bb) #

[View source]
def north_west(bb) #

[View source]
def pawn_attacks(colour, square : Number) #

[View source]
def pawn_attacks(colour, square : Square) #

[View source]
def queen_attacks(square : Number, occupancy) #

[View source]
def rank(square : Number) #

[View source]
def rank(square : Square) #

[View source]
def rook_attacks(square : Number, occupancy) #

[View source]
def rook_attacks(square : Square, occupancy) #

[View source]
def south(bb) #

[View source]
def south_east(bb) #

[View source]
def south_west(bb) #

[View source]
def square_bb(square : Number) #

[View source]
def square_bb(square : Square) #

[View source]
def square_string(square : Number) #

[View source]
def square_string(square : Square) #

[View source]
def west(bb) #

[View source]
def white_pawn_attacks(square : Number) #

[View source]
def white_pawn_attacks(square : Square) #

[View source]
def white_pawns_attacks(bb) #

[View source]
def white_pawns_moves(bb, occupancy) #

[View source]