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