Files
hcsalmon1-Chess-Engine-Test/Python/engine.py
Coding with Tom 47914e7df2 Update engine.py
no numpy, using only ints. Compiled with pypy
2025-01-22 15:07:56 +00:00

3443 lines
113 KiB
Python

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();