1 2from functools import reduce 3from operator import or_ 4from pychess.Utils.const import WHITE, BLACK, KING, PAWN, EMPTY, KNIGHT, ROOK, BISHOP, QUEEN, \ 5 A1, A2, A3, A4, A5, A6, A7, A8, \ 6 B2, C3, D4, E5, F6, G7, H8,\ 7 B7, C6, D5, E4, F3, G2, H1, \ 8 B1, B8, H2, H7, G3, G6, B3, B6, sliders 9 10from .bitboard import bitPosArray, iterBits, setBit 11 12 13def RANK(cord): 14 return cord >> 3 15 16 17def FILE(cord): 18 return cord & 7 19 20 21# Evaluating constants 22 23PAWN_VALUE = 100 24KNIGHT_VALUE = 300 25BISHOP_VALUE = 330 26ROOK_VALUE = 500 27QUEEN_VALUE = 900 28KING_VALUE = 2000 29PIECE_VALUES = [0, PAWN_VALUE, KNIGHT_VALUE, BISHOP_VALUE, ROOK_VALUE, 30 QUEEN_VALUE, KING_VALUE] 31 32ASEAN_PIECE_VALUES = (0, 100, 450, 300, 630, 180, 2000) 33CRAZY_PIECE_VALUES = (0, 100, 200, 240, 240, 380, 2000) 34ATOMIC_PIECE_VALUES = (0, 100, 90, 0, 220, 850, 2000) 35 36# Maximum possible search depth. The hash structure only allows 8-bit depths. 37MAXPLY = 10 38# Maximum possible score. Mate in n ply is +/- (MATE_VALUE-n). 39# The hash structure only allows signed 16-bit scores. 40MATE_VALUE = MAXVAL = 32767 41MATE_DEPTH = 255 42 43 44def VALUE_AT_PLY(val, ply): 45 """ Return the value of scoring val a given number of plies into the future. """ 46 if val >= +32512: 47 return val - ply 48 if val <= -32512: 49 return val + ply 50 return val 51 52 53# How many points does it give to have the piece standing i cords from the 54# opponent king 55pawnTScale = [0, 40, 20, 12, 9, 6, 4, 2, 1, 0] 56bishopTScale = [0, 50, 25, 15, 7, 5, 3, 2, 2, 1] 57knightTScale = [0, 100, 50, 35, 10, 3, 2, 2, 1, 1] 58rookTScale = [0, 50, 40, 15, 5, 2, 1, 1, 1, 0] 59queenTScale = [0, 100, 60, 20, 10, 7, 5, 4, 3, 2] 60 61passedScores = ((0, 48, 48, 120, 144, 192, 240, 0), 62 (0, 240, 192, 144, 120, 48, 48, 0)) 63 64# Penalties for one or more isolated pawns on a given file 65isolani_normal = (-8, -10, -12, -14, -14, -12, -10, -8) 66# Penalties if the file is half-open (i.e. no enemy pawns on it) 67isolani_weaker = (-22, -24, -26, -28, -28, -26, -24, -22) 68 69# Distance boards for different pieces 70 71taxicab = [[0] * 64 for i in range(64)] 72sdistance = [[0] * 64 for i in range(64)] 73for fcord in range(64): 74 for tcord in range(fcord + 1, 64): 75 fx = FILE(fcord) 76 fy = RANK(fcord) 77 tx = FILE(tcord) 78 ty = RANK(tcord) 79 taxicab[fcord][tcord] = taxicab[fcord][tcord] = abs(fx - tx) + abs(fy - 80 ty) 81 sdistance[fcord][tcord] = sdistance[fcord][tcord] = min( 82 abs(fx - tx), abs(fy - ty)) 83 84distance = [[[0] * 64 for i in range(64)] for j in range(KING + 1)] 85 86distance[EMPTY] = None 87distance[KING] = sdistance 88distance[PAWN] = sdistance 89 90# Special table for knightdistances 91 92knightDistance = [ 93 6, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 94 5, 4, 5, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 5, 95 4, 5, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 96 5, 4, 3, 4, 3, 2, 3, 2, 3, 2, 3, 4, 3, 4, 5, 97 4, 3, 4, 3, 2, 3, 2, 3, 2, 3, 2, 3, 4, 3, 4, 98 5, 4, 3, 2, 3, 4, 1, 2, 1, 4, 3, 2, 3, 4, 5, 99 4, 3, 4, 3, 2, 1, 2, 3, 2, 1, 2, 3, 4, 3, 4, 100 5, 4, 3, 2, 3, 2, 3, 0, 3, 2, 3, 2, 3, 4, 5, 101 4, 3, 4, 3, 2, 1, 2, 3, 2, 1, 2, 3, 4, 3, 4, 102 5, 4, 3, 2, 3, 4, 1, 2, 1, 4, 3, 2, 3, 4, 5, 103 4, 3, 4, 3, 2, 3, 2, 3, 2, 3, 2, 3, 4, 3, 4, 104 5, 4, 3, 4, 3, 2, 3, 2, 3, 2, 3, 4, 3, 4, 5, 105 4, 5, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 106 5, 4, 5, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 5, 107 6, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 108] 109 110# Calculate 111 112for fcord in range(64): 113 frank = RANK(fcord) 114 ffile = FILE(fcord) 115 116 for tcord in range(fcord + 1, 64): 117 # Notice, that we skip fcord == tcord, as all fields are zero from 118 # scratch in anyway 119 120 trank = RANK(tcord) 121 tfile = FILE(tcord) 122 123 # Knight 124 field = (7 - frank + trank) * 15 + 7 - ffile + tfile 125 distance[KNIGHT][tcord][fcord] = distance[KNIGHT][fcord][tcord] = \ 126 knightDistance[field] 127 128 # Rook 129 if frank == trank or ffile == tfile: 130 distance[ROOK][tcord][fcord] = distance[ROOK][fcord][tcord] = 1 131 else: 132 distance[ROOK][tcord][fcord] = distance[ROOK][fcord][tcord] = 2 133 134 # Bishop 135 if abs(frank - trank) == abs(ffile - tfile): 136 distance[BISHOP][tcord][fcord] = distance[BISHOP][fcord][tcord] = 1 137 else: 138 distance[BISHOP][tcord][fcord] = distance[BISHOP][fcord][tcord] = 2 139 140 # Queen 141 if frank == trank or ffile == tfile or abs(frank - trank) == abs( 142 ffile - tfile): 143 distance[QUEEN][tcord][fcord] = distance[QUEEN][fcord][tcord] = 1 144 else: 145 distance[QUEEN][tcord][fcord] = distance[QUEEN][fcord][tcord] = 2 146 147# Special cases for knights in corners 148distance[KNIGHT][A1][B2] = distance[KNIGHT][B2][A1] = 4 149distance[KNIGHT][H1][G2] = distance[KNIGHT][G2][H1] = 4 150distance[KNIGHT][A8][B7] = distance[KNIGHT][B7][A8] = 4 151distance[KNIGHT][H8][G7] = distance[KNIGHT][G7][H8] = 4 152 153############################################################################### 154# Boards used for evaluating 155############################################################################### 156 157pawnScoreBoard = ( 158 (0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, -10, -10, 5, 5, 5, -2, -2, -2, 6, 6, 159 -2, -2, -2, 0, 0, 0, 25, 25, 0, 0, 0, 2, 2, 12, 16, 16, 12, 2, 2, 4, 8, 160 12, 16, 16, 12, 4, 4, 4, 8, 12, 16, 16, 12, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0), 161 (0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 12, 16, 16, 12, 4, 4, 4, 8, 12, 16, 16, 12, 162 4, 4, 2, 2, 12, 16, 16, 12, 2, 2, 0, 0, 0, 25, 25, 0, 0, 0, -2, -2, -2, 6, 163 6, -2, -2, -2, 5, 5, 5, -10, -10, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0)) 164 165outpost = ((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 167 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 168 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 169 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) 171 172normalKing = (24, 24, 24, 16, 16, 0, 32, 32, 24, 20, 16, 12, 12, 16, 20, 24, 173 16, 12, 8, 4, 4, 8, 12, 16, 12, 8, 4, 0, 0, 4, 8, 12, 12, 8, 4, 174 0, 0, 4, 8, 12, 16, 12, 8, 4, 4, 8, 12, 16, 24, 20, 16, 12, 12, 175 16, 20, 24, 24, 24, 24, 16, 16, 0, 32, 32) 176 177endingKing = (0, 6, 12, 18, 18, 12, 6, 0, 6, 12, 18, 24, 24, 18, 12, 6, 12, 18, 178 24, 32, 32, 24, 18, 12, 18, 24, 32, 48, 48, 32, 24, 18, 18, 24, 179 32, 48, 48, 32, 24, 18, 12, 18, 24, 32, 32, 24, 18, 12, 6, 12, 180 18, 24, 24, 18, 12, 6, 0, 6, 12, 18, 18, 12, 6, 0) 181 182racingKing = (0, 0, 0, 0, 0, 0, 0, 0, 183 500, 500, 500, 500, 500, 500, 500, 500, 184 950, 950, 950, 950, 950, 950, 950, 950, 185 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 186 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 187 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 188 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 189 14000, 14000, 14000, 14000, 14000, 14000, 14000, 14000) 190 191# Maps for bitboards 192 193d2e2 = (0x0018000000000000, 0x0000000000001800) 194brank7 = (0x000000000000FF00, 0x00FF000000000000) 195brank8 = (0x00000000000000FF, 0xFF00000000000000) 196brank67 = (0x0000000000FFFF00, 0x00FFFF0000000000) 197brank58 = (0x00000000FFFFFFFF, 0xFFFFFFFF00000000) 198brank48 = (0x000000FFFFFFFFFF, 0xFFFFFFFFFF000000) 199 200# Penalties if the file is half-open (i.e. no enemy pawns on it) 201isolani_weaker = (-22, -24, -26, -28, -28, -26, -24, -22) 202 203stonewall = [0, 0] 204# D4, E3, F4 205# - - - - - - - - 206# - - - - - - - - 207# - - - - - - - - 208# - - - - - - - - 209# - - - # - # - - 210# - - - - # - - - 211# - - - - - - - - 212# - - - - - - - - 213stonewall[WHITE] = 0x81400000000 214 215# D5, E6, F5 216# - - - - - - - - 217# - - - - - - - - 218# - - - - # - - - 219# - - - # - # - - 220# - - - - - - - - 221# - - - - - - - - 222# - - - - - - - - 223# - - - - - - - - 224stonewall[BLACK] = 0x81400000000 225 226# - - - - - - - - 227# - - - - - - - - 228# - - - - - - - - 229# - - - - - - - - 230# - - - - - - - - 231# - # - - - - # - 232# # # - - - - # # 233# - - - - - - - - 234qwingpawns1 = (bitPosArray[A2] | bitPosArray[B2], bitPosArray[A7] | 235 bitPosArray[B7]) 236qwingpawns2 = (bitPosArray[A2] | bitPosArray[B3], bitPosArray[A7] | 237 bitPosArray[B6]) 238kwingpawns1 = (bitPosArray[G2] | bitPosArray[H2], bitPosArray[G7] | 239 bitPosArray[H7]) 240kwingpawns2 = (bitPosArray[G3] | bitPosArray[H2], bitPosArray[G6] | 241 bitPosArray[H7]) 242 243################################################################################ 244# Ranks and files # 245################################################################################ 246 247rankBits = [255 << i * 8 for i in range(7, -1, -1)] 248fileBits = [0x0101010101010101 << i for i in range(7, -1, -1)] 249 250# Bit boards 251 252WHITE_SQUARES = 0x55AA55AA55AA55AA 253BLACK_SQUARES = 0xAA55AA55AA55AA55 254 255# - - - - - - - - 256# - - - - - - - - 257# - - - - - - - - 258# - - - # # - - - 259# - - - # # - - - 260# - - - - - - - - 261# - - - - - - - - 262# - - - - - - - - 263CENTER_FOUR = 0x0000001818000000 264 265# - - - - - - - - 266# - - - - - - - - 267# - - # # # # - - 268# - - # # # # - - 269# - - # # # # - - 270# - - # # # # - - 271# - - - - - - - - 272# - - - - - - - - 273sbox = 0x00003C3C3C3C0000 274 275# - - - - - - - - 276# - # # # # # # - 277# - # # # # # # - 278# - # # # # # # - 279# - # # # # # # - 280# - # # # # # # - 281# - # # # # # # - 282# - - - - - - - - 283lbox = 0x007E7E7E7E7E7E00 284 285# - - - - - # # # 286# - - - - - # # # 287# - - - - - # # # 288# - - - - - # # # 289# - - - - - # # # 290# - - - - - # # # 291# - - - - - # # # 292# - - - - - # # # 293right = fileBits[5] | fileBits[6] | fileBits[7] 294 295# # # # - - - - - 296# # # # - - - - - 297# # # # - - - - - 298# # # # - - - - - 299# # # # - - - - - 300# # # # - - - - - 301# # # # - - - - - 302# # # # - - - - - 303left = fileBits[0] | fileBits[1] | fileBits[2] 304 305# Generate the move bitboards. For e.g. the bitboard for all # 306# the moves of a knight on f3 is given by MoveArray[knight][21]. # 307 308dir = [ 309 None, 310 [9, 11], # Only capture moves are included 311 [-21, -19, -12, -8, 8, 12, 19, 21], 312 [-11, -9, 9, 11], 313 [-10, -1, 1, 10], 314 [-11, -10, -9, -1, 1, 9, 10, 11], 315 [-11, -10, -9, -1, 1, 9, 10, 11], 316 [-9, -11], 317 [-11, -9, 9, 10, 11], 318 [-11, -10, -9, 9, 11], 319 [-11, -9, 9, 11], 320 321 # Following are for front and back walls. Will be removed from list after 322 # the loop 323 [9, 10, 11], 324 [-9, -10, -11] 325] 326 327sliders += [False, False] 328 329map = [ 330 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 331 -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, 8, 9, 10, 11, 12, 13, 14, 15, -1, 332 -1, 16, 17, 18, 19, 20, 21, 22, 23, -1, -1, 24, 25, 26, 27, 28, 29, 30, 31, 333 -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, 40, 41, 42, 43, 44, 45, 46, 334 47, -1, -1, 48, 49, 50, 51, 52, 53, 54, 55, -1, -1, 56, 57, 58, 59, 60, 61, 335 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 336 -1, -1, -1, -1 337] 338 339moveArray = [[0] * 64 for i in range(len(dir))] # moveArray[len(dir)][64] 340 341for piece in range(1, len(dir)): 342 for fcord in range(120): 343 f = map[fcord] 344 if f == -1: 345 # We only generate moves for squares inside the board 346 continue 347 # Create a new bitboard 348 b = 0 349 for d in dir[piece]: 350 tcord = fcord 351 while True: 352 tcord += d 353 t = map[tcord] 354 if t == -1: 355 # If we landed outside of board, there is no more to look 356 # for 357 break 358 b = setBit(b, t) 359 if not sliders[piece]: 360 # If we are a slider, we should not break, but add the dir 361 # value once again 362 break 363 moveArray[piece][f] = b 364 365frontWall = (moveArray[-2], moveArray[-1]) 366del moveArray[-1] 367del moveArray[-1] 368del dir[-1] 369del dir[-1] 370del sliders[-1] 371del sliders[-1] 372 373# For each square, there are 8 rays. The first 4 rays are diagonals 374# for the bishops and the next 4 are file/rank for the rooks. 375# The queen uses all 8 rays. 376# These rays are used for move generation rather than MoveArray[]. 377# Also initialize the directions[][] array. directions[f][t] returns 378# the index into rays[f] array allow us to find the ray in that direction. 379 380directions = [[-1] * 64 for i in range(64)] # directions[64][64] 381rays = [[0] * 8 for i in range(64)] # rays[64][8] 382 383for fcord in range(120): 384 f = map[fcord] 385 if f == -1: 386 continue 387 ray = -1 388 for piece in BISHOP, ROOK: 389 for d in dir[piece]: 390 ray += 1 391 b = 0 392 tcord = fcord 393 while True: 394 tcord += d 395 t = map[tcord] 396 if t == -1: 397 break 398 rays[f][ray] = setBit(rays[f][ray], t) 399 directions[f][t] = ray 400 401# The FromToRay[b2][f6] gives the diagonal ray from c3 to f6; 402# It also produces horizontal/vertical rays as well. If no 403# ray is possible, then a 0 is returned. 404 405fromToRay = [[0] * 64 for i in range(64)] # fromToRay[64][64] 406 407for piece in BISHOP, ROOK: 408 for fcord in range(120): 409 f = map[fcord] 410 if f == -1: 411 continue 412 for d in dir[piece]: 413 tcord = fcord 414 t = map[tcord] 415 416 while True: 417 b = fromToRay[f][t] 418 tcord += d 419 t = map[tcord] 420 if t == -1: 421 break 422 fromToRay[f][t] = setBit(fromToRay[f][t], t) 423 fromToRay[f][t] |= b 424 425# The PassedPawnMask variable is used to determine if a pawn is passed. 426# his mask is basically all 1's from the square in front of the pawn to 427# the promotion square, also duplicated on both files besides the pawn 428# file. Other bits will be set to zero. 429# E.g. PassedPawnMask[white][b3] = 1's in a4-c4-c8-a8 rect, 0 otherwise. 430 431passedPawnMask = [[0] * 64, [0] * 64] 432 433# Do for white pawns first 434for cord in range(64): 435 passedPawnMask[WHITE][cord] = rays[cord][7] 436 passedPawnMask[BLACK][cord] = rays[cord][4] 437 if cord & 7 != 0: 438 # If file is not left most 439 passedPawnMask[WHITE][cord] |= rays[cord - 1][7] 440 passedPawnMask[BLACK][cord] |= rays[cord - 1][4] 441 if cord & 7 != 7: 442 # If file is not right most 443 passedPawnMask[WHITE][cord] |= rays[cord + 1][7] 444 passedPawnMask[BLACK][cord] |= rays[cord + 1][4] 445 446# The IsolaniMask variable is used to determine if a pawn is an isolani. 447# This mask is basically all 1's on files beside the file the pawn is on. 448# Other bits will be set to zero. 449# E.g. isolaniMask[d-file] = 1's in c-file & e-file, 0 otherwise. 450 451isolaniMask = [0] * 8 452 453isolaniMask[0] = fileBits[1] 454isolaniMask[7] = fileBits[6] 455for i in range(1, 7): 456 isolaniMask[i] = fileBits[i - 1] | fileBits[i + 1] 457 458# The SquarePawnMask is used to determine if a king is in the square of 459# the passed pawn and is able to prevent it from queening. 460# Caveat: Pawns on 2nd rank have the same mask as pawns on the 3rd rank 461# as they can advance 2 squares. 462 463squarePawnMask = [[0] * 64, [0] * 64] 464for cord in range(64): 465 # White mask 466 rank = 7 - RANK(cord) 467 i = max(cord & 56, cord - rank) 468 j = min(cord | 7, cord + rank) 469 for k in range(i, j + 1): 470 squarePawnMask[WHITE][cord] |= bitPosArray[k] | fromToRay[k][k | 56] 471 472 # Black mask 473 rank = RANK(cord) 474 i = max(cord & 56, cord - rank) 475 j = min(cord | 7, cord + rank) 476 for k in range(i, j + 1): 477 squarePawnMask[BLACK][cord] |= bitPosArray[k] | fromToRay[k][k & 7] 478 479# For pawns on 2nd rank, they have same mask as pawns on 3rd rank 480for cord in range(A2, H2 + 1): 481 squarePawnMask[WHITE][cord] = squarePawnMask[WHITE][cord + 8] 482for cord in range(A7, H7 + 1): 483 squarePawnMask[BLACK][cord] = squarePawnMask[BLACK][cord - 8] 484 485# These tables are used to calculate rook, queen and bishop moves 486 487ray00 = [rays[cord][5] | rays[cord][6] | 1 << (63 - cord) 488 for cord in range(64)] 489ray45 = [rays[cord][0] | rays[cord][3] | 1 << (63 - cord) 490 for cord in range(64)] 491ray90 = [rays[cord][4] | rays[cord][7] | 1 << (63 - cord) 492 for cord in range(64)] 493ray135 = [rays[cord][1] | rays[cord][2] | 1 << (63 - cord) 494 for cord in range(64)] 495 496attack00 = [{} for a in range(64)] 497attack45 = [{} for a in range(64)] 498attack90 = [{} for a in range(64)] 499attack135 = [{} for a in range(64)] 500 501cmap = [128, 64, 32, 16, 8, 4, 2, 1] 502rot1 = [A1, A2, A3, A4, A5, A6, A7, A8] 503rot2 = [A1, B2, C3, D4, E5, F6, G7, H8] 504rot3 = [A8, B7, C6, D5, E4, F3, G2, H1] 505 506# To save time, we init a main line for each of the four directions, and next 507# we will translate it for each possible cord 508for cord in range(8): 509 for map in range(1, 256): 510 511 # Skip entries without cord set, as cord will always be set 512 if not map & cmap[cord]: 513 continue 514 515 # Find limits inclusive 516 cord1 = cord2 = cord 517 while cord1 > 0: 518 cord1 -= 1 519 if cmap[cord1] & map: 520 break 521 while cord2 < 7: 522 cord2 += 1 523 if cmap[cord2] & map: 524 break 525 526 # Remember A1 is the left most bit 527 map00 = map << 56 528 529 attack00[cord][map00] = \ 530 fromToRay[cord][cord1] |\ 531 fromToRay[cord][cord2] 532 533 map90 = reduce(or_, (1 << 63 - rot1[c] for c in iterBits(map00))) 534 attack90[rot1[cord]][map90] = \ 535 fromToRay[rot1[cord]][rot1[cord1]] | \ 536 fromToRay[rot1[cord]][rot1[cord2]] 537 538 map45 = reduce(or_, (1 << 63 - rot2[c] for c in iterBits(map00))) 539 attack45[rot2[cord]][map45] = \ 540 fromToRay[rot2[cord]][rot2[cord1]] | \ 541 fromToRay[rot2[cord]][rot2[cord2]] 542 543 map135 = reduce(or_, (1 << 63 - rot3[c] for c in iterBits(map00))) 544 attack135[rot3[cord]][map135] = \ 545 fromToRay[rot3[cord]][rot3[cord1]] |\ 546 fromToRay[rot3[cord]][rot3[cord2]] 547 548MAXBITBOARD = (1 << 64) - 1 549 550for r in range(A2, A8 + 1, 8): 551 for cord in iterBits(ray00[r]): 552 attack00[cord] = dict((map >> 8, ray >> 8) 553 for map, ray in attack00[cord - 8].items()) 554 555for r in range(B1, H1 + 1): 556 for cord in iterBits(ray90[r]): 557 attack90[cord] = dict((map >> 1, ray >> 1) 558 for map, ray in attack90[cord - 1].items()) 559 560# Bottom right 561for r in range(B1, H1 + 1): 562 for cord in iterBits(ray45[r]): 563 attack45[cord] = dict((map << 8 & MAXBITBOARD, ray << 8 & MAXBITBOARD) 564 for map, ray in attack45[cord + 8].items()) 565 566# Top left 567for r in reversed(range(A8, H8)): 568 for cord in iterBits(ray45[r]): 569 attack45[cord] = dict((map >> 8, ray >> 8) 570 for map, ray in attack45[cord - 8].items()) 571 572# Top right 573for r in range(B8, H8 + 1): 574 for cord in iterBits(ray135[r]): 575 attack135[cord] = dict((map >> 8, ray >> 8) 576 for map, ray in attack135[cord - 8].items()) 577 578# Bottom left 579for r in reversed(range(A1, H1)): 580 for cord in iterBits(ray135[r]): 581 attack135[cord] = dict((map << 8 & MAXBITBOARD, ray << 8 & MAXBITBOARD) 582 for map, ray in attack135[cord + 8].items()) 583