import time #import warnings #warnings.filterwarnings("ignore", category=RuntimeWarning, message="overflow encountered in scalar multiply") #region Constants WP = 0 WN = 1 WB = 2 WR = 3 WQ = 4 WK = 5 BP = 6 BN = 7 BB = 8 BR = 9 BQ = 10 BK = 11 EMPTY = 12 A8 = 0 B8 = 1 C8 = 2 D8 = 3 E8 = 4 F8 = 5 G8 = 6 H8 = 7 A7 = 8 B7 = 9 C7 = 10 D7 = 11 E7 = 12 F7 = 13 G7 = 14 H7 = 15 A6 = 16 B6 = 17 C6 = 18 D6 = 19 E6 = 20 F6 = 21 G6 = 22 H6 = 23 A5 = 24 B5 = 25 C5 = 26 D5 = 27 E5 = 28 F5 = 29 G5 = 30 H5 = 31 A4 = 32 B4 = 33 C4 = 34 D4 = 35 E4 = 36 F4 = 37 G4 = 38 H4 = 39 A3 = 40 B3 = 41 C3 = 42 D3 = 43 E3 = 44 F3 = 45 G3 = 46 H3 = 47 A2 = 48 B2 = 49 C2 = 50 D2 = 51 E2 = 52 F2 = 53 G2 = 54 H2 = 55 A1 = 56 B1 = 57 C1 = 58 D1 = 59 E1 = 60 F1 = 61 G1 = 62 H1 = 63 PINNED_SQUARE_INDEX = 0 PINNING_PIECE_INDEX = 1 TAG_NONE = 0 TAG_CAPTURE = 1 TAG_WHITEEP = 2 TAG_BLACKEP = 3 TAG_WCASTLEKS = 4 TAG_WCASTLEQS = 5 TAG_BCASTLEKS = 6 TAG_BCASTLEQS = 7 TAG_BKnightPromotion = 8 TAG_BBishopPromotion = 9 TAG_BQueenPromotion = 10 TAG_BRookPromotion = 11 TAG_WKnightPromotion = 12 TAG_WBishopPromotion = 13 TAG_WQueenPromotion = 14 TAG_WRookPromotion = 15 TAG_BCaptureKnightPromotion = 16 TAG_BCaptureBishopPromotion = 17 TAG_BCaptureQueenPromotion = 18 TAG_BCaptureRookPromotion = 19 TAG_WCaptureKnightPromotion = 20 TAG_WCaptureBishopPromotion = 21 TAG_WCaptureQueenPromotion = 22 TAG_WCaptureRookPromotion = 23 TAG_DoublePawnWhite = 24 TAG_DoublePawnBlack = 25 TAG_CHECK = 26 TAG_CHECK_CAPTURE = 27 WKS_CASTLE_RIGHTS = 0 WQS_CASTLE_RIGHTS = 1 BKS_CASTLE_RIGHTS = 2 BQS_CASTLE_RIGHTS = 3 WKS_EMPTY_BITBOARD = 6917529027641081856 WQS_EMPTY_BITBOARD = 1008806316530991104 BKS_EMPTY_BITBOARD = 96 BQS_EMPTY_BITBOARD = 14 MOVE_STARTING = 0 MOVE_TARGET = 1 MOVE_PIECE = 2 MOVE_TAG = 3 INBETWEEN_BITBOARDS = [ [ 0, 2, 6, 14, 30, 62, 126, 254, 256, 512, 0, 0, 0, 0, 0, 0, 65792, 0, 262656, 0, 0, 0, 0, 0, 16843008, 0, 0, 134480384, 0, 0, 0, 0, 4311810304, 0, 0, 0, 68853957120, 0, 0, 0, 1103823438080, 0, 0, 0, 0, 35253226045952, 0, 0, 282578800148736, 0, 0, 0, 0, 0, 18049651735527936, 0, 72340172838076672, 0, 0, 0, 0, 0, 0, 9241421688590303744], [ 1, 0, 4, 12, 28, 60, 124, 252, 256, 512, 1024, 0, 0, 0, 0, 0, 0, 131584, 0, 525312, 0, 0, 0, 0, 0, 33686016, 0, 0, 268960768, 0, 0, 0, 0, 8623620608, 0, 0, 0, 137707914240, 0, 0, 0, 2207646876160, 0, 0, 0, 0, 70506452091904, 0, 0, 565157600297472, 0, 0, 0, 0, 0, 36099303471055872, 0, 144680345676153344, 0, 0, 0, 0, 0, 0], [ 3, 2, 0, 8, 24, 56, 120, 248, 0, 512, 1024, 2048, 0, 0, 0, 0, 66048, 0, 263168, 0, 1050624, 0, 0, 0, 0, 0, 67372032, 0, 0, 537921536, 0, 0, 0, 0, 17247241216, 0, 0, 0, 275415828480, 0, 0, 0, 4415293752320, 0, 0, 0, 0, 141012904183808, 0, 0, 1130315200594944, 0, 0, 0, 0, 0, 0, 0, 289360691352306688, 0, 0, 0, 0, 0], [ 7, 6, 4, 0, 16, 48, 112, 240, 0, 0, 1024, 2048, 4096, 0, 0, 0, 0, 132096, 0, 526336, 0, 2101248, 0, 0, 16909312, 0, 0, 134744064, 0, 0, 1075843072, 0, 0, 0, 0, 34494482432, 0, 0, 0, 550831656960, 0, 0, 0, 8830587504640, 0, 0, 0, 0, 0, 0, 0, 2260630401189888, 0, 0, 0, 0, 0, 0, 0, 578721382704613376, 0, 0, 0, 0], [ 15, 14, 12, 8, 0, 32, 96, 224, 0, 0, 0, 2048, 4096, 8192, 0, 0, 0, 0, 264192, 0, 1052672, 0, 4202496, 0, 0, 33818624, 0, 0, 269488128, 0, 0, 2151686144, 4328785920, 0, 0, 0, 68988964864, 0, 0, 0, 0, 0, 0, 0, 17661175009280, 0, 0, 0, 0, 0, 0, 0, 4521260802379776, 0, 0, 0, 0, 0, 0, 0, 1157442765409226752, 0, 0, 0], [ 31, 30, 28, 24, 16, 0, 64, 192, 0, 0, 0, 0, 4096, 8192, 16384, 0, 0, 0, 0, 528384, 0, 2105344, 0, 8404992, 0, 0, 67637248, 0, 0, 538976256, 0, 0, 0, 8657571840, 0, 0, 0, 137977929728, 0, 0, 1108169199616, 0, 0, 0, 0, 35322350018560, 0, 0, 0, 0, 0, 0, 0, 9042521604759552, 0, 0, 0, 0, 0, 0, 0, 2314885530818453504, 0, 0], [ 63, 62, 60, 56, 48, 32, 0, 128, 0, 0, 0, 0, 0, 8192, 16384, 32768, 0, 0, 0, 0, 1056768, 0, 4210688, 0, 0, 0, 0, 135274496, 0, 0, 1077952512, 0, 0, 0, 17315143680, 0, 0, 0, 275955859456, 0, 0, 2216338399232, 0, 0, 0, 0, 70644700037120, 0, 283691315109888, 0, 0, 0, 0, 0, 18085043209519104, 0, 0, 0, 0, 0, 0, 0, 4629771061636907008, 0], [ 127, 126, 124, 120, 112, 96, 64, 0, 0, 0, 0, 0, 0, 0, 16384, 32768, 0, 0, 0, 0, 0, 2113536, 0, 8421376, 0, 0, 0, 0, 270548992, 0, 0, 2155905024, 0, 0, 0, 34630287360, 0, 0, 0, 551911718912, 0, 0, 4432676798464, 0, 0, 0, 0, 141289400074240, 0, 567382630219776, 0, 0, 0, 0, 0, 36170086419038208, 72624976668147712, 0, 0, 0, 0, 0, 0, 9259542123273814016], [ 1, 2, 0, 0, 0, 0, 0, 0, 0, 512, 1536, 3584, 7680, 15872, 32256, 65024, 65536, 131072, 0, 0, 0, 0, 0, 0, 16842752, 0, 67239936, 0, 0, 0, 0, 0, 4311810048, 0, 0, 34426978304, 0, 0, 0, 0, 1103823437824, 0, 0, 0, 17626613022720, 0, 0, 0, 282578800148480, 0, 0, 0, 0, 9024825867763712, 0, 0, 72340172838076416, 0, 0, 0, 0, 0, 4620710844295151616, 0], [ 1, 2, 4, 0, 0, 0, 0, 0, 256, 0, 1024, 3072, 7168, 15360, 31744, 64512, 65536, 131072, 262144, 0, 0, 0, 0, 0, 0, 33685504, 0, 134479872, 0, 0, 0, 0, 0, 8623620096, 0, 0, 68853956608, 0, 0, 0, 0, 2207646875648, 0, 0, 0, 35253226045440, 0, 0, 0, 565157600296960, 0, 0, 0, 0, 18049651735527424, 0, 0, 144680345676152832, 0, 0, 0, 0, 0, 9241421688590303232], [ 0, 2, 4, 8, 0, 0, 0, 0, 768, 512, 0, 2048, 6144, 14336, 30720, 63488, 0, 131072, 262144, 524288, 0, 0, 0, 0, 16908288, 0, 67371008, 0, 268959744, 0, 0, 0, 0, 0, 17247240192, 0, 0, 137707913216, 0, 0, 0, 0, 4415293751296, 0, 0, 0, 70506452090880, 0, 0, 0, 1130315200593920, 0, 0, 0, 0, 36099303471054848, 0, 0, 289360691352305664, 0, 0, 0, 0, 0], [ 36099303471054849, 0, 4, 8, 16, 0, 0, 0, 1792, 1536, 1024, 0, 4096, 12288, 28672, 61440, 0, 0, 262144, 524288, 1048576, 0, 0, 0, 0, 33816576, 0, 134742016, 0, 537919488, 0, 0, 4328783872, 0, 0, 34494480384, 0, 0, 275415826432, 0, 0, 0, 0, 8830587502592, 0, 0, 0, 141012904181760, 0, 0, 0, 2260630401187840, 0, 0, 0, 0, 0, 0, 0, 578721382704611328, 0, 0, 0, 0], [ 0, 0, 0, 8, 16, 32, 0, 0, 3840, 3584, 3072, 2048, 0, 8192, 24576, 57344, 0, 0, 0, 524288, 1048576, 2097152, 0, 0, 0, 0, 67633152, 0, 269484032, 0, 1075838976, 0, 0, 8657567744, 0, 0, 68988960768, 0, 0, 550831652864, 1108169195520, 0, 0, 0, 17661175005184, 0, 0, 0, 0, 0, 0, 0, 4521260802375680, 0, 0, 0, 0, 0, 0, 0, 1157442765409222656, 0, 0, 0], [ 0, 0, 0, 0, 16, 32, 64, 0, 7936, 7680, 7168, 6144, 4096, 0, 16384, 49152, 0, 0, 0, 0, 1048576, 2097152, 4194304, 0, 0, 0, 0, 135266304, 0, 538968064, 0, 2151677952, 0, 0, 17315135488, 0, 0, 137977921536, 0, 0, 0, 2216338391040, 0, 0, 0, 35322350010368, 0, 0, 283691315101696, 0, 0, 0, 0, 9042521604751360, 0, 0, 0, 0, 0, 0, 0, 2314885530818445312, 0, 0], [ 0, 0, 0, 0, 0, 32, 64, 128, 16128, 15872, 15360, 14336, 12288, 8192, 0, 32768, 0, 0, 0, 0, 0, 2097152, 4194304, 8388608, 0, 0, 0, 0, 270532608, 0, 1077936128, 0, 0, 0, 0, 34630270976, 0, 0, 275955843072, 0, 0, 0, 4432676782080, 0, 0, 0, 70644700020736, 0, 0, 567382630203392, 0, 0, 0, 0, 18085043209502720, 0, 72624976668131328, 0, 0, 0, 0, 0, 4629771061636890624, 0], [ 0, 0, 0, 0, 0, 0, 64, 128, 32512, 32256, 31744, 30720, 28672, 24576, 16384, 0, 0, 0, 0, 0, 0, 0, 4194304, 8388608, 0, 0, 0, 0, 0, 541065216, 0, 2155872256, 0, 0, 0, 0, 69260541952, 0, 0, 551911686144, 0, 0, 0, 8865353564160, 0, 0, 0, 141289400041472, 0, 0, 1134765260406784, 0, 0, 0, 0, 36170086419005440, 0, 145249953336262656, 0, 0, 0, 0, 0, 9259542123273781248], [ 257, 0, 516, 0, 0, 0, 0, 0, 256, 512, 0, 0, 0, 0, 0, 0, 0, 131072, 393216, 917504, 1966080, 4063232, 8257536, 16646144, 16777216, 33554432, 0, 0, 0, 0, 0, 0, 4311744512, 0, 17213423616, 0, 0, 0, 0, 0, 1103823372288, 0, 0, 8813306445824, 0, 0, 0, 0, 282578800082944, 0, 0, 0, 4512412933816320, 0, 0, 0, 72340172838010880, 0, 0, 0, 0, 2310355422147510272, 0, 0], [ 0, 514, 0, 1032, 0, 0, 0, 0, 256, 512, 1024, 0, 0, 0, 0, 0, 65536, 0, 262144, 786432, 1835008, 3932160, 8126464, 16515072, 16777216, 33554432, 67108864, 0, 0, 0, 0, 0, 0, 8623489024, 0, 34426847232, 0, 0, 0, 0, 0, 2207646744576, 0, 0, 17626612891648, 0, 0, 0, 0, 565157600165888, 0, 0, 0, 9024825867632640, 0, 0, 0, 144680345676021760, 0, 0, 0, 0, 4620710844295020544, 0], [ 513, 0, 1028, 0, 2064, 0, 0, 0, 0, 512, 1024, 2048, 0, 0, 0, 0, 196608, 131072, 0, 524288, 1572864, 3670016, 7864320, 16252928, 0, 33554432, 67108864, 134217728, 0, 0, 0, 0, 4328521728, 0, 17246978048, 0, 68853694464, 0, 0, 0, 0, 0, 4415293489152, 0, 0, 35253225783296, 0, 0, 0, 0, 1130315200331776, 0, 0, 0, 18049651735265280, 0, 0, 0, 289360691352043520, 0, 0, 0, 0, 9241421688590041088], [ 0, 1026, 0, 2056, 0, 4128, 0, 0, 0, 0, 1024, 2048, 4096, 0, 0, 0, 458752, 393216, 262144, 0, 1048576, 3145728, 7340032, 15728640, 0, 0, 67108864, 134217728, 268435456, 0, 0, 0, 0, 8657043456, 0, 34493956096, 0, 137707388928, 0, 0, 1108168671232, 0, 0, 8830586978304, 0, 0, 70506451566592, 0, 0, 0, 0, 2260630400663552, 0, 0, 0, 36099303470530560, 0, 0, 0, 578721382704087040, 0, 0, 0, 0], [ 36099303470530561, 0, 2052, 0, 4112, 0, 8256, 0, 0, 0, 0, 2048, 4096, 8192, 0, 0, 983040, 917504, 786432, 524288, 0, 2097152, 6291456, 14680064, 0, 0, 0, 134217728, 268435456, 536870912, 0, 0, 0, 0, 17314086912, 0, 68987912192, 0, 275414777856, 0, 0, 2216337342464, 0, 0, 17661173956608, 0, 0, 141012903133184, 283691314053120, 0, 0, 0, 4521260801327104, 0, 0, 0, 0, 0, 0, 0, 1157442765408174080, 0, 0, 0], [ 0, 0, 0, 4104, 0, 8224, 0, 16512, 0, 0, 0, 0, 4096, 8192, 16384, 0, 2031616, 1966080, 1835008, 1572864, 1048576, 0, 4194304, 12582912, 0, 0, 0, 0, 268435456, 536870912, 1073741824, 0, 0, 0, 0, 34628173824, 0, 137975824384, 0, 550829555712, 0, 0, 4432674684928, 0, 0, 35322347913216, 0, 0, 0, 567382628106240, 0, 0, 0, 9042521602654208, 0, 0, 72624976666034176, 0, 0, 0, 0, 2314885530816348160, 0, 0], [ 0, 0, 0, 0, 8208, 0, 16448, 0, 0, 0, 0, 0, 0, 8192, 16384, 32768, 4128768, 4063232, 3932160, 3670016, 3145728, 2097152, 0, 8388608, 0, 0, 0, 0, 0, 536870912, 1073741824, 2147483648, 0, 0, 0, 0, 69256347648, 0, 275951648768, 0, 0, 0, 0, 8865349369856, 0, 0, 70644695826432, 0, 0, 0, 1134765256212480, 0, 0, 0, 18085043205308416, 0, 0, 145249953332068352, 0, 0, 0, 0, 4629771061632696320, 0], [ 0, 0, 0, 0, 0, 16416, 0, 32896, 0, 0, 0, 0, 0, 0, 16384, 32768, 8323072, 8257536, 8126464, 7864320, 7340032, 6291456, 4194304, 0, 0, 0, 0, 0, 0, 0, 1073741824, 2147483648, 0, 0, 0, 0, 0, 138512695296, 0, 551903297536, 0, 0, 0, 0, 17730698739712, 0, 0, 141289391652864, 0, 0, 0, 2269530512424960, 0, 0, 0, 36170086410616832, 0, 0, 290499906664136704, 0, 0, 0, 0, 9259542123265392640], [ 65793, 0, 0, 132104, 0, 0, 0, 0, 65792, 0, 132096, 0, 0, 0, 0, 0, 65536, 131072, 0, 0, 0, 0, 0, 0, 0, 33554432, 100663296, 234881024, 503316480, 1040187392, 2113929216, 4261412864, 4294967296, 8589934592, 0, 0, 0, 0, 0, 0, 1103806595072, 0, 4406636445696, 0, 0, 0, 0, 0, 282578783305728, 0, 0, 2256206450130944, 0, 0, 0, 0, 72340172821233664, 0, 0, 0, 1155177711056977920, 0, 0, 0], [ 0, 131586, 0, 0, 264208, 0, 0, 0, 0, 131584, 0, 264192, 0, 0, 0, 0, 65536, 131072, 262144, 0, 0, 0, 0, 0, 16777216, 0, 67108864, 201326592, 469762048, 1006632960, 2080374784, 4227858432, 4294967296, 8589934592, 17179869184, 0, 0, 0, 0, 0, 0, 2207613190144, 0, 8813272891392, 0, 0, 0, 0, 0, 565157566611456, 0, 0, 4512412900261888, 0, 0, 0, 0, 144680345642467328, 0, 0, 0, 2310355422113955840, 0, 0], [ 0, 0, 263172, 0, 0, 528416, 0, 0, 131328, 0, 263168, 0, 528384, 0, 0, 0, 0, 131072, 262144, 524288, 0, 0, 0, 0, 50331648, 33554432, 0, 134217728, 402653184, 939524096, 2013265920, 4160749568, 0, 8589934592, 17179869184, 34359738368, 0, 0, 0, 0, 1108101562368, 0, 4415226380288, 0, 17626545782784, 0, 0, 0, 0, 0, 1130315133222912, 0, 0, 9024825800523776, 0, 0, 0, 0, 289360691284934656, 0, 0, 0, 4620710844227911680, 0], [ 262657, 0, 0, 526344, 0, 0, 1056832, 0, 0, 262656, 0, 526336, 0, 1056768, 0, 0, 0, 0, 262144, 524288, 1048576, 0, 0, 0, 117440512, 100663296, 67108864, 0, 268435456, 805306368, 1879048192, 4026531840, 0, 0, 17179869184, 34359738368, 68719476736, 0, 0, 0, 0, 2216203124736, 0, 8830452760576, 0, 35253091565568, 0, 0, 283691179835392, 0, 0, 2260630266445824, 0, 0, 18049651601047552, 0, 0, 0, 0, 578721382569869312, 0, 0, 0, 9241421688455823360], [ 0, 525314, 0, 0, 1052688, 0, 0, 2113664, 0, 0, 525312, 0, 1052672, 0, 2113536, 0, 0, 0, 0, 524288, 1048576, 2097152, 0, 0, 251658240, 234881024, 201326592, 134217728, 0, 536870912, 1610612736, 3758096384, 0, 0, 0, 34359738368, 68719476736, 137438953472, 0, 0, 0, 0, 4432406249472, 0, 17660905521152, 0, 70506183131136, 0, 0, 567382359670784, 0, 0, 4521260532891648, 0, 0, 36099303202095104, 72624976397598720, 0, 0, 0, 1157442765139738624, 0, 0, 0], [ 36099303202095105, 0, 1050628, 0, 0, 2105376, 0, 0, 0, 0, 0, 1050624, 0, 2105344, 0, 4227072, 0, 0, 0, 0, 1048576, 2097152, 4194304, 0, 520093696, 503316480, 469762048, 402653184, 268435456, 0, 1073741824, 3221225472, 0, 0, 0, 0, 68719476736, 137438953472, 274877906944, 0, 0, 0, 0, 8864812498944, 0, 35321811042304, 0, 141012366262272, 0, 0, 1134764719341568, 0, 0, 9042521065783296, 0, 0, 0, 145249952795197440, 0, 0, 0, 2314885530279477248, 0, 0], [ 0, 0, 0, 2101256, 0, 0, 4210752, 0, 0, 0, 0, 0, 2101248, 0, 4210688, 0, 0, 0, 0, 0, 0, 2097152, 4194304, 8388608, 1056964608, 1040187392, 1006632960, 939524096, 805306368, 536870912, 0, 2147483648, 0, 0, 0, 0, 0, 137438953472, 274877906944, 549755813888, 0, 0, 0, 0, 17729624997888, 0, 70643622084608, 0, 0, 0, 0, 2269529438683136, 0, 0, 18085042131566592, 0, 0, 0, 290499905590394880, 0, 0, 0, 4629771060558954496, 0], [ 0, 0, 0, 0, 4202512, 0, 0, 8421504, 0, 0, 0, 0, 0, 4202496, 0, 8421376, 0, 0, 0, 0, 0, 0, 4194304, 8388608, 2130706432, 2113929216, 2080374784, 2013265920, 1879048192, 1610612736, 1073741824, 0, 0, 0, 0, 0, 0, 0, 274877906944, 549755813888, 0, 0, 0, 0, 0, 35459249995776, 0, 141287244169216, 0, 0, 0, 0, 4539058877366272, 0, 0, 36170084263133184, 0, 0, 0, 580999811180789760, 0, 0, 0, 9259542121117908992], [ 16843009, 0, 0, 0, 33818640, 0, 0, 0, 16843008, 0, 0, 33818624, 0, 0, 0, 0, 16842752, 0, 33816576, 0, 0, 0, 0, 0, 16777216, 33554432, 0, 0, 0, 0, 0, 0, 0, 8589934592, 25769803776, 60129542144, 128849018880, 266287972352, 541165879296, 1090921693184, 1099511627776, 2199023255552, 0, 0, 0, 0, 0, 0, 282574488338432, 0, 1128098930098176, 0, 0, 0, 0, 0, 72340168526266368, 0, 0, 577588851233521664, 0, 0, 0, 0], [ 0, 33686018, 0, 0, 0, 67637280, 0, 0, 0, 33686016, 0, 0, 67637248, 0, 0, 0, 0, 33685504, 0, 67633152, 0, 0, 0, 0, 16777216, 33554432, 67108864, 0, 0, 0, 0, 0, 4294967296, 0, 17179869184, 51539607552, 120259084288, 257698037760, 532575944704, 1082331758592, 1099511627776, 2199023255552, 4398046511104, 0, 0, 0, 0, 0, 0, 565148976676864, 0, 2256197860196352, 0, 0, 0, 0, 0, 144680337052532736, 0, 0, 1155177702467043328, 0, 0, 0], [ 0, 0, 67372036, 0, 0, 0, 135274560, 0, 0, 0, 67372032, 0, 0, 135274496, 0, 0, 33619968, 0, 67371008, 0, 135266304, 0, 0, 0, 0, 33554432, 67108864, 134217728, 0, 0, 0, 0, 12884901888, 8589934592, 0, 34359738368, 103079215104, 240518168576, 515396075520, 1065151889408, 0, 2199023255552, 4398046511104, 8796093022208, 0, 0, 0, 0, 283673999966208, 0, 1130297953353728, 0, 4512395720392704, 0, 0, 0, 0, 0, 289360674105065472, 0, 0, 2310355404934086656, 0, 0], [ 0, 0, 0, 134744072, 0, 0, 0, 270549120, 67240192, 0, 0, 134744064, 0, 0, 270548992, 0, 0, 67239936, 0, 134742016, 0, 270532608, 0, 0, 0, 0, 67108864, 134217728, 268435456, 0, 0, 0, 30064771072, 25769803776, 17179869184, 0, 68719476736, 206158430208, 481036337152, 1030792151040, 0, 0, 4398046511104, 8796093022208, 17592186044416, 0, 0, 0, 0, 567347999932416, 0, 2260595906707456, 0, 9024791440785408, 0, 0, 72624942037860352, 0, 0, 578721348210130944, 0, 0, 4620710809868173312, 0], [ 134480385, 0, 0, 0, 269488144, 0, 0, 0, 0, 134480384, 0, 0, 269488128, 0, 0, 541097984, 0, 0, 134479872, 0, 269484032, 0, 541065216, 0, 0, 0, 0, 134217728, 268435456, 536870912, 0, 0, 64424509440, 60129542144, 51539607552, 34359738368, 0, 137438953472, 412316860416, 962072674304, 0, 0, 0, 8796093022208, 17592186044416, 35184372088832, 0, 0, 0, 0, 1134695999864832, 0, 4521191813414912, 0, 18049582881570816, 0, 0, 145249884075720704, 0, 0, 1157442696420261888, 0, 0, 9241421619736346624], [ 0, 268960770, 0, 0, 0, 538976288, 0, 0, 0, 0, 268960768, 0, 0, 538976256, 0, 0, 0, 0, 0, 268959744, 0, 538968064, 0, 1082130432, 0, 0, 0, 0, 268435456, 536870912, 1073741824, 0, 133143986176, 128849018880, 120259084288, 103079215104, 68719476736, 0, 274877906944, 824633720832, 0, 0, 0, 0, 17592186044416, 35184372088832, 70368744177664, 0, 0, 0, 0, 2269391999729664, 0, 9042383626829824, 0, 36099165763141632, 0, 0, 290499768151441408, 0, 0, 2314885392840523776, 0, 0], [ 36099165763141633, 0, 537921540, 0, 0, 0, 1077952576, 0, 0, 0, 0, 537921536, 0, 0, 1077952512, 0, 0, 0, 0, 0, 537919488, 0, 1077936128, 0, 0, 0, 0, 0, 0, 536870912, 1073741824, 2147483648, 270582939648, 266287972352, 257698037760, 240518168576, 206158430208, 137438953472, 0, 549755813888, 0, 0, 0, 0, 0, 35184372088832, 70368744177664, 140737488355328, 0, 0, 0, 0, 4538783999459328, 0, 18084767253659648, 0, 0, 0, 0, 580999536302882816, 0, 0, 4629770785681047552, 0], [ 0, 0, 0, 1075843080, 0, 0, 0, 2155905152, 0, 0, 0, 0, 1075843072, 0, 0, 2155905024, 0, 0, 0, 0, 0, 1075838976, 0, 2155872256, 0, 0, 0, 0, 0, 0, 1073741824, 2147483648, 545460846592, 541165879296, 532575944704, 515396075520, 481036337152, 412316860416, 274877906944, 0, 0, 0, 0, 0, 0, 0, 70368744177664, 140737488355328, 0, 0, 0, 0, 0, 9077567998918656, 0, 36169534507319296, 0, 0, 0, 0, 1161999072605765632, 0, 0, 9259541571362095104], [ 4311810305, 0, 0, 0, 0, 8657571872, 0, 0, 4311810304, 0, 0, 0, 8657571840, 0, 0, 0, 4311810048, 0, 0, 8657567744, 0, 0, 0, 0, 4311744512, 0, 8657043456, 0, 0, 0, 0, 0, 4294967296, 8589934592, 0, 0, 0, 0, 0, 0, 0, 2199023255552, 6597069766656, 15393162788864, 32985348833280, 68169720922112, 138538465099776, 279275953455104, 281474976710656, 562949953421312, 0, 0, 0, 0, 0, 0, 72339069014638592, 0, 288793326105133056, 0, 0, 0, 0, 0], [ 0, 8623620610, 0, 0, 0, 0, 17315143744, 0, 0, 8623620608, 0, 0, 0, 17315143680, 0, 0, 0, 8623620096, 0, 0, 17315135488, 0, 0, 0, 0, 8623489024, 0, 17314086912, 0, 0, 0, 0, 4294967296, 8589934592, 17179869184, 0, 0, 0, 0, 0, 1099511627776, 0, 4398046511104, 13194139533312, 30786325577728, 65970697666560, 136339441844224, 277076930199552, 281474976710656, 562949953421312, 1125899906842624, 0, 0, 0, 0, 0, 0, 144678138029277184, 0, 577586652210266112, 0, 0, 0, 0], [ 0, 0, 17247241220, 0, 0, 0, 0, 34630287488, 0, 0, 17247241216, 0, 0, 0, 34630287360, 0, 0, 0, 17247240192, 0, 0, 34630270976, 0, 0, 8606711808, 0, 17246978048, 0, 34628173824, 0, 0, 0, 0, 8589934592, 17179869184, 34359738368, 0, 0, 0, 0, 3298534883328, 2199023255552, 0, 8796093022208, 26388279066624, 61572651155456, 131941395333120, 272678883688448, 0, 562949953421312, 1125899906842624, 2251799813685248, 0, 0, 0, 0, 72620543991349248, 0, 289356276058554368, 0, 1155173304420532224, 0, 0, 0], [ 0, 0, 0, 34494482440, 0, 0, 0, 0, 0, 0, 0, 34494482432, 0, 0, 0, 69260574720, 17213489152, 0, 0, 34494480384, 0, 0, 69260541952, 0, 0, 17213423616, 0, 34493956096, 0, 69256347648, 0, 0, 0, 0, 17179869184, 34359738368, 68719476736, 0, 0, 0, 7696581394432, 6597069766656, 4398046511104, 0, 17592186044416, 52776558133248, 123145302310912, 263882790666240, 0, 0, 1125899906842624, 2251799813685248, 4503599627370496, 0, 0, 0, 0, 145241087982698496, 0, 578712552117108736, 0, 2310346608841064448, 0, 0], [ 0, 0, 0, 0, 68988964880, 0, 0, 0, 34426978560, 0, 0, 0, 68988964864, 0, 0, 0, 0, 34426978304, 0, 0, 68988960768, 0, 0, 138521083904, 0, 0, 34426847232, 0, 68987912192, 0, 138512695296, 0, 0, 0, 0, 34359738368, 68719476736, 137438953472, 0, 0, 16492674416640, 15393162788864, 13194139533312, 8796093022208, 0, 35184372088832, 105553116266496, 246290604621824, 0, 0, 0, 2251799813685248, 4503599627370496, 9007199254740992, 0, 0, 0, 0, 290482175965396992, 0, 1157425104234217472, 0, 4620693217682128896, 0], [ 68853957121, 0, 0, 0, 0, 137977929760, 0, 0, 0, 68853957120, 0, 0, 0, 137977929728, 0, 0, 0, 0, 68853956608, 0, 0, 137977921536, 0, 0, 0, 0, 0, 68853694464, 0, 137975824384, 0, 277025390592, 0, 0, 0, 0, 68719476736, 137438953472, 274877906944, 0, 34084860461056, 32985348833280, 30786325577728, 26388279066624, 17592186044416, 0, 70368744177664, 211106232532992, 0, 0, 0, 0, 4503599627370496, 9007199254740992, 18014398509481984, 0, 0, 0, 0, 580964351930793984, 0, 2314850208468434944, 0, 9241386435364257792], [ 0, 137707914242, 0, 0, 0, 0, 275955859520, 0, 0, 0, 137707914240, 0, 0, 0, 275955859456, 0, 0, 0, 0, 137707913216, 0, 0, 275955843072, 0, 0, 0, 0, 0, 137707388928, 0, 275951648768, 0, 0, 0, 0, 0, 0, 137438953472, 274877906944, 549755813888, 69269232549888, 68169720922112, 65970697666560, 61572651155456, 52776558133248, 35184372088832, 0, 140737488355328, 0, 0, 0, 0, 0, 9007199254740992, 18014398509481984, 36028797018963968, 0, 0, 0, 0, 1161928703861587968, 0, 4629700416936869888, 0], [ 36028797018963969, 0, 275415828484, 0, 0, 0, 0, 551911719040, 0, 0, 0, 275415828480, 0, 0, 0, 551911718912, 0, 0, 0, 0, 275415826432, 0, 0, 551911686144, 0, 0, 0, 0, 0, 275414777856, 0, 551903297536, 0, 0, 0, 0, 0, 0, 274877906944, 549755813888, 139637976727552, 138538465099776, 136339441844224, 131941395333120, 123145302310912, 105553116266496, 70368744177664, 0, 0, 0, 0, 0, 0, 0, 18014398509481984, 36028797018963968, 0, 0, 0, 0, 0, 2323857407723175936, 0, 9259400833873739776], [ 1103823438081, 0, 0, 0, 0, 0, 2216338399296, 0, 1103823438080, 0, 0, 0, 0, 2216338399232, 0, 0, 1103823437824, 0, 0, 0, 2216338391040, 0, 0, 0, 1103823372288, 0, 0, 2216337342464, 0, 0, 0, 0, 1103806595072, 0, 2216203124736, 0, 0, 0, 0, 0, 1099511627776, 2199023255552, 0, 0, 0, 0, 0, 0, 0, 562949953421312, 1688849860263936, 3940649673949184, 8444249301319680, 17451448556060672, 35465847065542656, 71494644084506624, 72057594037927936, 144115188075855872, 0, 0, 0, 0, 0, 0], [ 0, 2207646876162, 0, 0, 0, 0, 0, 4432676798592, 0, 2207646876160, 0, 0, 0, 0, 4432676798464, 0, 0, 2207646875648, 0, 0, 0, 4432676782080, 0, 0, 0, 2207646744576, 0, 0, 4432674684928, 0, 0, 0, 0, 2207613190144, 0, 4432406249472, 0, 0, 0, 0, 1099511627776, 2199023255552, 4398046511104, 0, 0, 0, 0, 0, 281474976710656, 0, 1125899906842624, 3377699720527872, 7881299347898368, 16888498602639360, 34902897112121344, 70931694131085312, 72057594037927936, 144115188075855872, 288230376151711744, 0, 0, 0, 0, 0], [ 0, 0, 4415293752324, 0, 0, 0, 0, 0, 0, 0, 4415293752320, 0, 0, 0, 0, 8865353596928, 0, 0, 4415293751296, 0, 0, 0, 8865353564160, 0, 0, 0, 4415293489152, 0, 0, 8865349369856, 0, 0, 2203318222848, 0, 4415226380288, 0, 8864812498944, 0, 0, 0, 0, 2199023255552, 4398046511104, 8796093022208, 0, 0, 0, 0, 844424930131968, 562949953421312, 0, 2251799813685248, 6755399441055744, 15762598695796736, 33776997205278720, 69805794224242688, 0, 144115188075855872, 288230376151711744, 576460752303423488, 0, 0, 0, 0], [ 0, 0, 0, 8830587504648, 0, 0, 0, 0, 0, 0, 0, 8830587504640, 0, 0, 0, 0, 0, 0, 0, 8830587502592, 0, 0, 0, 17730707128320, 4406653222912, 0, 0, 8830586978304, 0, 0, 17730698739712, 0, 0, 4406636445696, 0, 8830452760576, 0, 17729624997888, 0, 0, 0, 0, 4398046511104, 8796093022208, 17592186044416, 0, 0, 0, 1970324836974592, 1688849860263936, 1125899906842624, 0, 4503599627370496, 13510798882111488, 31525197391593472, 67553994410557440, 0, 0, 288230376151711744, 576460752303423488, 1152921504606846976, 0, 0, 0], [ 0, 0, 0, 0, 17661175009296, 0, 0, 0, 0, 0, 0, 0, 17661175009280, 0, 0, 0, 8813306511360, 0, 0, 0, 17661175005184, 0, 0, 0, 0, 8813306445824, 0, 0, 17661173956608, 0, 0, 35461397479424, 0, 0, 8813272891392, 0, 17660905521152, 0, 35459249995776, 0, 0, 0, 0, 8796093022208, 17592186044416, 35184372088832, 0, 0, 4222124650659840, 3940649673949184, 3377699720527872, 2251799813685248, 0, 9007199254740992, 27021597764222976, 63050394783186944, 0, 0, 0, 576460752303423488, 1152921504606846976, 2305843009213693952, 0, 0], [ 0, 0, 0, 0, 0, 35322350018592, 0, 0, 17626613022976, 0, 0, 0, 0, 35322350018560, 0, 0, 0, 17626613022720, 0, 0, 0, 35322350010368, 0, 0, 0, 0, 17626612891648, 0, 0, 35322347913216, 0, 0, 0, 0, 0, 17626545782784, 0, 35321811042304, 0, 70918499991552, 0, 0, 0, 0, 17592186044416, 35184372088832, 70368744177664, 0, 8725724278030336, 8444249301319680, 7881299347898368, 6755399441055744, 4503599627370496, 0, 18014398509481984, 54043195528445952, 0, 0, 0, 0, 1152921504606846976, 2305843009213693952, 4611686018427387904, 0], [ 35253226045953, 0, 0, 0, 0, 0, 70644700037184, 0, 0, 35253226045952, 0, 0, 0, 0, 70644700037120, 0, 0, 0, 35253226045440, 0, 0, 0, 70644700020736, 0, 0, 0, 0, 35253225783296, 0, 0, 70644695826432, 0, 0, 0, 0, 0, 35253091565568, 0, 70643622084608, 0, 0, 0, 0, 0, 0, 35184372088832, 70368744177664, 140737488355328, 17732923532771328, 17451448556060672, 16888498602639360, 15762598695796736, 13510798882111488, 9007199254740992, 0, 36028797018963968, 0, 0, 0, 0, 0, 2305843009213693952, 4611686018427387904, 9223372036854775808], [ 0, 70506452091906, 0, 0, 0, 0, 0, 141289400074368, 0, 0, 70506452091904, 0, 0, 0, 0, 141289400074240, 0, 0, 0, 70506452090880, 0, 0, 0, 141289400041472, 0, 0, 0, 0, 70506451566592, 0, 0, 141289391652864, 0, 0, 0, 0, 0, 70506183131136, 0, 141287244169216, 0, 0, 0, 0, 0, 0, 70368744177664, 140737488355328, 35747322042253312, 35465847065542656, 34902897112121344, 33776997205278720, 31525197391593472, 27021597764222976, 18014398509481984, 0, 0, 0, 0, 0, 0, 0, 4611686018427387904, 9223372036854775808], [ 282578800148737, 0, 0, 0, 0, 0, 0, 567382630219904, 282578800148736, 0, 0, 0, 0, 0, 567382630219776, 0, 282578800148480, 0, 0, 0, 0, 567382630203392, 0, 0, 282578800082944, 0, 0, 0, 567382628106240, 0, 0, 0, 282578783305728, 0, 0, 567382359670784, 0, 0, 0, 0, 282574488338432, 0, 567347999932416, 0, 0, 0, 0, 0, 281474976710656, 562949953421312, 0, 0, 0, 0, 0, 0, 0, 144115188075855872, 432345564227567616, 1008806316530991104, 2161727821137838080, 4467570830351532032, 9079256848778919936, 18302628885633695744], [ 0, 565157600297474, 0, 0, 0, 0, 0, 0, 0, 565157600297472, 0, 0, 0, 0, 0, 1134765260439552, 0, 565157600296960, 0, 0, 0, 0, 1134765260406784, 0, 0, 565157600165888, 0, 0, 0, 1134765256212480, 0, 0, 0, 565157566611456, 0, 0, 1134764719341568, 0, 0, 0, 0, 565148976676864, 0, 1134695999864832, 0, 0, 0, 0, 281474976710656, 562949953421312, 1125899906842624, 0, 0, 0, 0, 0, 72057594037927936, 0, 288230376151711744, 864691128455135232, 2017612633061982208, 4323455642275676160, 8935141660703064064, 18158513697557839872], [ 18158513697557839873, 0, 1130315200594948, 0, 0, 0, 0, 0, 0, 0, 1130315200594944, 0, 0, 0, 0, 0, 0, 0, 1130315200593920, 0, 0, 0, 0, 2269530520813568, 0, 0, 1130315200331776, 0, 0, 0, 2269530512424960, 0, 0, 0, 1130315133222912, 0, 0, 2269529438683136, 0, 0, 564049465049088, 0, 1130297953353728, 0, 2269391999729664, 0, 0, 0, 0, 562949953421312, 1125899906842624, 2251799813685248, 0, 0, 0, 0, 216172782113783808, 144115188075855872, 0, 576460752303423488, 1729382256910270464, 4035225266123964416, 8646911284551352320, 17870283321406128128], [ 17870283321406128129, 0, 0, 2260630401189896, 0, 0, 0, 0, 0, 0, 0, 2260630401189888, 0, 0, 0, 0, 0, 0, 0, 2260630401187840, 0, 0, 0, 0, 0, 0, 0, 2260630400663552, 0, 0, 0, 4539061024849920, 1128103225065472, 0, 0, 2260630266445824, 0, 0, 4539058877366272, 0, 0, 1128098930098176, 0, 2260595906707456, 0, 4538783999459328, 0, 0, 0, 0, 1125899906842624, 2251799813685248, 4503599627370496, 0, 0, 0, 504403158265495552, 432345564227567616, 288230376151711744, 0, 1152921504606846976, 3458764513820540928, 8070450532247928832, 17293822569102704640], [ 17293822569102704641, 0, 0, 0, 4521260802379792, 0, 0, 0, 0, 0, 0, 0, 4521260802379776, 0, 0, 0, 0, 0, 0, 0, 4521260802375680, 0, 0, 0, 2256206466908160, 0, 0, 0, 4521260801327104, 0, 0, 0, 0, 2256206450130944, 0, 0, 4521260532891648, 0, 0, 9078117754732544, 0, 0, 2256197860196352, 0, 4521191813414912, 0, 9077567998918656, 0, 0, 0, 0, 2251799813685248, 4503599627370496, 9007199254740992, 0, 0, 1080863910568919040, 1008806316530991104, 864691128455135232, 576460752303423488, 0, 2305843009213693952, 6917529027641081856, 16140901064495857664], [ 16140901064495857665, 0, 0, 0, 0, 9042521604759584, 0, 0, 0, 0, 0, 0, 0, 9042521604759552, 0, 0, 4512412933881856, 0, 0, 0, 0, 9042521604751360, 0, 0, 0, 4512412933816320, 0, 0, 0, 9042521602654208, 0, 0, 0, 0, 4512412900261888, 0, 0, 9042521065783296, 0, 0, 0, 0, 0, 4512395720392704, 0, 9042383626829824, 0, 18155135997837312, 0, 0, 0, 0, 4503599627370496, 9007199254740992, 18014398509481984, 0, 2233785415175766016, 2161727821137838080, 2017612633061982208, 1729382256910270464, 1152921504606846976, 0, 4611686018427387904, 13835058055282163712], [ 13835058055282163713, 0, 0, 0, 0, 0, 18085043209519168, 0, 9024825867763968, 0, 0, 0, 0, 0, 18085043209519104, 0, 0, 9024825867763712, 0, 0, 0, 0, 18085043209502720, 0, 0, 0, 9024825867632640, 0, 0, 0, 18085043205308416, 0, 0, 0, 0, 9024825800523776, 0, 0, 18085042131566592, 0, 0, 0, 0, 0, 9024791440785408, 0, 18084767253659648, 0, 0, 0, 0, 0, 0, 9007199254740992, 18014398509481984, 36028797018963968, 4539628424389459968, 4467570830351532032, 4323455642275676160, 4035225266123964416, 3458764513820540928, 2305843009213693952, 0, 9223372036854775808], [ 18049651735527937, 0, 0, 0, 0, 0, 0, 36170086419038336, 0, 18049651735527936, 0, 0, 0, 0, 0, 36170086419038208, 0, 0, 18049651735527424, 0, 0, 0, 0, 36170086419005440, 0, 0, 0, 18049651735265280, 0, 0, 0, 36170086410616832, 0, 0, 0, 0, 18049651601047552, 0, 0, 36170084263133184, 0, 0, 0, 0, 0, 18049582881570816, 0, 36169534507319296, 0, 0, 0, 0, 0, 0, 18014398509481984, 36028797018963968, 9151314442816847872, 9079256848778919936, 8935141660703064064, 8646911284551352320, 8070450532247928832, 6917529027641081856, 4611686018427387904, 0], ]; SQUARE_BBS = [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, 34359738368, 68719476736, 137438953472, 274877906944, 549755813888, 1099511627776, 2199023255552, 4398046511104, 8796093022208, 17592186044416, 35184372088832, 70368744177664, 140737488355328, 281474976710656, 562949953421312, 1125899906842624, 2251799813685248, 4503599627370496, 9007199254740992, 18014398509481984, 36028797018963968, 72057594037927936, 144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976, 2305843009213693952, 4611686018427387904, 9223372036854775808, ]; KING_ATTACKS = [ 770, 1797, 3594, 7188, 14376, 28752, 57504, 49216, 197123, 460039, 920078, 1840156, 3680312, 7360624, 14721248, 12599488, 50463488, 117769984, 235539968, 471079936, 942159872, 1884319744, 3768639488, 3225468928, 12918652928, 30149115904, 60298231808, 120596463616, 241192927232, 482385854464, 964771708928, 825720045568, 3307175149568, 7718173671424, 15436347342848, 30872694685696, 61745389371392, 123490778742784, 246981557485568, 211384331665408, 846636838289408, 1975852459884544, 3951704919769088, 7903409839538176, 15806819679076352, 31613639358152704, 63227278716305408, 54114388906344448, 216739030602088448, 505818229730443264, 1011636459460886528, 2023272918921773056, 4046545837843546112, 8093091675687092224, 16186183351374184448, 13853283560024178688, 144959613005987840, 362258295026614272, 724516590053228544, 1449033180106457088, 2898066360212914176, 5796132720425828352, 11592265440851656704, 4665729213955833856, ]; KNIGHT_ATTACKS = [ 132096, 329728, 659712, 1319424, 2638848, 5277696, 10489856, 4202496, 33816580, 84410376, 168886289, 337772578, 675545156, 1351090312, 2685403152, 1075839008, 8657044482, 21609056261, 43234889994, 86469779988, 172939559976, 345879119952, 687463207072, 275414786112, 2216203387392, 5531918402816, 11068131838464, 22136263676928, 44272527353856, 88545054707712, 175990581010432, 70506185244672, 567348067172352, 1416171111120896, 2833441750646784, 5666883501293568, 11333767002587136, 22667534005174272, 45053588738670592, 18049583422636032, 145241105196122112, 362539804446949376, 725361088165576704, 1450722176331153408, 2901444352662306816, 5802888705324613632, 11533718717099671552, 4620693356194824192, 288234782788157440, 576469569871282176, 1224997833292120064, 2449995666584240128, 4899991333168480256, 9799982666336960512, 1152939783987658752, 2305878468463689728, 1128098930098176, 2257297371824128, 4796069720358912, 9592139440717824, 19184278881435648, 38368557762871296, 4679521487814656, 9077567998918656, ]; WHITE_PAWN_ATTACKS = [ 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 10, 20, 40, 80, 160, 64, 512, 1280, 2560, 5120, 10240, 20480, 40960, 16384, 131072, 327680, 655360, 1310720, 2621440, 5242880, 10485760, 4194304, 33554432, 83886080, 167772160, 335544320, 671088640, 1342177280, 2684354560, 1073741824, 8589934592, 21474836480, 42949672960, 85899345920, 171798691840, 343597383680, 687194767360, 274877906944, 2199023255552, 5497558138880, 10995116277760, 21990232555520, 43980465111040, 87960930222080, 175921860444160, 70368744177664, 562949953421312, 1407374883553280, 2814749767106560, 5629499534213120, 11258999068426240, 22517998136852480, 45035996273704960, 18014398509481984, ]; BLACK_PAWN_ATTACKS = [ 512, 1280, 2560, 5120, 10240, 20480, 40960, 16384, 131072, 327680, 655360, 1310720, 2621440, 5242880, 10485760, 4194304, 33554432, 83886080, 167772160, 335544320, 671088640, 1342177280, 2684354560, 1073741824, 8589934592, 21474836480, 42949672960, 85899345920, 171798691840, 343597383680, 687194767360, 274877906944, 2199023255552, 5497558138880, 10995116277760, 21990232555520, 43980465111040, 87960930222080, 175921860444160, 70368744177664, 562949953421312, 1407374883553280, 2814749767106560, 5629499534213120, 11258999068426240, 22517998136852480, 45035996273704960, 18014398509481984, 144115188075855872, 360287970189639680, 720575940379279360, 1441151880758558720, 2882303761517117440, 5764607523034234880, 11529215046068469760, 4611686018427387904, 0, 0, 0, 0, 0, 0, 0, 0, ]; MAX_ULONG = 18446744073709551615; PieceNames:str = ['P', 'N', 'B', 'R', 'Q', 'K', 'P', 'N', 'B', 'R', 'Q', 'K', '_']; PieceColours:str = ['W', 'W', 'W', 'W', 'W', 'W', 'B', 'B', 'B', 'B', 'B', 'B', '_']; NO_SQUARE: int = 65; BP_STARTING_POSITIONS = 65280 WP_STARTING_POSITIONS = 71776119061217280; BK_STARTING_POSITION = 16; WK_STARTING_POSITION = 1152921504606846976; BN_STARTING_POSITIONS = 66; WN_STARTING_POSITIONS = 4755801206503243776; WR_STARTING_POSITIONS = 9295429630892703744; BR_STARTING_POSITIONS = 129; BB_STARTING_POSITIONS = 36; WB_STARTING_POSITIONS = 2594073385365405696; WQ_STARTING_POSITION = 576460752303423488; BQ_STARTING_POSITION = 8; RANK_1_BITBOARD = 18374686479671623680 RANK_2_BITBOARD = 71776119061217280 RANK_3_BITBOARD = 280375465082880 RANK_4_BITBOARD = 1095216660480 RANK_5_BITBOARD = 4278190080 RANK_6_BITBOARD = 16711680 RANK_7_BITBOARD = 65280 RANK_8_BITBOARD = 255 BISHOP_ATTACKS = [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 0, 256, 513, 1026, 2052, 4104, 8208, 16416, 0, 65536, 131328, 262657, 525314, 1050628, 2101256, 4202512, 0, 16777216, 33619968, 67240192, 134480385, 268960770, 537921540, 1075843080, 0, 4294967296, 8606711808, 17213489152, 34426978560, 68853957121, 137707914242, 275415828484, 0, 1099511627776, 2203318222848, 4406653222912, 8813306511360, 17626613022976, 35253226045953, 70506452091906, 0, 281474976710656, 564049465049088, 1128103225065472, 2256206466908160, 4512412933881856, 9024825867763968, 18049651735527937, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 8, 16, 32, 64, 128, 0, 516, 1032, 2064, 4128, 8256, 16512, 32768, 0, 132104, 264208, 528416, 1056832, 2113664, 4227072, 8388608, 0, 33818640, 67637280, 135274560, 270549120, 541097984, 1082130432, 2147483648, 0, 8657571872, 17315143744, 34630287488, 69260574720, 138521083904, 277025390592, 549755813888, 0, 2216338399296, 4432676798592, 8865353596928, 17730707128320, 35461397479424, 70918499991552, 140737488355328, 0, 567382630219904, 1134765260439552, 2269530520813568, 4539061024849920, 9078117754732544, 18155135997837312, 36028797018963968, 0, ], [ 0, 256, 66048, 16909312, 4328785920, 1108169199616, 283691315109888, 72624976668147712, 0, 65536, 16908288, 4328783872, 1108169195520, 283691315101696, 72624976668131328, 145249953336262656, 0, 16777216, 4328521728, 1108168671232, 283691314053120, 72624976666034176, 145249953332068352, 290499906664136704, 0, 4294967296, 1108101562368, 283691179835392, 72624976397598720, 145249952795197440, 290499905590394880, 580999811180789760, 0, 1099511627776, 283673999966208, 72624942037860352, 145249884075720704, 290499768151441408, 580999536302882816, 1161999072605765632, 0, 281474976710656, 72620543991349248, 145241087982698496, 290482175965396992, 580964351930793984, 1161928703861587968, 2323857407723175936, 0, 72057594037927936, 144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976, 2305843009213693952, 4611686018427387904, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 9241421688590303744, 36099303471055872, 141012904183808, 550831656960, 2151686144, 8404992, 32768, 0, 4620710844295151616, 9241421688590303232, 36099303471054848, 141012904181760, 550831652864, 2151677952, 8388608, 0, 2310355422147510272, 4620710844295020544, 9241421688590041088, 36099303470530560, 141012903133184, 550829555712, 2147483648, 0, 1155177711056977920, 2310355422113955840, 4620710844227911680, 9241421688455823360, 36099303202095104, 141012366262272, 549755813888, 0, 577588851233521664, 1155177702467043328, 2310355404934086656, 4620710809868173312, 9241421619736346624, 36099165763141632, 140737488355328, 0, 288793326105133056, 577586652210266112, 1155173304420532224, 2310346608841064448, 4620693217682128896, 9241386435364257792, 36028797018963968, 0, 144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976, 2305843009213693952, 4611686018427387904, 9223372036854775808, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], ]; ROOK_ATTACKS = [ [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 257, 514, 1028, 2056, 4112, 8224, 16448, 32896, 65793, 131586, 263172, 526344, 1052688, 2105376, 4210752, 8421504, 16843009, 33686018, 67372036, 134744072, 269488144, 538976288, 1077952576, 2155905152, 4311810305, 8623620610, 17247241220, 34494482440, 68988964880, 137977929760, 275955859520, 551911719040, 1103823438081, 2207646876162, 4415293752324, 8830587504648, 17661175009296, 35322350018592, 70644700037184, 141289400074368, 282578800148737, 565157600297474, 1130315200594948, 2260630401189896, 4521260802379792, 9042521604759584, 18085043209519168, 36170086419038336, ], [ 254, 252, 248, 240, 224, 192, 128, 0, 65024, 64512, 63488, 61440, 57344, 49152, 32768, 0, 16646144, 16515072, 16252928, 15728640, 14680064, 12582912, 8388608, 0, 4261412864, 4227858432, 4160749568, 4026531840, 3758096384, 3221225472, 2147483648, 0, 1090921693184, 1082331758592, 1065151889408, 1030792151040, 962072674304, 824633720832, 549755813888, 0, 279275953455104, 277076930199552, 272678883688448, 263882790666240, 246290604621824, 211106232532992, 140737488355328, 0, 71494644084506624, 70931694131085312, 69805794224242688, 67553994410557440, 63050394783186944, 54043195528445952, 36028797018963968, 0, 18302628885633695744, 18158513697557839872, 17870283321406128128, 17293822569102704640, 16140901064495857664, 13835058055282163712, 9223372036854775808, 0 ], [ 72340172838076672, 144680345676153344, 289360691352306688, 578721382704613376, 1157442765409226752, 2314885530818453504, 4629771061636907008, 9259542123273814016, 72340172838076416, 144680345676152832, 289360691352305664, 578721382704611328, 1157442765409222656, 2314885530818445312, 4629771061636890624, 9259542123273781248, 72340172838010880, 144680345676021760, 289360691352043520, 578721382704087040, 1157442765408174080, 2314885530816348160, 4629771061632696320, 9259542123265392640, 72340172821233664, 144680345642467328, 289360691284934656, 578721382569869312, 1157442765139738624, 2314885530279477248, 4629771060558954496, 9259542121117908992, 72340168526266368, 144680337052532736, 289360674105065472, 578721348210130944, 1157442696420261888, 2314885392840523776, 4629770785681047552, 9259541571362095104, 72339069014638592, 144678138029277184, 289356276058554368, 578712552117108736, 1157425104234217472, 2314850208468434944, 4629700416936869888, 9259400833873739776, 72057594037927936, 144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976, 2305843009213693952, 4611686018427387904, 9223372036854775808, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0, 1, 3, 7, 15, 31, 63, 127, 0, 256, 768, 1792, 3840, 7936, 16128, 32512, 0, 65536, 196608, 458752, 983040, 2031616, 4128768, 8323072, 0, 16777216, 50331648, 117440512, 251658240, 520093696, 1056964608, 2130706432, 0, 4294967296, 12884901888, 30064771072, 64424509440, 133143986176, 270582939648, 545460846592, 0, 1099511627776, 3298534883328, 7696581394432, 16492674416640, 34084860461056, 69269232549888, 139637976727552, 0, 281474976710656, 844424930131968, 1970324836974592, 4222124650659840, 8725724278030336, 17732923532771328, 35747322042253312, 0, 72057594037927936, 216172782113783808, 504403158265495552, 1080863910568919040, 2233785415175766016, 4539628424389459968, 9151314442816847872 ] ]; EMPTY_BITBOARD = 0; #endregion pieceArray = [0,0,0,0,0,0, 0,0,0,0,0,0]; whiteToPlay: bool = True; castleRights: bool = [True, True, True, True]; ep: int = NO_SQUARE; boardPly: int = 0; SQ_CHAR_Y = [ '8', '8', '8', '8', '8', '8', '8', '8', '7', '7', '7', '7', '7', '7', '7', '7', '6', '6', '6', '6', '6', '6', '6', '6', '5', '5', '5', '5', '5', '5', '5', '5', '4', '4', '4', '4', '4', '4', '4', '4', '3', '3', '3', '3', '3', '3', '3', '3', '2', '2', '2', '2', '2', '2', '2', '2', '1', '1', '1', '1', '1', '1', '1', '1', 'A', ] SQ_CHAR_X = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'N', ] def PrintMoveNoNL(starting: int, target_square: int, tag: int): #{ #starting if starting < 0 or starting > 63: #{ print(f"{starting}", end=""); #} else: #{ print(f"{SQ_CHAR_X[starting]}", end=""); print(f"{SQ_CHAR_Y[starting]}", end="") #} #target if target_square < 0 or target_square > 63: #{ print("%d", target_square) #} else: #{ print(f"{SQ_CHAR_X[target_square]}", end=""); print(f"{SQ_CHAR_Y[target_square]}", end=""); #} if tag == TAG_BCaptureKnightPromotion or tag == TAG_BKnightPromotion or tag == TAG_WKnightPromotion or tag == TAG_WCaptureKnightPromotion: #{ print("n", end="") #} elif tag == TAG_BCaptureRookPromotion or tag == TAG_BRookPromotion or tag == TAG_WRookPromotion or tag == TAG_WCaptureRookPromotion: #{ print("r", end="") #} elif tag == TAG_BCaptureBishopPromotion or tag == TAG_BBishopPromotion or tag == TAG_WBishopPromotion or tag == TAG_WCaptureBishopPromotion: #{ print("b", end="") #} elif tag == TAG_BCaptureQueenPromotion or tag == TAG_BQueenPromotion or tag == TAG_WQueenPromotion or tag == TAG_WCaptureQueenPromotion: #{ print("q", end="") #} #} #def getBishopMovesSeparate(startingSquare: int, occupancy: int) -> int: #{ #occupancy &= BISHOP_MASKS[startingSquare] # Apply the occupancy mask #occupancy *= BISHOP_MAGIC_NUMBERS[startingSquare] # Multiply by the magic number #occupancy = (occupancy >> (64 - BISHOP_REL_BITS[startingSquare])) & 0x1FF # Ensure it's a 9-bit result #return BISHOP_ATTACKS[startingSquare][occupancy] #} #def getRookMovesSeparate(startingSquare: int, occupancy: int) -> int: #{ #occupancy &= ROOK_MASKS[startingSquare] # Apply the occupancy mask #occupancy *= ROOK_MAGIC_NUMBERS[startingSquare] # Multiply by the magic number #occupancy = (occupancy >> (64 - ROOK_REL_BITS[startingSquare])) & 0xFFF # Ensure it's a 12-bit result #return ROOK_ATTACKS[startingSquare][occupancy] #} BISHOP_UP_LEFT = 0; BISHOP_UP_RIGHT = 1; BISHOP_DOWN_LEFT = 2; BISHOP_DOWN_RIGHT = 3; ROOK_UP = 0; ROOK_DOWN = 2; ROOK_LEFT = 3; ROOK_RIGHT = 1; def getRookMovesSeparate(square: int, combined_occ:int) -> int: #{ combinedAttacks = 0; rookAttackUp:int = ROOK_ATTACKS[ROOK_UP][square]; rookAndOccs = rookAttackUp & combined_occ; if (rookAndOccs != 0): #{ lastValue = rookAndOccs; for i in range(0, 8): #{ rookAndOccs = rookAndOccs & rookAndOccs - 1; if (rookAndOccs == 0): #{ endSquare:int = BitscanForward(lastValue); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; break; #} lastValue = rookAndOccs; #} #} else: #{ combinedAttacks |= rookAttackUp; #} rookAttackLeft = ROOK_ATTACKS[ROOK_LEFT][square]; rookAndOccs = rookAttackLeft & combined_occ; if (rookAndOccs != 0): #{ lastValue = rookAndOccs; for i in range(0, 8): #{ rookAndOccs = rookAndOccs & rookAndOccs - 1; if (rookAndOccs == 0): #{ endSquare:int = BitscanForward(lastValue); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; break; #} lastValue = rookAndOccs; #} #} else: #{ combinedAttacks |= rookAttackLeft; #} rookAttackDown = ROOK_ATTACKS[ROOK_DOWN][square]; rookAndOccs = rookAttackDown & combined_occ; if (rookAndOccs != 0): #{ endSquare = BitscanForward(rookAndOccs); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; #} else: #{ combinedAttacks |= rookAttackDown; #} rookAttackRight = ROOK_ATTACKS[ROOK_RIGHT][square]; rookAndOccs = rookAttackRight & combined_occ; if (rookAndOccs != 0): #{ endSquare = BitscanForward(rookAndOccs); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; #} else: #{ combinedAttacks |= rookAttackRight; #} return combinedAttacks; #} def getBishopMovesSeparate(square, combined_occ): #{ combinedAttacks = 0; bishopAttackUpLeft = BISHOP_ATTACKS[BISHOP_UP_LEFT][square]; bishopAndOccs = bishopAttackUpLeft & combined_occ; if (bishopAndOccs != 0): #{ lastValue = bishopAndOccs; for i in range(0, 8): #{ bishopAndOccs &= bishopAndOccs - 1; if (bishopAndOccs == 0): #{ endSquare = BitscanForward(lastValue); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; break; #} lastValue = bishopAndOccs; #} #} else: #{ combinedAttacks |= bishopAttackUpLeft; #} bishopAttackUpRight = BISHOP_ATTACKS[BISHOP_UP_RIGHT][square]; bishopAndOccs = bishopAttackUpRight & combined_occ; if (bishopAndOccs != 0): #{ lastValue = bishopAndOccs; for i in range(0, 8): #{ bishopAndOccs &= bishopAndOccs - 1; if (bishopAndOccs == 0): #{ endSquare:int = BitscanForward(lastValue); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; break; #} lastValue = bishopAndOccs; #} #} else: #{ combinedAttacks |= bishopAttackUpRight; #} bishopAttackDownLeft = BISHOP_ATTACKS[BISHOP_DOWN_LEFT][square]; bishopAndOccs = bishopAttackDownLeft & combined_occ; if (bishopAndOccs != 0): #{ endSquare = BitscanForward(bishopAndOccs); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; #} else: #{ combinedAttacks |= bishopAttackDownLeft; #} bishopAttackDownRight = BISHOP_ATTACKS[BISHOP_DOWN_RIGHT][square]; bishopAndOccs = bishopAttackDownRight & combined_occ; if (bishopAndOccs != 0): #{ endSquare = BitscanForward(bishopAndOccs); combinedAttacks |= INBETWEEN_BITBOARDS[square][endSquare]; #} else: #{ combinedAttacks |= bishopAttackDownRight; #} return combinedAttacks; #} def Is_Square_Attacked_By_Black(square: int, occupancy: int) -> bool: #{ if (pieceArray[BP] & WHITE_PAWN_ATTACKS[square]) != 0: #{ return True #} if (pieceArray[BN] & KNIGHT_ATTACKS[square]) != 0: #{ return True #} if (pieceArray[BK] & KING_ATTACKS[square]) != 0: #{ return True #} bishopAttacks: int = getBishopMovesSeparate(square, occupancy) if (pieceArray[BB] & bishopAttacks) != 0: #{ return True #} if (pieceArray[BQ] & bishopAttacks) != 0: #{ return True #} rookAttacks: int = getRookMovesSeparate(square, occupancy) if (pieceArray[BR] & rookAttacks) != 0: #{ return True #} if (pieceArray[BQ] & rookAttacks) != 0: #{ return True #} return False #} def Is_Square_Attacked_By_White(square: int, occupancy: int) -> bool: #{ if (pieceArray[WP] & BLACK_PAWN_ATTACKS[square]) != 0: #{ return True #} if (pieceArray[WN] & KNIGHT_ATTACKS[square]) != 0: #{ return True #} if (pieceArray[WK] & KING_ATTACKS[square]) != 0: #{ return True #} bishopAttacks: int = getBishopMovesSeparate(square, occupancy) if (pieceArray[WB] & bishopAttacks) != 0: #{ return True #} if (pieceArray[WQ] & bishopAttacks) != 0: #{ return True #} rookAttacks: int = getRookMovesSeparate(square, occupancy) if (pieceArray[WR] & rookAttacks) != 0: #{ return True #} if (pieceArray[WQ] & rookAttacks) != 0: #{ return True #} return False #} MAGIC: int = 0x03f79d71b4cb0a89 DEBRUIJN64: int = [ 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63, ]; def BitscanForward(tempBitboard: int) -> int: #{ result = MAGIC * (tempBitboard ^ (tempBitboard - 1)); index = (result & ((1 << 64) - 1)) >> 58; if index < 0 or index > 63: #{ print(f"error {index} out of range"); return -1; #} return DEBRUIJN64[index]; #} def SetStartingPosition(): #{ ep = NO_SQUARE; whiteToPlay = True; castleRights[0] = True; castleRights[1] = True; castleRights[2] = True; castleRights[3] = True; pieceArray[WP] = WP_STARTING_POSITIONS pieceArray[WN] = WN_STARTING_POSITIONS pieceArray[WB] = WB_STARTING_POSITIONS pieceArray[WR] = WR_STARTING_POSITIONS pieceArray[WQ] = WQ_STARTING_POSITION pieceArray[WK] = WK_STARTING_POSITION pieceArray[BP] = BP_STARTING_POSITIONS pieceArray[BN] = BN_STARTING_POSITIONS pieceArray[BB] = BB_STARTING_POSITIONS pieceArray[BR] = BR_STARTING_POSITIONS pieceArray[BQ] = BQ_STARTING_POSITION pieceArray[BK] = BK_STARTING_POSITION #} class Board: def __init__(self): self.piece_array = [0,0,0,0,0,0 ,0,0,0,0,0,0]; # Corresponds to pieceArray self.white_to_play = True # Corresponds to isWhite self.castle_rights = [True, True, True, True] # Corresponds to castleRights self.ep = NO_SQUARE def SetStartingPositionStruct(board:Board): #{ board.ep = NO_SQUARE; board.white_to_play = True; board.castle_rights[0] = True; board.castle_rights[1] = True; board.castle_rights[2] = True; board.castle_rights[3] = True; board.piece_array[WP] = WP_STARTING_POSITIONS; board.piece_array[WN] = WN_STARTING_POSITIONS; board.piece_array[WB] = WB_STARTING_POSITIONS; board.piece_array[WR] = WR_STARTING_POSITIONS; board.piece_array[WQ] = WQ_STARTING_POSITION; board.piece_array[WK] = WK_STARTING_POSITION; board.piece_array[BP] = BP_STARTING_POSITIONS; board.piece_array[BN] = BN_STARTING_POSITIONS; board.piece_array[BB] = BB_STARTING_POSITIONS; board.piece_array[BR] = BR_STARTING_POSITIONS; board.piece_array[BQ] = BQ_STARTING_POSITION; board.piece_array[BK] = BK_STARTING_POSITION; # def IsOccupied(bitboard: int, square: int) -> bool: #{ return (bitboard & SQUARE_BBS[square]) != 0 #} def GetOccupiedIndex(square: int) -> int: #{ for i in range(0, 12): #{ if IsOccupied(pieceArray[i], square): #{ return i; #} #} return EMPTY; #} def PrintBoard(): print("Board:"); boardArray = [0] * 64 for i in range(0, 64): boardArray[i] = GetOccupiedIndex(i); for rank in range(0, 8): #{ print(" ", end=""); for file in range(0, 8): #{ square: int = (rank * 8) + file; print(f"{PieceColours[boardArray[square]]}{PieceNames[boardArray[square]]} ", end=""); #} print(); #} print(); print(f"White to play: {whiteToPlay}"); print(f"Castle: {castleRights[0]} {castleRights[1]} {castleRights[2]} {castleRights[3]}"); print(f"ep: {ep}"); print(f"ply: {boardPly}"); print(); print(); #} def PerftInline(depth: int, ply: int) -> int: #{ global whiteToPlay; global ep; piece_array_local = [ pieceArray[0], pieceArray[1], pieceArray[2], pieceArray[3], pieceArray[4], pieceArray[5], pieceArray[6], pieceArray[7], pieceArray[8], pieceArray[9], pieceArray[10], pieceArray[11], ]; #if depth == 0: #{ # return 1; #} moveList = [[0] * 4 for _ in range(50)]; moveCount:int = 0; WHITE_OCCUPANCIES: int = piece_array_local[0] | piece_array_local[1] | piece_array_local[2] | piece_array_local[3] | piece_array_local[4] | piece_array_local[5]; BLACK_OCCUPANCIES: int = piece_array_local[6] | piece_array_local[7] | piece_array_local[8] | piece_array_local[9] | piece_array_local[10] | piece_array_local[11]; COMBINED_OCCUPANCIES: int = WHITE_OCCUPANCIES | BLACK_OCCUPANCIES; EMPTY_OCCUPANCIES: int = ~COMBINED_OCCUPANCIES tempBitboard: int; checkBitboard: int = 0; tempPinBitboard: int; tempAttack: int; tempEmpty: int; tempCaptures: int; startingSquare:int = NO_SQUARE; targetSquare:int= NO_SQUARE; pinArray = [[-1, -1] for _ in range(8)]; pinNumber:int = 0; #Generate Moves if whiteToPlay == True: #{ whiteKingCheckCount: int = 0 whiteKingPosition: int = BitscanForward(piece_array_local[WK]) #pawns tempBitboard = piece_array_local[BP] & WHITE_PAWN_ATTACKS[whiteKingPosition] if tempBitboard != 0: #{ pawn_square: int = BitscanForward(tempBitboard); checkBitboard = EMPTY_BITBOARD << pawn_square whiteKingCheckCount+=1; #} #knights tempBitboard = piece_array_local[BN] & KNIGHT_ATTACKS[whiteKingPosition] if tempBitboard != 0: #{ knight_square: int = BitscanForward(tempBitboard); checkBitboard = SQUARE_BBS[knight_square] whiteKingCheckCount += 1; #} #bishops bishopAttacksChecks: int = getBishopMovesSeparate(whiteKingPosition, BLACK_OCCUPANCIES) tempBitboard = piece_array_local[BB] & bishopAttacksChecks while tempBitboard != 0: #{ piece_square: int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] whiteKingCheckCount += 1; #} else: #{ pinned_square: int = BitscanForward(tempPinBitboard) tempPinBitboard &= tempPinBitboard - 1 if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber += 1; #} #} tempBitboard &= tempBitboard - 1; #} #queen tempBitboard = piece_array_local[BQ] & bishopAttacksChecks; while tempBitboard != 0: #{ piece_square: int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES; if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] whiteKingCheckCount += 1; #} else: #{ pinned_square: int = BitscanForward(tempPinBitboard) tempPinBitboard &= tempPinBitboard - 1 if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square pinNumber+=1; #} #} tempBitboard &= tempBitboard - 1 #} #rook rook_attacks: int = getRookMovesSeparate(whiteKingPosition, BLACK_OCCUPANCIES); tempBitboard = piece_array_local[BR] & rook_attacks; while tempBitboard != 0: #{ piece_square: int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES; if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; whiteKingCheckCount += 1; #} else: #{ pinned_square: int = BitscanForward(tempPinBitboard); tempPinBitboard &= tempPinBitboard - 1; if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square; pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square; pinNumber += 1; #} #} tempBitboard &= tempBitboard - 1; #} #queen tempBitboard = piece_array_local[BQ] & rook_attacks; while tempBitboard != 0: #{ piece_square: int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES; if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][piece_square]; whiteKingCheckCount+=1; #} else: #{ pinned_square: int = BitscanForward(tempPinBitboard); tempPinBitboard &= tempPinBitboard - 1 if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square pinNumber+=1; #} #} tempBitboard &= tempBitboard - 1 #} #If double check if whiteKingCheckCount > 1: #{ occupanciesWithoutWhiteKing: int = COMBINED_OCCUPANCIES & (~piece_array_local[WK]) tempAttack = KING_ATTACKS[whiteKingPosition] tempEmpty = tempAttack & EMPTY_OCCUPANCIES while tempEmpty != 0: #{ targetSquare = BitscanForward(tempEmpty) tempEmpty &= tempEmpty - 1 if (piece_array_local[BP] & WHITE_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} bishopAttacks: int = getBishopMovesSeparate(targetSquare, occupanciesWithoutWhiteKing) if (piece_array_local[BB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & bishopAttacks) != 0: #{ continue #} rookAttacks: int = getRookMovesSeparate(targetSquare, occupanciesWithoutWhiteKing) if (piece_array_local[BR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = whiteKingPosition; moveList[moveCount][MOVE_TARGET] = targetSquare; moveList[moveCount][MOVE_TAG] = TAG_NONE; moveList[moveCount][MOVE_PIECE] = WK; moveCount+= 1; #} #captures tempCaptures = tempAttack & BLACK_OCCUPANCIES; while tempCaptures != 0: #{ targetSquare = BitscanForward(tempCaptures); tempCaptures &= tempCaptures - 1; if (piece_array_local[BP] & WHITE_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} bishopAttacks: int = getBishopMovesSeparate(targetSquare, occupanciesWithoutWhiteKing) if (piece_array_local[BB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & bishopAttacks) != 0: #{ continue #} rookAttacks: int = getRookMovesSeparate(targetSquare, occupanciesWithoutWhiteKing) if (piece_array_local[BR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = whiteKingPosition; moveList[moveCount][MOVE_TARGET] = targetSquare; moveList[moveCount][MOVE_TAG] = TAG_CAPTURE; moveList[moveCount][MOVE_PIECE] = WK; moveCount+= 1; #} #} else: #{ if whiteKingCheckCount == 0: #{ checkBitboard = MAX_ULONG; #} occupanciesWithoutWhiteKing: int = COMBINED_OCCUPANCIES & (~piece_array_local[WK]); tempAttack = KING_ATTACKS[whiteKingPosition]; tempEmpty = tempAttack & EMPTY_OCCUPANCIES; while tempEmpty != 0: #{ targetSquare = BitscanForward(tempEmpty); tempEmpty &= tempEmpty - 1; if (piece_array_local[BP] & WHITE_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} bishopAttacks: int = getBishopMovesSeparate(targetSquare, occupanciesWithoutWhiteKing); if (piece_array_local[BB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & bishopAttacks) != 0: #{ continue #} rookAttacks: int = getRookMovesSeparate(targetSquare, occupanciesWithoutWhiteKing); if (piece_array_local[BR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = whiteKingPosition moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = WK moveCount+=1; #} #captures tempCaptures = tempAttack & BLACK_OCCUPANCIES; while tempCaptures != 0: #{ targetSquare = BitscanForward(tempCaptures) tempCaptures &= tempCaptures - 1 if (piece_array_local[BP] & WHITE_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[BK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} bishopAttacks: int = getBishopMovesSeparate(targetSquare, occupanciesWithoutWhiteKing); if (piece_array_local[BB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & bishopAttacks) != 0: #{ continue #} rookAttacks: int = getRookMovesSeparate(targetSquare, occupanciesWithoutWhiteKing); if (piece_array_local[BR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[BQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = whiteKingPosition; moveList[moveCount][MOVE_TARGET] = targetSquare; moveList[moveCount][MOVE_TAG] = TAG_CAPTURE; moveList[moveCount][MOVE_PIECE] = WK; moveCount+=1; #} if whiteKingCheckCount == 0: #{ if castleRights[WKS_CASTLE_RIGHTS] == True: #{ if whiteKingPosition == E1: #{ #king on e1 if (WKS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES) == 0: #{ #f1 and g1 empty if (piece_array_local[WR] & SQUARE_BBS[H1]) != 0: #{ #rook on h1 if Is_Square_Attacked_By_Black(F1, COMBINED_OCCUPANCIES) == False: #{ if Is_Square_Attacked_By_Black(G1, COMBINED_OCCUPANCIES) == False: #{ moveList[moveCount][MOVE_STARTING] = E1; moveList[moveCount][MOVE_TARGET] = G1; moveList[moveCount][MOVE_TAG] = TAG_WCASTLEKS; moveList[moveCount][MOVE_PIECE] = WK; moveCount+=1; #} #} #} #} #} #} if castleRights[WQS_CASTLE_RIGHTS] == True: #{ if whiteKingPosition == E1: #{ #king on e1 if (WQS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES) == 0: #{ #f1 and g1 empty if (piece_array_local[WR] & SQUARE_BBS[A1]) != 0: #{ #rook on h1 if Is_Square_Attacked_By_Black(C1, COMBINED_OCCUPANCIES) == False: #{ if Is_Square_Attacked_By_Black(D1, COMBINED_OCCUPANCIES) == False: #{ moveList[moveCount][MOVE_STARTING] = E1; moveList[moveCount][MOVE_TARGET] = C1; moveList[moveCount][MOVE_TAG] = TAG_WCASTLEQS; moveList[moveCount][MOVE_PIECE] = WK; moveCount+=1; #} #} #} #} #} #} #} tempBitboard = piece_array_local[WN]; while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1; #removes the knight from that square to not infinitely loop tempPinBitboard = MAX_ULONG; if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} tempAttack = ((KNIGHT_ATTACKS[startingSquare] & BLACK_OCCUPANCIES) & checkBitboard) & tempPinBitboard #gets knight captures while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = WN moveCount+=1; #} tempAttack = ((KNIGHT_ATTACKS[startingSquare] & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = WN moveCount+=1; #} #} tempBitboard = piece_array_local[WP] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1; tempPinBitboard = MAX_ULONG; if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; #} #} #} if (SQUARE_BBS[startingSquare-8] & COMBINED_OCCUPANCIES) == 0: #{ #if up one square is empty if ((SQUARE_BBS[startingSquare-8] & checkBitboard) & tempPinBitboard) != 0: #{ if (SQUARE_BBS[startingSquare] & RANK_7_BITBOARD) != 0: #{ #if promotion moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare - 8 moveList[moveCount][MOVE_TAG] = TAG_WQueenPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare - 8 moveList[moveCount][MOVE_TAG] = TAG_WRookPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare - 8 moveList[moveCount][MOVE_TAG] = TAG_WBishopPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare - 8 moveList[moveCount][MOVE_TAG] = TAG_WKnightPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} else: #{ moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare - 8 moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} #} if (SQUARE_BBS[startingSquare] & RANK_2_BITBOARD) != 0: #{ #if on rank 2 if ((SQUARE_BBS[startingSquare-16] & checkBitboard) & tempPinBitboard) != 0: #{ #if not pinned or if ((SQUARE_BBS[startingSquare-16]) & COMBINED_OCCUPANCIES) == 0: #{ #if up two squares and one square are empty moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare - 16 moveList[moveCount][MOVE_TAG] = TAG_DoublePawnWhite moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} #} #} #} tempAttack = ((WHITE_PAWN_ATTACKS[startingSquare] & BLACK_OCCUPANCIES) & checkBitboard) & tempPinBitboard #if black piece diagonal to pawn while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 if (SQUARE_BBS[startingSquare] & RANK_7_BITBOARD) != 0: #{ #if promotion moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_WCaptureQueenPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_WCaptureRookPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_WCaptureBishopPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_WCaptureKnightPromotion moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} else: #{ moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} #} if (SQUARE_BBS[startingSquare] & RANK_5_BITBOARD) != 0: #{ #check rank for ep if ep != NO_SQUARE: #{ if (((WHITE_PAWN_ATTACKS[startingSquare] & SQUARE_BBS[ep]) & checkBitboard) & tempPinBitboard) != 0: #{ if (piece_array_local[WK] & RANK_5_BITBOARD) == 0: #{ #if no king on rank 5 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = int(ep) moveList[moveCount][MOVE_TAG] = TAG_WHITEEP moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} elif (piece_array_local[BR]&RANK_5_BITBOARD) == 0 and (piece_array_local[BQ]&RANK_5_BITBOARD) == 0: #{ # if no b rook or queen on rank 5 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = int(ep) moveList[moveCount][MOVE_TAG] = TAG_WHITEEP moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} else: #{ #wk and br or bq on rank 5 occupancyWithoutEPPawns: int = COMBINED_OCCUPANCIES & ~SQUARE_BBS[startingSquare] occupancyWithoutEPPawns &= ~SQUARE_BBS[ep+8] rookAttacksFromKing: int = getRookMovesSeparate(whiteKingPosition, occupancyWithoutEPPawns); if (rookAttacksFromKing & piece_array_local[BR]) == 0: #{ if (rookAttacksFromKing & piece_array_local[BQ]) == 0: #{ moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = int(ep) moveList[moveCount][MOVE_TAG] = TAG_WHITEEP moveList[moveCount][MOVE_PIECE] = WP moveCount+=1; #} #} #} #} #} #} #} tempBitboard = piece_array_local[WR] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} rookAttacks = getRookMovesSeparate(startingSquare, COMBINED_OCCUPANCIES); tempAttack = ((rookAttacks & BLACK_OCCUPANCIES) & checkBitboard) & tempPinBitboard; while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = WR moveCount+=1; #} tempAttack = ((rookAttacks & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = WR moveCount+=1; #} #} tempBitboard = piece_array_local[WB] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} bishopAttacks = getBishopMovesSeparate(startingSquare, COMBINED_OCCUPANCIES); tempAttack = ((bishopAttacks & BLACK_OCCUPANCIES) & checkBitboard) & tempPinBitboard; while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = WB moveCount+=1; #} tempAttack = ((bishopAttacks & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = WB moveCount+=1; #} #} tempBitboard = piece_array_local[WQ] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]]; #} #} #} queenAttacks = getRookMovesSeparate(startingSquare, COMBINED_OCCUPANCIES); queenAttacks |= getBishopMovesSeparate(startingSquare, COMBINED_OCCUPANCIES); tempAttack = ((queenAttacks & BLACK_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = WQ moveCount+=1; #} tempAttack = ((queenAttacks & EMPTY_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = WQ moveCount+=1; #} #} #} #} else: #{ #black move blackKingCheckCount: int = 0 blackKingPosition: int = BitscanForward(piece_array_local[BK]); #pawns tempBitboard = piece_array_local[WP] & BLACK_PAWN_ATTACKS[blackKingPosition] if tempBitboard != 0: #{ pawn_square:int = BitscanForward(tempBitboard); checkBitboard = SQUARE_BBS[pawn_square]; blackKingCheckCount+=1; #} #knights tempBitboard = piece_array_local[WN] & KNIGHT_ATTACKS[blackKingPosition] if tempBitboard != 0: #{ knight_square: int = BitscanForward(tempBitboard); checkBitboard = SQUARE_BBS[knight_square] blackKingCheckCount+=1; #} #bishops bishopAttacksChecks: int = getBishopMovesSeparate(blackKingPosition, WHITE_OCCUPANCIES) tempBitboard = piece_array_local[WB] & bishopAttacksChecks; while tempBitboard != 0: #{ piece_square: int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; blackKingCheckCount+=1; #} else: #{ pinned_square: int = BitscanForward(tempPinBitboard) tempPinBitboard &= tempPinBitboard - 1 if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square pinNumber+=1; #} #} tempBitboard &= tempBitboard - 1 #} #queen tempBitboard = piece_array_local[WQ] & bishopAttacksChecks while tempBitboard != 0: #{ piece_square:int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square]; blackKingCheckCount+=1; #} else: #{ pinned_square: int = BitscanForward(tempPinBitboard) tempPinBitboard &= tempPinBitboard - 1; if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square pinNumber+=1; #} #} tempBitboard &= tempBitboard - 1 #} #rook rook_attacks:int = getRookMovesSeparate(blackKingPosition, WHITE_OCCUPANCIES) tempBitboard = piece_array_local[WR] & rook_attacks while tempBitboard != 0: #{ piece_square:int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] blackKingCheckCount+=1 #} else: #{ pinned_square:int = BitscanForward(tempPinBitboard) tempPinBitboard &= tempPinBitboard - 1 if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square pinNumber+=1; #} #} tempBitboard &= tempBitboard - 1 #} #queen tempBitboard = piece_array_local[WQ] & rook_attacks while tempBitboard != 0: #{ piece_square:int = BitscanForward(tempBitboard); tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES if tempPinBitboard == 0: #{ checkBitboard = INBETWEEN_BITBOARDS[blackKingPosition][piece_square] blackKingCheckCount+=1; #} else: #{ pinned_square:int = BitscanForward(tempPinBitboard) tempPinBitboard &= tempPinBitboard - 1 if tempPinBitboard == 0: #{ pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square pinNumber+=1; #} #} tempBitboard &= tempBitboard - 1 #} if blackKingCheckCount > 1: #{ occupancyWithoutBlackKing: int = COMBINED_OCCUPANCIES & (~piece_array_local[BK]) tempAttack = KING_ATTACKS[blackKingPosition] & WHITE_OCCUPANCIES; while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1; if (piece_array_local[WP] & BLACK_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} bishopAttacks:int = getBishopMovesSeparate(targetSquare, occupancyWithoutBlackKing); if (piece_array_local[WB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & bishopAttacks) != 0: #{ continue #} rookAttacks = getRookMovesSeparate(targetSquare, occupancyWithoutBlackKing); if (piece_array_local[WR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BK moveCount+=1; #} tempAttack = KING_ATTACKS[blackKingPosition] & ~COMBINED_OCCUPANCIES while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1; if (piece_array_local[WP] & WHITE_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} bishopAttacks:int = getBishopMovesSeparate(targetSquare, occupancyWithoutBlackKing) if (piece_array_local[WB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & bishopAttacks) != 0: #{ continue #} rookAttacks:int = getRookMovesSeparate(targetSquare, occupancyWithoutBlackKing); if (piece_array_local[WR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BK moveCount+=1; #} #} else: #{ if blackKingCheckCount == 0: #{ checkBitboard = MAX_ULONG #} tempBitboard = piece_array_local[BP] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} if (SQUARE_BBS[startingSquare+8] & COMBINED_OCCUPANCIES) == 0: #{ #if up one square is empty if ((SQUARE_BBS[startingSquare+8] & checkBitboard) & tempPinBitboard) != 0: #{ if (SQUARE_BBS[startingSquare] & RANK_2_BITBOARD) != 0: #{ #if promotion moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare + 8 moveList[moveCount][MOVE_TAG] = TAG_BBishopPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare + 8 moveList[moveCount][MOVE_TAG] = TAG_BKnightPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare + 8 moveList[moveCount][MOVE_TAG] = TAG_BRookPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare + 8 moveList[moveCount][MOVE_TAG] = TAG_BQueenPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; #} else: #{ moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare + 8 moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; #} #} if (SQUARE_BBS[startingSquare] & RANK_7_BITBOARD) != 0: #{ #if on rank 2 if ((SQUARE_BBS[startingSquare+16] & checkBitboard) & tempPinBitboard) != 0: #{ if ((SQUARE_BBS[startingSquare+16]) & COMBINED_OCCUPANCIES) == 0: #{ #if up two squares and one square are empty moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = startingSquare + 16 moveList[moveCount][MOVE_TAG] = TAG_DoublePawnBlack moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; #} #} #} #} tempAttack = ((BLACK_PAWN_ATTACKS[startingSquare] & WHITE_OCCUPANCIES) & checkBitboard) & tempPinBitboard #if black piece diagonal to pawn while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); #find the bit tempAttack &= tempAttack - 1 if (SQUARE_BBS[startingSquare] & RANK_2_BITBOARD) != 0: #{ #if promotion moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_BCaptureQueenPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_BCaptureRookPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_BCaptureKnightPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_BCaptureBishopPromotion moveList[moveCount][MOVE_PIECE] = BP moveCount+=1 #} else: #{ moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BP moveCount+=1 #} #} if (SQUARE_BBS[startingSquare] & RANK_4_BITBOARD) != 0: #{ #check rank for ep if ep != NO_SQUARE: #{ if (((BLACK_PAWN_ATTACKS[startingSquare] & SQUARE_BBS[ep]) & checkBitboard) & tempPinBitboard) != 0: #{ if (piece_array_local[BK] & RANK_4_BITBOARD) == 0: #{ #if no king on rank 5 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = int(ep) moveList[moveCount][MOVE_TAG] = TAG_BLACKEP moveList[moveCount][MOVE_PIECE] = BP moveCount+=1 #} elif (piece_array_local[WR]&RANK_4_BITBOARD) == 0 and (piece_array_local[WQ]&RANK_4_BITBOARD) == 0: #{ # if no b rook or queen on rank 5 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = int(ep) moveList[moveCount][MOVE_TAG] = TAG_BLACKEP moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; #} else: #{ #wk and br or bq on rank 5 occupancyWithoutEPPawns = COMBINED_OCCUPANCIES & ~SQUARE_BBS[startingSquare] occupancyWithoutEPPawns &= ~SQUARE_BBS[ep-8] rookAttacksFromKing = getRookMovesSeparate(blackKingPosition, occupancyWithoutEPPawns) if (rookAttacksFromKing & piece_array_local[WR]) == 0: #{ if (rookAttacksFromKing & piece_array_local[WQ]) == 0: #{ moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = int(ep) moveList[moveCount][MOVE_TAG] = TAG_BLACKEP moveList[moveCount][MOVE_PIECE] = BP moveCount+=1; #} #} #} #} #} #} #} tempBitboard = piece_array_local[BN] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); #looks for the startingSquare tempBitboard &= tempBitboard - 1 #removes the knight from that square to not infinitely loop tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0,pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} tempAttack = ((KNIGHT_ATTACKS[startingSquare] & WHITE_OCCUPANCIES) & checkBitboard) & tempPinBitboard #gets knight captures while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BN moveCount+=1 #} tempAttack = ((KNIGHT_ATTACKS[startingSquare] & (~COMBINED_OCCUPANCIES)) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BN moveCount+=1 #} #} tempBitboard = piece_array_local[BB] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} bishopAttacks = getBishopMovesSeparate(startingSquare, COMBINED_OCCUPANCIES) tempAttack = ((bishopAttacks & WHITE_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BB moveCount+=1; #} tempAttack = ((bishopAttacks & (~COMBINED_OCCUPANCIES)) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BB moveCount+=1; #} #} tempBitboard = piece_array_local[BR] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} rookAttacks = getRookMovesSeparate(startingSquare, COMBINED_OCCUPANCIES) tempAttack = ((rookAttacks & WHITE_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BR moveCount+=1; #} tempAttack = ((rookAttacks & (~COMBINED_OCCUPANCIES)) & checkBitboard) & tempPinBitboard; while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BR moveCount+=1; #} #} tempBitboard = piece_array_local[BQ] while tempBitboard != 0: #{ startingSquare = BitscanForward(tempBitboard); tempBitboard &= tempBitboard - 1 tempPinBitboard = MAX_ULONG if pinNumber != 0: #{ for i in range(0, pinNumber): #{ if pinArray[i][PINNED_SQUARE_INDEX] == startingSquare: #{ tempPinBitboard = INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]] #} #} #} queenAttacks = getRookMovesSeparate(startingSquare, COMBINED_OCCUPANCIES) queenAttacks |= getBishopMovesSeparate(startingSquare, COMBINED_OCCUPANCIES) tempAttack = ((queenAttacks & WHITE_OCCUPANCIES) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BQ moveCount+=1; #} tempAttack = ((queenAttacks & (~COMBINED_OCCUPANCIES)) & checkBitboard) & tempPinBitboard while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 moveList[moveCount][MOVE_STARTING] = startingSquare moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BQ moveCount+=1; #} #} tempAttack = KING_ATTACKS[blackKingPosition] & WHITE_OCCUPANCIES #gets knight captures while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 if (piece_array_local[WP] & BLACK_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} occupancyWithoutBlackKing = COMBINED_OCCUPANCIES & (~piece_array_local[BK]) bishopAttacks = getBishopMovesSeparate(targetSquare, occupancyWithoutBlackKing) if (piece_array_local[WB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & bishopAttacks) != 0: #{ continue #} rookAttacks = getRookMovesSeparate(targetSquare, occupancyWithoutBlackKing) if (piece_array_local[WR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = blackKingPosition moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_CAPTURE moveList[moveCount][MOVE_PIECE] = BK moveCount+=1; #} tempAttack = KING_ATTACKS[blackKingPosition] & (~COMBINED_OCCUPANCIES) #get knight moves to emtpy squares while tempAttack != 0: #{ targetSquare = BitscanForward(tempAttack); tempAttack &= tempAttack - 1 if (piece_array_local[WP] & BLACK_PAWN_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WN] & KNIGHT_ATTACKS[targetSquare]) != 0: #{ continue #} if (piece_array_local[WK] & KING_ATTACKS[targetSquare]) != 0: #{ continue #} occupancyWithoutBlackKing: int = COMBINED_OCCUPANCIES & (~piece_array_local[BK]) bishopAttacks = getBishopMovesSeparate(targetSquare, occupancyWithoutBlackKing) if (piece_array_local[WB] & bishopAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & bishopAttacks) != 0: #{ continue #} rookAttacks = getRookMovesSeparate(targetSquare, occupancyWithoutBlackKing) if (piece_array_local[WR] & rookAttacks) != 0: #{ continue #} if (piece_array_local[WQ] & rookAttacks) != 0: #{ continue #} moveList[moveCount][MOVE_STARTING] = blackKingPosition moveList[moveCount][MOVE_TARGET] = targetSquare moveList[moveCount][MOVE_TAG] = TAG_NONE moveList[moveCount][MOVE_PIECE] = BK moveCount+=1; #} #} if blackKingCheckCount == 0: #{ if castleRights[BKS_CASTLE_RIGHTS] == True: #{ if blackKingPosition == E8: #{ #king on e1 if (BKS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES) == 0: #{ #f1 and g1 empty if (piece_array_local[BR] & SQUARE_BBS[H8]) != 0: #{ #rook on h1 if Is_Square_Attacked_By_White(F8, COMBINED_OCCUPANCIES) == False: #{ if Is_Square_Attacked_By_White(G8, COMBINED_OCCUPANCIES) == False: #{ moveList[moveCount][MOVE_STARTING] = E8 moveList[moveCount][MOVE_TARGET] = G8 moveList[moveCount][MOVE_TAG] = TAG_BCASTLEKS moveList[moveCount][MOVE_PIECE] = BK moveCount+=1; #} #} #} #} #} #} if castleRights[BQS_CASTLE_RIGHTS] == True: #{ if blackKingPosition == E8: #{ #king on e1 if (BQS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES) == 0: #{ #f1 and g1 empty if (piece_array_local[BR] & SQUARE_BBS[A8]) != 0: #{ #rook on h1 if Is_Square_Attacked_By_White(C8, COMBINED_OCCUPANCIES) == False: #{ if Is_Square_Attacked_By_White(D8, COMBINED_OCCUPANCIES) == False: #{ moveList[moveCount][MOVE_STARTING] = E8 moveList[moveCount][MOVE_TARGET] = C8 moveList[moveCount][MOVE_TAG] = TAG_BCASTLEQS moveList[moveCount][MOVE_PIECE] = BK moveCount+=1; #} #} #} #} #} #} #} #} if depth == 1: #{ return moveCount ##} nodes:int = 0 priorNodes:int copyEp:int = ep copyCastle:bool = [castleRights[0], castleRights[1], castleRights[2], castleRights[3]] for moveIndex in range(0, moveCount): #{ startingSquare:int = moveList[moveIndex][MOVE_STARTING] targetSquare:int = moveList[moveIndex][MOVE_TARGET] piece:int = moveList[moveIndex][MOVE_PIECE] tag:int = moveList[moveIndex][MOVE_TAG] captureIndex: int = -1 whiteToPlay = not whiteToPlay match tag: #{ case 0: #none pieceArray[piece] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 26: #check pieceArray[piece] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 1: #capture pieceArray[piece] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] if piece >= WP and piece <= WK: #{ for i in range(BP, BK + 1): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] #} else: #{ #is black for i in range(WP, BP): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] #} ep = NO_SQUARE case 27: #check cap pieceArray[piece] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] if piece >= 0 and piece <= WK: #{ for i in range(BP, BK + 1): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] #} else: #{ #is black for i in range(WP, BP): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] #} ep = NO_SQUARE case 2: #white ep #move piece pieceArray[WP] |= SQUARE_BBS[targetSquare] pieceArray[WP] &= ~SQUARE_BBS[startingSquare] #remove pieceArray[BP] &= ~SQUARE_BBS[targetSquare+8] ep = NO_SQUARE case 3: #black ep #move piece pieceArray[BP] |= SQUARE_BBS[targetSquare] pieceArray[BP] &= ~SQUARE_BBS[startingSquare] #remove white pawn square up pieceArray[WP] &= ~SQUARE_BBS[targetSquare-8] ep = NO_SQUARE case 4: #WKS #white king pieceArray[WK] |= SQUARE_BBS[G1] pieceArray[WK] &= ~SQUARE_BBS[E1] #white rook pieceArray[WR] |= SQUARE_BBS[F1] pieceArray[WR] &= ~SQUARE_BBS[H1] #occupancies castleRights[WKS_CASTLE_RIGHTS] = False castleRights[WQS_CASTLE_RIGHTS] = False ep = NO_SQUARE case 5: #WQS #white king pieceArray[WK] |= SQUARE_BBS[C1] pieceArray[WK] &= ~SQUARE_BBS[E1] #white rook pieceArray[WR] |= SQUARE_BBS[D1] pieceArray[WR] &= ~SQUARE_BBS[A1] castleRights[WKS_CASTLE_RIGHTS] = False castleRights[WQS_CASTLE_RIGHTS] = False ep = NO_SQUARE case 6: #BKS #white king pieceArray[BK] |= SQUARE_BBS[G8] pieceArray[BK] &= ~SQUARE_BBS[E8] #white rook pieceArray[BR] |= SQUARE_BBS[F8] pieceArray[BR] &= ~SQUARE_BBS[H8] castleRights[BKS_CASTLE_RIGHTS] = False castleRights[BQS_CASTLE_RIGHTS] = False ep = NO_SQUARE case 7: #BQS #white king pieceArray[BK] |= SQUARE_BBS[C8] pieceArray[BK] &= ~SQUARE_BBS[E8] #white rook pieceArray[BR] |= SQUARE_BBS[D8] pieceArray[BR] &= ~SQUARE_BBS[A8] castleRights[BKS_CASTLE_RIGHTS] = False castleRights[BQS_CASTLE_RIGHTS] = False ep = NO_SQUARE case 8: #BNPr pieceArray[BN] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 9: #BBPr pieceArray[BB] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 10: #BQPr pieceArray[BQ] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 11: #BRPr pieceArray[BR] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 12: #WNPr pieceArray[WN] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 13: #WBPr pieceArray[WB] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 14: #WQPr pieceArray[WQ] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 15: #WRPr pieceArray[WR] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE case 16: #BNPrCAP pieceArray[BN] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(WP, BP): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 17: #BBPrCAP pieceArray[BB] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(WP, BP): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 18: #BQPrCAP pieceArray[BQ] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(WP, BP): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 19: #BRPrCAP pieceArray[BR] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(WP, BP): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 20: #WNPrCAP pieceArray[WN] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(BP, BK + 1): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 21: #WBPrCAP pieceArray[WB] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(BP, BK + 1): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 22: #WQPrCAP pieceArray[WQ] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(BP, BK + 1): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 23: #WRPrCAP pieceArray[WR] |= SQUARE_BBS[targetSquare] pieceArray[piece] &= ~SQUARE_BBS[startingSquare] ep = NO_SQUARE for i in range(BP, BK + 1): #{ if (pieceArray[i] & SQUARE_BBS[targetSquare]) != 0: #{ captureIndex = i break #} #} pieceArray[captureIndex] &= ~SQUARE_BBS[targetSquare] case 24: #WDouble pieceArray[WP] |= SQUARE_BBS[targetSquare] pieceArray[WP] &= ~SQUARE_BBS[startingSquare] ep = targetSquare + 8 case 25: #BDouble pieceArray[BP] |= SQUARE_BBS[targetSquare] pieceArray[BP] &= ~SQUARE_BBS[startingSquare] ep = targetSquare - 8 #} if piece == WK: #{ castleRights[WKS_CASTLE_RIGHTS] = False castleRights[WQS_CASTLE_RIGHTS] = False #} elif piece == BK: #{ castleRights[BKS_CASTLE_RIGHTS] = False castleRights[BQS_CASTLE_RIGHTS] = False #} elif piece == WR: #{ if castleRights[WKS_CASTLE_RIGHTS] == True: #{ if (pieceArray[WR] & SQUARE_BBS[H1]) == 0: #{ castleRights[WKS_CASTLE_RIGHTS] = False #} #} if castleRights[WQS_CASTLE_RIGHTS] == True: #{ if (pieceArray[WR] & SQUARE_BBS[A1]) == 0: #{ castleRights[WQS_CASTLE_RIGHTS] = False #} #} #} elif piece == BR: #{ if castleRights[BKS_CASTLE_RIGHTS] == True: #{ if (pieceArray[BR] & SQUARE_BBS[H8]) == 0: #{ castleRights[BKS_CASTLE_RIGHTS] = False #} #} if castleRights[BQS_CASTLE_RIGHTS] == True: #{ if (pieceArray[BR] & SQUARE_BBS[A8]) == 0: #{ castleRights[BQS_CASTLE_RIGHTS] = False #} #} #} priorNodes = nodes nodes += PerftInline(depth-1, ply+1) whiteToPlay = not whiteToPlay match tag: #{ case 0: #none pieceArray[piece] |= SQUARE_BBS[startingSquare] pieceArray[piece] &= ~SQUARE_BBS[targetSquare] case 26: #check pieceArray[piece] |= SQUARE_BBS[startingSquare] pieceArray[piece] &= ~SQUARE_BBS[targetSquare] case 1: #capture pieceArray[piece] |= SQUARE_BBS[startingSquare] pieceArray[piece] &= ~SQUARE_BBS[targetSquare] if (piece >= WP and piece < BP): #{ pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] #} else: #{ #is black pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] #} case 27: #check cap pieceArray[piece] |= SQUARE_BBS[startingSquare] pieceArray[piece] &= ~SQUARE_BBS[targetSquare] if piece >= WP and piece < BP: #{ pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] #} else: #{ #is black pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] #} case 2: #white ep pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WP] &= ~SQUARE_BBS[targetSquare] pieceArray[BP] |= SQUARE_BBS[targetSquare+8] case 3: #black ep pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BP] &= ~SQUARE_BBS[targetSquare] pieceArray[WP] |= SQUARE_BBS[targetSquare-8] case 4: #WKS #white king pieceArray[WK] |= SQUARE_BBS[E1] pieceArray[WK] &= ~SQUARE_BBS[G1] #white rook pieceArray[WR] |= SQUARE_BBS[H1] pieceArray[WR] &= ~SQUARE_BBS[F1] case 5: #WQS #white king pieceArray[WK] |= SQUARE_BBS[E1] pieceArray[WK] &= ~SQUARE_BBS[C1] #white rook pieceArray[WR] |= SQUARE_BBS[A1] pieceArray[WR] &= ~SQUARE_BBS[D1] case 6: #BKS #white king pieceArray[BK] |= SQUARE_BBS[E8] pieceArray[BK] &= ~SQUARE_BBS[G8] #white rook pieceArray[BR] |= SQUARE_BBS[H8] pieceArray[BR] &= ~SQUARE_BBS[F8] case 7: #BQS #white king pieceArray[BK] |= SQUARE_BBS[E8] pieceArray[BK] &= ~SQUARE_BBS[C8] #white rook pieceArray[BR] |= SQUARE_BBS[A8] pieceArray[BR] &= ~SQUARE_BBS[D8] case 8: #BNPr pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BN] &= ~SQUARE_BBS[targetSquare] case 9: #BBPr pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BB] &= ~SQUARE_BBS[targetSquare] case 10: #BQPr pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BQ] &= ~SQUARE_BBS[targetSquare] case 11: #BRPr pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BR] &= ~SQUARE_BBS[targetSquare] case 12: #WNPr pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WN] &= ~SQUARE_BBS[targetSquare] case 13: #WBPr pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WB] &= ~SQUARE_BBS[targetSquare] case 14: #WQPr pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WQ] &= ~SQUARE_BBS[targetSquare] case 15: #WRPr pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WR] &= ~SQUARE_BBS[targetSquare] case 16: #BNPrCAP pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BN] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 17: #BBPrCAP pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BB] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 18: #BQPrCAP pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BQ] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 19: #BRPrCAP pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BR] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 20: #WNPrCAP pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WN] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 21: #WBPrCAP pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WB] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 22: #WQPrCAP pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WQ] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 23: #WRPrCAP pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WR] &= ~SQUARE_BBS[targetSquare] pieceArray[captureIndex] |= SQUARE_BBS[targetSquare] case 24: #WDouble pieceArray[WP] |= SQUARE_BBS[startingSquare] pieceArray[WP] &= ~SQUARE_BBS[targetSquare] case 25: #BDouble pieceArray[BP] |= SQUARE_BBS[startingSquare] pieceArray[BP] &= ~SQUARE_BBS[targetSquare] #} castleRights[0] = copyCastle[0] castleRights[1] = copyCastle[1] castleRights[2] = copyCastle[2] castleRights[3] = copyCastle[3] ep = copyEp if ply == 0: #{ PrintMoveNoNL(moveList[moveIndex][MOVE_STARTING], moveList[moveIndex][MOVE_TARGET], moveList[moveIndex][MOVE_TAG]) print(f": {nodes-priorNodes}") #} #} return nodes #} def current_milli_time(): return round(time.time() * 1000) def RunPerftInline(depth: int): #{ timestamp_start = current_milli_time(); nodes: int = PerftInline(depth, 0) timestamp_end = current_milli_time(); elapsed = timestamp_end - timestamp_start print(f"Nodes: {nodes}"); print(f"Elapsed time: {elapsed}"); #} SetStartingPosition(); PrintBoard(); RunPerftInline(6); #RunPerftInlineStruct(6); input();