Files
hcsalmon1-Chess-Engine-Test/Zig/main.zig
Coding with Tom 8d64057a72 Update main.zig
Fixed errors
2025-01-24 12:57:50 +00:00

2868 lines
113 KiB
Zig

const std = @import("std");
const constants = @import("constants.zig");
const WHITE_TO_PLAY = true;
const BLACK_TO_PLAY = false;
//inline BitscanForward(const tempBitboard);
const MAGIC:u64 = 0x03f79d71b4cb0a89;
const DEBRUIJN64:[64]usize = [64]usize
{
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
};
fn BitscanForward(tempBitboard:u64) usize {
return @truncate(DEBRUIJN64[MAGIC *% (tempBitboard ^ (tempBitboard - 1)) >> 58]);
}
//fens
const FEN_STARTING_POSITION = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
const PINNED_SQUARE_INDEX = 0;
const PINNING_PIECE_INDEX = 1;
//LSB
//equation: startingSquare = (DEBRUIJN64[MAGIC * (tempBitboard ^ (tempBitboard - 1)) >> 58]);
const MAX_ULONG = 18446744073709551615;
const MOVE_STARTING = 0;
const MOVE_TARGET = 1;
const MOVE_PIECE = 2;
const MOVE_TAG = 3;
const SQ_CHAR_Y = [_]u8
{
'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'
};
const SQ_CHAR_X = [_]u8 {
'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'
};
const BLACK_PAWN_CHAR = 'p';
const BLACK_KNIGHT_CHAR = 'n';
const BLACK_BISHOP_CHAR = 'b';
const BLACK_ROOK_CHAR = 'r';
const BLACK_QUEEN_CHAR = 'q';
const BLACK_KING_CHAR = 'k';
const WHITE_PAWN_CHAR = 'P';
const WHITE_KNIGHT_CHAR = 'N';
const WHITE_BISHOP_CHAR = 'B';
const WHITE_ROOK_CHAR = 'R';
const WHITE_QUEEN_CHAR = 'Q';
const WHITE_KING_CHAR = 'K';
const DUCK_CHAR = 'D';
const BRACKET_CHAR = '/';
const SPACE_CHAR = ' ';
const DASH_CHAR = '-';
const W_SIDE_CHAR = 'w';
const B_SIDE_CHAR = 'b';
const CAPITAL_K_CHAR = 'K';
const CAPITAL_Q_CHAR = 'Q';
const SMALL_K_CHAR = 'k'; const SMALL_Q_CHAR = 'q';
const BITBOARD_COUNT = 12;
const WKS_CASTLE_RIGHTS = 0;
const WQS_CASTLE_RIGHTS = 1;
const BKS_CASTLE_RIGHTS = 2;
const BQS_CASTLE_RIGHTS = 3;
const WP = 0;
const WN = 1;
const WB = 2;
const WR = 3;
const WQ = 4;
const WK = 5;
const BP = 6;
const BN = 7;
const BB = 8;
const BR = 9;
const BQ = 10;
const BK = 11;
const WHITE_PAWN_ATTACKS = [_]u64
{
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,
};
const BLACK_PAWN_ATTACKS = [_]u64
{
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,
};
const KNIGHT_ATTACKS = [_]u64
{
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,
};
const BISHOP_MASKS = [_]u64
{
18049651735527936,
70506452091904,
275415828992,
1075975168,
38021120,
8657588224,
2216338399232,
567382630219776,
9024825867763712,
18049651735527424,
70506452221952,
275449643008,
9733406720,
2216342585344,
567382630203392,
1134765260406784,
4512412933816832,
9024825867633664,
18049651768822272,
70515108615168,
2491752130560,
567383701868544,
1134765256220672,
2269530512441344,
2256206450263040,
4512412900526080,
9024834391117824,
18051867805491712,
637888545440768,
1135039602493440,
2269529440784384,
4539058881568768,
1128098963916800,
2256197927833600,
4514594912477184,
9592139778506752,
19184279556981248,
2339762086609920,
4538784537380864,
9077569074761728,
562958610993152,
1125917221986304,
2814792987328512,
5629586008178688,
11259172008099840,
22518341868716544,
9007336962655232,
18014673925310464,
2216338399232,
4432676798464,
11064376819712,
22137335185408,
44272556441600,
87995357200384,
35253226045952,
70506452091904,
567382630219776,
1134765260406784,
2832480465846272,
5667157807464448,
11333774449049600,
22526811443298304,
9024825867763712,
18049651735527936
};
const ROOK_MASKS = [_]u64
{
282578800148862,
565157600297596,
1130315200595066,
2260630401190006,
4521260802379886,
9042521604759646,
18085043209519166,
36170086419038334,
282578800180736,
565157600328704,
1130315200625152,
2260630401218048,
4521260802403840,
9042521604775424,
18085043209518592,
36170086419037696,
282578808340736,
565157608292864,
1130315208328192,
2260630408398848,
4521260808540160,
9042521608822784,
18085043209388032,
36170086418907136,
282580897300736,
565159647117824,
1130317180306432,
2260632246683648,
4521262379438080,
9042522644946944,
18085043175964672,
36170086385483776,
283115671060736,
565681586307584,
1130822006735872,
2261102847592448,
4521664529305600,
9042787892731904,
18085034619584512,
36170077829103616,
420017753620736,
699298018886144,
1260057572672512,
2381576680245248,
4624614895390720,
9110691325681664,
18082844186263552,
36167887395782656,
35466950888980736,
34905104758997504,
34344362452452352,
33222877839362048,
30979908613181440,
26493970160820224,
17522093256097792,
35607136465616896,
9079539427579068672,
8935706818303361536,
8792156787827803136,
8505056726876686336,
7930856604974452736,
6782456361169985536,
4485655873561051136,
9115426935197958144
};
const ROOK_MAGIC_NUMBERS = [_]u64
{
0x8a80104000800020,
0x140002000100040,
0x2801880a0017001,
0x100081001000420,
0x200020010080420,
0x3001c0002010008,
0x8480008002000100,
0x2080088004402900,
0x800098204000,
0x2024401000200040,
0x100802000801000,
0x120800800801000,
0x208808088000400,
0x2802200800400,
0x2200800100020080,
0x801000060821100,
0x80044006422000,
0x100808020004000,
0x12108a0010204200,
0x140848010000802,
0x481828014002800,
0x8094004002004100,
0x4010040010010802,
0x20008806104,
0x100400080208000,
0x2040002120081000,
0x21200680100081,
0x20100080080080,
0x2000a00200410,
0x20080800400,
0x80088400100102,
0x80004600042881,
0x4040008040800020,
0x440003000200801,
0x4200011004500,
0x188020010100100,
0x14800401802800,
0x2080040080800200,
0x124080204001001,
0x200046502000484,
0x480400080088020,
0x1000422010034000,
0x30200100110040,
0x100021010009,
0x2002080100110004,
0x202008004008002,
0x20020004010100,
0x2048440040820001,
0x101002200408200,
0x40802000401080,
0x4008142004410100,
0x2060820c0120200,
0x1001004080100,
0x20c020080040080,
0x2935610830022400,
0x44440041009200,
0x280001040802101,
0x2100190040002085,
0x80c0084100102001,
0x4024081001000421,
0x20030a0244872,
0x12001008414402,
0x2006104900a0804,
0x1004081002402
};
const BISHOP_MAGIC_NUMBERS = [_]u64
{
0x40040844404084,
0x2004208a004208,
0x10190041080202,
0x108060845042010,
0x581104180800210,
0x2112080446200010,
0x1080820820060210,
0x3c0808410220200,
0x4050404440404,
0x21001420088,
0x24d0080801082102,
0x1020a0a020400,
0x40308200402,
0x4011002100800,
0x401484104104005,
0x801010402020200,
0x400210c3880100,
0x404022024108200,
0x810018200204102,
0x4002801a02003,
0x85040820080400,
0x810102c808880400,
0xe900410884800,
0x8002020480840102,
0x220200865090201,
0x2010100a02021202,
0x152048408022401,
0x20080002081110,
0x4001001021004000,
0x800040400a011002,
0xe4004081011002,
0x1c004001012080,
0x8004200962a00220,
0x8422100208500202,
0x2000402200300c08,
0x8646020080080080,
0x80020a0200100808,
0x2010004880111000,
0x623000a080011400,
0x42008c0340209202,
0x209188240001000,
0x400408a884001800,
0x110400a6080400,
0x1840060a44020800,
0x90080104000041,
0x201011000808101,
0x1a2208080504f080,
0x8012020600211212,
0x500861011240000,
0x180806108200800,
0x4000020e01040044,
0x300000261044000a,
0x802241102020002,
0x20906061210001,
0x5a84841004010310,
0x4010801011c04,
0xa010109502200,
0x4a02012000,
0x500201010098b028,
0x8040002811040900,
0x28000010020204,
0x6000020202d0240,
0x8918844842082200,
0x4010011029020020
};
const BISHOP_REL_BITS =[_]usize
{
6 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,
5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,
5 ,5 ,7 ,7 ,7 ,7 ,5 ,5 ,
5 ,5 ,7 ,9 ,9 ,7 ,5 ,5 ,
5 ,5 ,7 ,9 ,9 ,7 ,5 ,5 ,
5 ,5 ,7 ,7 ,7 ,7 ,5 ,5 ,
5 ,5 ,5 ,5 ,5 ,5 ,5 ,5 ,
6 ,5 ,5 ,5 ,5 ,5 ,5 ,6 ,
};
const ROOK_REL_BITS = [_]usize
{
12 ,11 ,11 ,11 ,11 ,11 ,11 ,12 ,
11 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,
11 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,
11 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,
11 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,
11 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,
11 ,10 ,10 ,10 ,10 ,10 ,10 ,11 ,
12 ,11 ,11 ,11 ,11 ,11 ,11 ,12 ,
};
const KING_ATTACKS = [_]u64
{ 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,
};
const SQUARE_BBS = [_]u64
{
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,
};
const RANK_1_BITBOARD = 18374686479671623680;
const RANK_2_BITBOARD = 71776119061217280;
const RANK_3_BITBOARD = 280375465082880;
const RANK_4_BITBOARD = 1095216660480;
const RANK_5_BITBOARD = 4278190080;
const RANK_6_BITBOARD = 16711680;
const RANK_7_BITBOARD = 65280;
const RANK_8_BITBOARD = 255;
const FILE_A_BITBOARD = 72340172838076673;
const FILE_B_BITBOARD = 144680345676153346;
const FILE_C_BITBOARD = 289360691352306692;
const FILE_D_BITBOARD = 578721382704613384;
const FILE_E_BITBOARD = 1157442765409226768;
const FILE_F_BITBOARD = 2314885530818453536;
const FILE_G_BITBOARD = 4629771061636907072;
const FILE_H_BITBOARD = 9259542123273814144;
const FILE_TO_SQUARE_BBS = [_]u64
{
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144,
};
pub inline fn getBishopAttacksFast(startingSquare: usize, occupancy: u64) u64 {
var mutableOccupancy: u64 = occupancy;
const shiftAmount: u64 = 64 - BISHOP_REL_BITS[startingSquare];
mutableOccupancy &= BISHOP_MASKS[startingSquare];
mutableOccupancy *%= BISHOP_MAGIC_NUMBERS[startingSquare];
mutableOccupancy >>= @truncate(shiftAmount);
return constants.BISHOP_ATTACKS[startingSquare][@truncate(mutableOccupancy)];
}
pub inline fn getRookAttacksFast(startingSquare: usize, occupancy: u64) u64 {
var mutableOccupancy: u64 = occupancy;
const shiftAmount: u64 = 64 - ROOK_REL_BITS[startingSquare];
mutableOccupancy &= ROOK_MASKS[startingSquare];
mutableOccupancy *%= ROOK_MAGIC_NUMBERS[startingSquare];
mutableOccupancy >>= @truncate(shiftAmount);
return constants.ROOK_ATTACKS[startingSquare][@truncate(mutableOccupancy)];
}
const WHITE_START_INDEX = WP;
const WHITE_END_INDEX = WK;
const BLACK_START_INDEX = BP;
const BLACK_END_INDEX = BK;
const TAG_NONE = 0;
const TAG_CAPTURE = 1;
const TAG_WHITE_EP = 2;
const TAG_BLACK_EP = 3;
const TAG_WCASTLEKS = 4;
const TAG_WCASTLEQS = 5;
const TAG_BCASTLEKS = 6;
const TAG_BCASTLEQS = 7;
const TAG_B_N_PROMOTION = 8;
const TAG_B_B_PROMOTION = 9;
const TAG_B_Q_PROMOTION = 10;
const TAG_B_R_PROMOTION = 11;
const TAG_W_N_PROMOTION = 12;
const TAG_W_B_PROMOTION = 13;
const TAG_W_Q_PROMOTION = 14;
const TAG_W_R_PROMOTION = 15;
const TAG_B_N_PROMOTION_CAP = 16;
const TAG_B_B_PROMOTION_CAP = 17;
const TAG_B_Q_PROMOTION_CAP = 18;
const TAG_B_R_PROMOTION_CAP = 19;
const TAG_W_N_PROMOTION_CAP = 20;
const TAG_W_B_PROMOTION_CAP = 21;
const TAG_W_Q_PROMOTION_CAP = 22;
const TAG_W_R_PROMOTION_CAP = 23;
const TAG_W_DOUBLE_PAWN = 24;
const TAG_B_DOUBLE_PAWN = 25;
const TAG_CHECK = 26;
const TAG_CHECK_CAPTURE = 27;
const PROMOTION_START = TAG_B_N_PROMOTION;
const PROMOTION_END_INCLUSIVE = TAG_W_R_PROMOTION_CAP;
const A8 = 0; const B8 = 1; const C8 = 2; const D8 = 3; const E8 = 4; const F8 = 5; const G8 = 6; const H8 = 7;
const A7 = 8; const B7 = 9; const C7 = 10; const D7 = 11; const E7 = 12; const F7 = 13; const G7 = 14; const H7 = 15;
const A6 = 16; const B6 = 17; const C6 = 18; const D6 = 19; const E6 = 20; const F6 = 21; const G6 = 22; const H6 = 23;
const A5 = 24; const B5 = 25; const C5 = 26; const D5 = 27; const E5 = 28; const F5 = 29; const G5 = 30; const H5 = 31;
const A4 = 32; const B4 = 33; const C4 = 34; const D4 = 35; const E4 = 36; const F4 = 37; const G4 = 38; const H4 = 39;
const A2 = 48; const B2 = 49; const C2 = 50; const D2 = 51; const E2 = 52; const F2 = 53; const G2 = 54; const H2 = 55;
const A1 = 56; const B1 = 57; const C1 = 58; const D1 = 59; const E1 = 60; const F1 = 61; const G1 = 62; const H1 = 63; const NO_SQUARE = 64;
const WKS_EMPTY_BITBOARD = 6917529027641081856;
const WQS_EMPTY_BITBOARD = 1008806316530991104;
const BKS_EMPTY_BITBOARD = 96;
const BQS_EMPTY_BITBOARD = 14;
const COMBINED_OCCUPANCIES = 0;
const WHITE_OCCUPANCIES = 1;
const BLACK_OCCUPANCIES = 2;
var bitboard_array_global: [12]u64 = undefined;
var occupancies_global: [3]u64 = undefined;
var ep_global: usize = undefined;
var castle_rights_global: [4]bool = undefined;
var is_white_global: bool = true;
//struct Board {
// pieceArray[12];
// occupancies[3];
// isWhite;
// ep;
// castleRights[4];
//};
const PIECE_PHASE = 0;
const SIDE_PHASE = 1;
const CASTLE_PHASE = 2;
const EP_PHASE = 3; const FIFTY_MOVE_PHASE = 4;
const MOVE_COUNT_PHASE = 5;
const PIECE_COLOURS = [_]u8 { 'W','W','W','W','W','W','b','b','b','b','b','b' };
const PIECE_CHARS = [_]u8 { 'P','N','B','R','Q','K','p','n','b','r','q','k' };
fn ResetBoardGlobal() void {
castle_rights_global[0] = false;
castle_rights_global[1] = false;
castle_rights_global[2] = false;
castle_rights_global[3] = false;
for (0..BITBOARD_COUNT) |i| {
bitboard_array_global[i] = 0;
}
is_white_global = true;
ep_global = NO_SQUARE;
}
fn ParseFenGlobal(input:[]const u8, starting_index:usize) void {
ResetBoardGlobal();
const inputLength = input.len;
if (starting_index >= inputLength) {
return;
}
if (starting_index < 0) {
return;
}
var currentPhase:usize = PIECE_PHASE;
var bracketCount:usize = 0;
var squareCount:usize = 0;
var epX:usize = NO_SQUARE;
var epY:usize = NO_SQUARE;
for (0..inputLength) |characterIndex| {
const characterInFen = input[characterIndex];
switch (currentPhase) {
0=> {
if (bracketCount == 7 and characterInFen == ' ') {
//prf(" next phase brackcount = 7, is empty\n");
currentPhase+=1;
} else {
if (bracketCount > 7) {
bracketCount = 0;
}
if (squareCount > 7) {
squareCount = 0;
}
const square:usize = (bracketCount * 8) + squareCount;
switch (characterInFen) {
'B' => {
//prf(" W bishop found %d\n", square);
bitboard_array_global[WB] |= SQUARE_BBS[square];
squareCount+=1;
},
'R' => {
//prf(" WR found\n");
bitboard_array_global[WR] |= SQUARE_BBS[square];
squareCount+=1;
},
'P' => {
//prf(" add white pawn %d\n", square);
bitboard_array_global[WP] |= SQUARE_BBS[square];
squareCount+=1;
},
'Q'=>{
//prf(" WQ found\n");
bitboard_array_global[WQ] |= SQUARE_BBS[square];
squareCount+=1;
},
'K'=>{
//prf(" WK\n");
bitboard_array_global[WK] |= SQUARE_BBS[square];
squareCount+=1;
},
'N'=>{
//prf(" WN found\n");
bitboard_array_global[WN] |= SQUARE_BBS[square];
squareCount+=1;
},
'b'=>{
//prf(" BB found\n");
bitboard_array_global[BB] |= SQUARE_BBS[square];
squareCount+=1;
},
'p'=>{
//prf(" BP sq: %d\n", square);
bitboard_array_global[BP] |= SQUARE_BBS[square];
squareCount+=1;
},
'q'=>{
//prf(" BQ sq: %d\n", square);
bitboard_array_global[BQ] |= SQUARE_BBS[square];
squareCount+=1;
},
'r'=>{
//prf(" BR sq: %d\n", square);
bitboard_array_global[BR] |= SQUARE_BBS[square];
squareCount+=1;
},
'n'=>{
//prf(" BN sq: %d\n", square);
bitboard_array_global[BN] |= SQUARE_BBS[square];
squareCount+=1;
},
'k'=>{
//prf(" BK sq: %d\n", square);
bitboard_array_global[BK] |= SQUARE_BBS[square];
squareCount+=1;
},
'/'=>{
//prf(" forward bracket slash\n", square);
squareCount = 0;
bracketCount+=1;
},
'1'=>{
//prf(" 1 found\n");
squareCount += 1;
},
'2'=>{
//prf(" 2 found\n");
squareCount += 2;
},
'3'=>{
//prf(" 3 found\n");
squareCount += 3;
},
'4'=>{
//prf(" 4 found\n");
squareCount += 4;
},
'5'=>{
//prf(" 5 found\n");
squareCount += 5;
},
'6'=>{
//prf(" 6 found\n");
squareCount += 6;
},
'7'=>{
//prf(" 7 found\n");
squareCount += 7;
},
'8'=>{
//prf(" 8 found\n");
squareCount += 8;
},
else => {
unreachable;
}
}
}
},
1 => {
if (characterInFen == 'w') {
is_white_global = true;
}
else if (characterInFen == 'b') {
is_white_global = false;
}
else if (characterInFen == ' ') {
currentPhase+=1;
}
break;
},
2 => {
switch (characterInFen)
{
'K'=>{
castle_rights_global[0] = true;
},
'Q'=>{
castle_rights_global[1] = true;
},
'k'=>{
castle_rights_global[2] = true;
},
'q'=>{
castle_rights_global[3] = true;
},
'-'=>{
},
' '=>{
currentPhase+=1;
},
else => {
}
}
},
3 => {
if (characterInFen == ' ') {
if (epX != -1) {
if (epY != -1) {
ep_global = (epY * 8) + epX;
}
}
currentPhase+=1;
} else {
switch (characterInFen) {
'a' => {
epX = 0;
},
'b' =>{
epX = 1;
},
'c'=>{
epX = 2;
},
'd'=>{
epX = 3;
},
'e'=>{
epX = 4;
},
'f'=>{
epX = 5;
},
'g'=>{
epX = 6;
},
'h'=>{
epX = 7;
},
'1'=>{
epY = 7;
},
'2'=>{
epY = 6;
},
'3'=>{
epY = 5;
},
'4'=>{
epY = 4;
},
'5'=>{
epY = 3;
},
'6'=>{
epY = 2;
},
'7'=>{
epY = 1;
},
'8'=>{
epY = 0;
},
else => {
unreachable;
}
}
}
},
4 =>{
},
5 => {
},
else => {
unreachable;
},
}
}
}
fn Is_Square_Attacked_By_Black_Global(square:usize, occupancy: u64) bool {
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[square]) != 0) {
return true;
}
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[square]) != 0) {
return true;
}
if ((bitboard_array_global[BK] & KING_ATTACKS[square]) != 0) {
return true;
}
const bishopAttacks = getBishopAttacksFast(square, occupancy);
if ((bitboard_array_global[BB] & bishopAttacks) != 0) {
return true;
}
if ((bitboard_array_global[BQ] & bishopAttacks) != 0) {
return true;
}
const rookAttacks = getRookAttacksFast(square, occupancy);
if ((bitboard_array_global[BR] & rookAttacks) != 0) {
return true;
}
if ((bitboard_array_global[BQ] & rookAttacks) != 0) {
return true;
}
return false;
}
fn Is_Square_Attacked_By_White_Global(square:usize, occupancy:u64) bool {
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[square]) != 0) {
return true;
}
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[square]) != 0) {
return true;
}
if ((bitboard_array_global[WK] & KING_ATTACKS[square]) != 0) {
return true;
}
const bishopAttacks = getBishopAttacksFast(square, occupancy);
if ((bitboard_array_global[WB] & bishopAttacks) != 0) {
return true;
}
if ((bitboard_array_global[WQ] & bishopAttacks) != 0) {
return true;
}
const rookAttacks = getRookAttacksFast(square, occupancy);
if ((bitboard_array_global[WR] & rookAttacks) != 0) {
return true;
}
if ((bitboard_array_global[WQ] & rookAttacks) != 0) {
return true;
}
return false;
}
fn OutOfBounds(move:usize) bool {
if (move > 63)
{
return true;
}
return false;
}
fn PrMoveNoNL(starting_square:usize, target_square:usize) void { //starting
if (OutOfBounds(starting_square) == true) {
std.debug.print("{}", .{starting_square});
} else {
std.debug.print("{c}{c}", .{SQ_CHAR_X[starting_square], SQ_CHAR_Y[starting_square]});
}
if (OutOfBounds(target_square) == true) {
std.debug.print("{}", .{target_square});
} else {
std.debug.print("{c}{c}", .{SQ_CHAR_X[target_square], SQ_CHAR_Y[target_square]});
}
}
fn perftInline(depth:i8, ply:u8) usize {
//if (depth == 0)
//{
// return 1;
//}
var move_list:[50][4]usize = undefined;
var move_count:usize = 0;
//Move generating variables
const WHITE_OCCUPANCIES_LOCAL:u64 = bitboard_array_global[0] | bitboard_array_global[1] | bitboard_array_global[2] | bitboard_array_global[3] | bitboard_array_global[4] | bitboard_array_global[5];
const BLACK_OCCUPANCIES_LOCAL:u64 = bitboard_array_global[6] | bitboard_array_global[7] | bitboard_array_global[8] | bitboard_array_global[9] | bitboard_array_global[10] | bitboard_array_global[11];
const COMBINED_OCCUPANCIES_LOCAL:u64 = WHITE_OCCUPANCIES_LOCAL | BLACK_OCCUPANCIES_LOCAL;
const EMPTY_OCCUPANCIES:u64 = ~COMBINED_OCCUPANCIES_LOCAL;
var temp_bitboard:u64 = undefined;
var check_bitboard:u64 = 0;
var temp_pin_bitboard:u64 = undefined;
var temp_attack:u64 = undefined;
var temp_empty:u64 = undefined;
var temp_captures:u64 = undefined;
var starting_square:usize = NO_SQUARE;
var target_square:usize = NO_SQUARE;
var pinArray:[8][2]usize = [8][2]usize {
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE },
.{ NO_SQUARE, NO_SQUARE},
};
var pinNumber:usize = 0;
if (is_white_global == true) {
var whiteKingCheckCount:usize = 0;
const whiteKingPosition:usize = DEBRUIJN64[MAGIC *% (bitboard_array_global[WK] ^ (bitboard_array_global[WK] - 1)) >> 58];
//pawns
temp_bitboard = bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[whiteKingPosition];
if (temp_bitboard != 0) {
const pawn_square:usize = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
check_bitboard = SQUARE_BBS[pawn_square];
whiteKingCheckCount+=1;
}
//knights
temp_bitboard = bitboard_array_global[BN] & KNIGHT_ATTACKS[whiteKingPosition];
if (temp_bitboard != 0) {
const knight_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
check_bitboard = SQUARE_BBS[knight_square];
whiteKingCheckCount+=1;
}
//bishops
const bishopAttacksChecks = getBishopAttacksFast(whiteKingPosition, BLACK_OCCUPANCIES_LOCAL);
temp_bitboard = bitboard_array_global[BB] & bishopAttacksChecks;
while (temp_bitboard != 0) {
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
whiteKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0) {
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
//queen
temp_bitboard = bitboard_array_global[BQ] & bishopAttacksChecks;
while (temp_bitboard != 0) {
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
whiteKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0) {
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
//rook
const rook_attacks = getRookAttacksFast(whiteKingPosition, BLACK_OCCUPANCIES_LOCAL);
temp_bitboard = bitboard_array_global[BR] & rook_attacks;
while (temp_bitboard != 0)
{
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
whiteKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0) {
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
//queen
temp_bitboard = bitboard_array_global[BQ] & rook_attacks;
while (temp_bitboard != 0)
{
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square] & WHITE_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][piece_square];
whiteKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0) {
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
if (whiteKingCheckCount > 1) {
const occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[WK]);
temp_attack = KING_ATTACKS[whiteKingPosition];
temp_empty = temp_attack & EMPTY_OCCUPANCIES;
while (temp_empty != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_empty ^ (temp_empty - 1)) >> 58];
temp_empty &= temp_empty - 1;
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const bishopAttacks = getBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WK;
move_count+=1;
}
//captures
temp_captures = temp_attack & BLACK_OCCUPANCIES_LOCAL;
while (temp_captures != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_captures ^ (temp_captures - 1)) >> 58];
temp_captures &= temp_captures - 1;
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const bishopAttacks = getBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WK;
move_count+=1;
}
} else {
if (whiteKingCheckCount == 0) {
check_bitboard = MAX_ULONG;
}
const occupanciesWithoutWhiteKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[WK]);
temp_attack = KING_ATTACKS[whiteKingPosition];
temp_empty = temp_attack & EMPTY_OCCUPANCIES;
while (temp_empty != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_empty ^ (temp_empty - 1)) >> 58];
temp_empty &= temp_empty - 1;
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const bishopAttacks = getBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WK;
move_count+=1;
}
//captures
temp_captures = temp_attack & BLACK_OCCUPANCIES_LOCAL;
while (temp_captures != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_captures ^ (temp_captures - 1)) >> 58];
temp_captures &= temp_captures - 1;
if ((bitboard_array_global[BP] & WHITE_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[BK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const bishopAttacks = getBishopAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupanciesWithoutWhiteKing);
if ((bitboard_array_global[BR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[BQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = whiteKingPosition;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WK;
move_count+=1;
}
if (whiteKingCheckCount == 0) {
if (castle_rights_global[WKS_CASTLE_RIGHTS] == true) {
if (whiteKingPosition == E1) { //king on e1
if ((WKS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) { //f1 and g1 empty
if ((bitboard_array_global[WR] & SQUARE_BBS[H1]) != 0) { //rook on h1
if (Is_Square_Attacked_By_Black_Global(F1, COMBINED_OCCUPANCIES_LOCAL) == false) {
if (Is_Square_Attacked_By_Black_Global(G1, COMBINED_OCCUPANCIES_LOCAL) == false) {
move_list[move_count][MOVE_STARTING] = E1;
move_list[move_count][MOVE_TARGET] = G1;
move_list[move_count][MOVE_TAG] = TAG_WCASTLEKS;
move_list[move_count][MOVE_PIECE] = WK;
move_count+=1;
}
}
}
}
}
}
if (castle_rights_global[WQS_CASTLE_RIGHTS] == true) {
if (whiteKingPosition == E1) { //king on e1
if ((WQS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) { //f1 and g1 empty
if ((bitboard_array_global[WR] & SQUARE_BBS[A1]) != 0) { //rook on h1
if (Is_Square_Attacked_By_Black_Global(C1, COMBINED_OCCUPANCIES_LOCAL) == false) {
if (Is_Square_Attacked_By_Black_Global(D1, COMBINED_OCCUPANCIES_LOCAL) == false) {
move_list[move_count][MOVE_STARTING] = E1;
move_list[move_count][MOVE_TARGET] = C1;
move_list[move_count][MOVE_TAG] = TAG_WCASTLEQS;
move_list[move_count][MOVE_PIECE] = WK;
move_count+=1;
}
}
}
}
}
}
}
temp_bitboard = bitboard_array_global[WN];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1; //removes the knight from that square to not infinitely loop
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
temp_attack = ((KNIGHT_ATTACKS[starting_square] & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //gets knight captures
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WN;
move_count+=1;
}
temp_attack = ((KNIGHT_ATTACKS[starting_square] & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WN;
move_count+=1;
}
}
temp_bitboard = bitboard_array_global[WP];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
if ((SQUARE_BBS[starting_square - 8] & COMBINED_OCCUPANCIES_LOCAL) == 0) { //if up one square is empty
if (((SQUARE_BBS[starting_square - 8] & check_bitboard) & temp_pin_bitboard) != 0) {
if ((SQUARE_BBS[starting_square] & RANK_7_BITBOARD) != 0) { //if promotion
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square - 8;
move_list[move_count][MOVE_TAG] = TAG_W_Q_PROMOTION;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square - 8;
move_list[move_count][MOVE_TAG] = TAG_W_R_PROMOTION;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square - 8;
move_list[move_count][MOVE_TAG] = TAG_W_B_PROMOTION;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square - 8;
move_list[move_count][MOVE_TAG] = TAG_W_N_PROMOTION;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
} else {
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square - 8;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
}
}
if ((SQUARE_BBS[starting_square] & RANK_2_BITBOARD) != 0) { //if on rank 2
if (((SQUARE_BBS[starting_square - 16] & check_bitboard) & temp_pin_bitboard) != 0) { //if not pinned or
if (((SQUARE_BBS[starting_square - 16]) & COMBINED_OCCUPANCIES_LOCAL) == 0) { //if up two squares and one square are empty
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square - 16;
move_list[move_count][MOVE_TAG] = TAG_W_DOUBLE_PAWN;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
}
}
}
}
temp_attack = ((WHITE_PAWN_ATTACKS[starting_square] & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //if black piece diagonal to pawn
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
if ((SQUARE_BBS[starting_square] & RANK_7_BITBOARD) != 0) { //if promotion
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_W_Q_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_W_R_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_W_B_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_W_N_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
} else {
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
}
}
if ((SQUARE_BBS[starting_square] & RANK_5_BITBOARD) != 0) { //check rank for ep
if (ep_global != NO_SQUARE) {
if ((((WHITE_PAWN_ATTACKS[starting_square] & SQUARE_BBS[ep_global]) & check_bitboard) & temp_pin_bitboard) != 0) {
if ((bitboard_array_global[WK] & RANK_5_BITBOARD) == 0) { //if no king on rank 5
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = ep_global;
move_list[move_count][MOVE_TAG] = TAG_WHITE_EP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
} else if ((bitboard_array_global[BR] & RANK_5_BITBOARD) == 0 and (bitboard_array_global[BQ] & RANK_5_BITBOARD) == 0) { // if no b rook or queen on rank 5
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = ep_global;
move_list[move_count][MOVE_TAG] = TAG_WHITE_EP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
} else { //wk and br or bq on rank 5
var occupancyWithoutEPPawns:u64 = COMBINED_OCCUPANCIES_LOCAL & ~SQUARE_BBS[starting_square];
occupancyWithoutEPPawns &= ~SQUARE_BBS[ep_global + 8];
const rookAttacksFromKing = getRookAttacksFast(whiteKingPosition, occupancyWithoutEPPawns);
if ((rookAttacksFromKing & bitboard_array_global[BR]) == 0) {
if ((rookAttacksFromKing & bitboard_array_global[BQ]) == 0) {
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = ep_global;
move_list[move_count][MOVE_TAG] = TAG_WHITE_EP;
move_list[move_count][MOVE_PIECE] = WP;
move_count+=1;
}
}
}
}
}
}
}
temp_bitboard = bitboard_array_global[WR];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
const rookAttacks = getRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
temp_attack = ((rookAttacks & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WR;
move_count+=1;
}
temp_attack = ((rookAttacks & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WR;
move_count+=1;
}
}
temp_bitboard = bitboard_array_global[WB];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
const bishopAttacks = getBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
temp_attack = ((bishopAttacks & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WB;
move_count+=1;
}
temp_attack = ((bishopAttacks & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WB;
move_count+=1;
}
}
temp_bitboard = bitboard_array_global[WQ];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[whiteKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
var queenAttacks:u64 = getRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
queenAttacks |= getBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
temp_attack = ((queenAttacks & BLACK_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = WQ;
move_count+=1;
}
temp_attack = ((queenAttacks & EMPTY_OCCUPANCIES) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = WQ;
move_count+=1;
}
}
}
} else { //black move
var blackKingCheckCount:usize = 0;
const blackKingPosition:usize = DEBRUIJN64[MAGIC *% (bitboard_array_global[BK] ^ (bitboard_array_global[BK] - 1)) >> 58];
//pawns
temp_bitboard = bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[blackKingPosition];
if (temp_bitboard != 0) {
const pawn_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
check_bitboard = SQUARE_BBS[pawn_square];
blackKingCheckCount+=1;
}
//knights
temp_bitboard = bitboard_array_global[WN] & KNIGHT_ATTACKS[blackKingPosition];
if (temp_bitboard != 0) {
const knight_square:usize = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
check_bitboard = SQUARE_BBS[knight_square];
blackKingCheckCount+=1;
}
//bishops
const bishopAttacksChecks = getBishopAttacksFast(blackKingPosition, WHITE_OCCUPANCIES_LOCAL);
temp_bitboard = bitboard_array_global[WB] & bishopAttacksChecks;
while (temp_bitboard != 0) {
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
blackKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0) {
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
//queen
temp_bitboard = bitboard_array_global[WQ] & bishopAttacksChecks;
while (temp_bitboard != 0) {
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
blackKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0) {
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
//rook
const rook_attacks = getRookAttacksFast(blackKingPosition, WHITE_OCCUPANCIES_LOCAL);
temp_bitboard = bitboard_array_global[WR] & rook_attacks;
while (temp_bitboard != 0) {
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
blackKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0)
{
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
//queen
temp_bitboard = bitboard_array_global[WQ] & rook_attacks;
while (temp_bitboard != 0) {
const piece_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square] & BLACK_OCCUPANCIES_LOCAL;
if (temp_pin_bitboard == 0) {
check_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][piece_square];
blackKingCheckCount+=1;
} else {
const pinned_square = DEBRUIJN64[MAGIC *% (temp_pin_bitboard ^ (temp_pin_bitboard - 1)) >> 58];
temp_pin_bitboard &= temp_pin_bitboard - 1;
if (temp_pin_bitboard == 0)
{
pinArray[pinNumber][PINNED_SQUARE_INDEX] = pinned_square;
pinArray[pinNumber][PINNING_PIECE_INDEX] = piece_square;
pinNumber+=1;
}
}
temp_bitboard &= temp_bitboard - 1;
}
if (blackKingCheckCount > 1) {
const occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[BK]);
temp_attack = KING_ATTACKS[blackKingPosition] & WHITE_OCCUPANCIES_LOCAL;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const bishopAttacks = getBishopAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BK;
move_count+=1;
}
temp_attack = KING_ATTACKS[blackKingPosition] & ~COMBINED_OCCUPANCIES_LOCAL;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
if ((bitboard_array_global[WP] & WHITE_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const bishopAttacks = getBishopAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BK;
move_count+=1;
}
} else {
if (blackKingCheckCount == 0) {
check_bitboard = MAX_ULONG;
}
temp_bitboard = bitboard_array_global[BP];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
if ((SQUARE_BBS[starting_square + 8] & COMBINED_OCCUPANCIES_LOCAL) == 0) { //if up one square is empty
if (((SQUARE_BBS[starting_square + 8] & check_bitboard) & temp_pin_bitboard) != 0) {
if ((SQUARE_BBS[starting_square] & RANK_2_BITBOARD) != 0) { //if promotion
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square + 8;
move_list[move_count][MOVE_TAG] = TAG_B_B_PROMOTION;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square + 8;
move_list[move_count][MOVE_TAG] = TAG_B_N_PROMOTION;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square + 8;
move_list[move_count][MOVE_TAG] = TAG_B_R_PROMOTION;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square + 8;
move_list[move_count][MOVE_TAG] = TAG_B_Q_PROMOTION;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
} else {
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square + 8;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
}
}
if ((SQUARE_BBS[starting_square] & RANK_7_BITBOARD) != 0) { //if on rank 2
if (((SQUARE_BBS[starting_square + 16] & check_bitboard) & temp_pin_bitboard) != 0) {
if (((SQUARE_BBS[starting_square + 16]) & COMBINED_OCCUPANCIES_LOCAL) == 0) { //if up two squares and one square are empty
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = starting_square + 16;
move_list[move_count][MOVE_TAG] = TAG_B_DOUBLE_PAWN;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
}
}
}
}
temp_attack = ((BLACK_PAWN_ATTACKS[starting_square] & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //if black piece diagonal to pawn
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58]; //find the bit
temp_attack &= temp_attack - 1;
if ((SQUARE_BBS[starting_square] & RANK_2_BITBOARD) != 0) { //if promotion
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_B_Q_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_B_R_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_B_N_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_B_B_PROMOTION_CAP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
} else {
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
}
}
if ((SQUARE_BBS[starting_square] & RANK_4_BITBOARD) != 0) { //check rank for ep
if (ep_global != NO_SQUARE) {
if ((((BLACK_PAWN_ATTACKS[starting_square] & SQUARE_BBS[ep_global]) & check_bitboard) & temp_pin_bitboard) != 0) {
if ((bitboard_array_global[BK] & RANK_4_BITBOARD) == 0) { //if no king on rank 5
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = ep_global;
move_list[move_count][MOVE_TAG] = TAG_BLACK_EP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
} else if ((bitboard_array_global[WR] & RANK_4_BITBOARD) == 0 and (bitboard_array_global[WQ] & RANK_4_BITBOARD) == 0) { // if no b rook or queen on rank 5 move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = ep_global;
move_list[move_count][MOVE_TAG] = TAG_BLACK_EP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
} else { //wk and br or bq on rank 5
var occupancyWithoutEPPawns = COMBINED_OCCUPANCIES_LOCAL & ~SQUARE_BBS[starting_square];
occupancyWithoutEPPawns &= ~SQUARE_BBS[ep_global - 8];
const rookAttacksFromKing = getRookAttacksFast(blackKingPosition, occupancyWithoutEPPawns);
if ((rookAttacksFromKing & bitboard_array_global[WR]) == 0) {
if ((rookAttacksFromKing & bitboard_array_global[WQ]) == 0) {
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = ep_global;
move_list[move_count][MOVE_TAG] = TAG_BLACK_EP;
move_list[move_count][MOVE_PIECE] = BP;
move_count+=1;
}
}
}
}
}
}
}
temp_bitboard = bitboard_array_global[BN];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58]; //looks for the startingSquare
temp_bitboard &= temp_bitboard - 1; //removes the knight from that square to not infinitely loop
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
temp_attack = ((KNIGHT_ATTACKS[starting_square] & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard; //gets knight captures
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BN;
move_count+=1;
}
temp_attack = ((KNIGHT_ATTACKS[starting_square] & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BN;
move_count+=1;
}
}
temp_bitboard = bitboard_array_global[BB];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
const bishopAttacks = getBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
temp_attack = ((bishopAttacks & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BB;
move_count+=1;
}
temp_attack = ((bishopAttacks & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BB;
move_count+=1;
}
}
temp_bitboard = bitboard_array_global[BR];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
const rookAttacks = getRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
temp_attack = ((rookAttacks & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BR;
move_count+=1;
}
temp_attack = ((rookAttacks & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BR;
move_count+=1;
}
}
temp_bitboard = bitboard_array_global[BQ];
while (temp_bitboard != 0) {
starting_square = DEBRUIJN64[MAGIC *% (temp_bitboard ^ (temp_bitboard - 1)) >> 58];
temp_bitboard &= temp_bitboard - 1;
temp_pin_bitboard = MAX_ULONG;
if (pinNumber != 0) {
for (0..pinNumber) |i| {
if (pinArray[i][PINNED_SQUARE_INDEX] == starting_square) {
temp_pin_bitboard = constants.INBETWEEN_BITBOARDS[blackKingPosition][pinArray[i][PINNING_PIECE_INDEX]];
}
}
}
var queenAttacks:u64 = getRookAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
queenAttacks |= getBishopAttacksFast(starting_square, COMBINED_OCCUPANCIES_LOCAL);
temp_attack = ((queenAttacks & WHITE_OCCUPANCIES_LOCAL) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BQ;
move_count+=1;
}
temp_attack = ((queenAttacks & (~COMBINED_OCCUPANCIES_LOCAL)) & check_bitboard) & temp_pin_bitboard;
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
move_list[move_count][MOVE_STARTING] = starting_square;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BQ;
move_count+=1;
}
}
temp_attack = KING_ATTACKS[blackKingPosition] & WHITE_OCCUPANCIES_LOCAL; //gets knight captures
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[BK]);
const bishopAttacks = getBishopAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = blackKingPosition;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_CAPTURE;
move_list[move_count][MOVE_PIECE] = BK;
move_count+=1;
}
temp_attack = KING_ATTACKS[blackKingPosition] & (~COMBINED_OCCUPANCIES_LOCAL); //get knight moves to emtpy squares
while (temp_attack != 0) {
target_square = DEBRUIJN64[MAGIC *% (temp_attack ^ (temp_attack - 1)) >> 58];
temp_attack &= temp_attack - 1;
if ((bitboard_array_global[WP] & BLACK_PAWN_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WN] & KNIGHT_ATTACKS[target_square]) != 0) {
continue;
}
if ((bitboard_array_global[WK] & KING_ATTACKS[target_square]) != 0) {
continue;
}
const occupancyWithoutBlackKing = COMBINED_OCCUPANCIES_LOCAL & (~bitboard_array_global[BK]);
const bishopAttacks = getBishopAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WB] & bishopAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & bishopAttacks) != 0) {
continue;
}
const rookAttacks = getRookAttacksFast(target_square, occupancyWithoutBlackKing);
if ((bitboard_array_global[WR] & rookAttacks) != 0) {
continue;
}
if ((bitboard_array_global[WQ] & rookAttacks) != 0) {
continue;
}
move_list[move_count][MOVE_STARTING] = blackKingPosition;
move_list[move_count][MOVE_TARGET] = target_square;
move_list[move_count][MOVE_TAG] = TAG_NONE;
move_list[move_count][MOVE_PIECE] = BK;
move_count+=1;
}
}
if (blackKingCheckCount == 0) {
if (castle_rights_global[BKS_CASTLE_RIGHTS] == true) {
if (blackKingPosition == E8) {
if ((BKS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) {
if ((bitboard_array_global[BR] & SQUARE_BBS[H8]) != 0) {
if (Is_Square_Attacked_By_White_Global(F8, COMBINED_OCCUPANCIES_LOCAL) == false) {
if (Is_Square_Attacked_By_White_Global(G8, COMBINED_OCCUPANCIES_LOCAL) == false) {
move_list[move_count][MOVE_STARTING] = E8;
move_list[move_count][MOVE_TARGET] = G8;
move_list[move_count][MOVE_TAG] = TAG_BCASTLEKS;
move_list[move_count][MOVE_PIECE] = BK;
move_count+=1;
}
}
}
}
}
}
if (castle_rights_global[BQS_CASTLE_RIGHTS] == true) {
if (blackKingPosition == E8) {
if ((BQS_EMPTY_BITBOARD & COMBINED_OCCUPANCIES_LOCAL) == 0) {
if ((bitboard_array_global[BR] & SQUARE_BBS[A8]) != 0) {
if (Is_Square_Attacked_By_White_Global(C8, COMBINED_OCCUPANCIES_LOCAL) == false) {
if (Is_Square_Attacked_By_White_Global(D8, COMBINED_OCCUPANCIES_LOCAL) == false) {
move_list[move_count][MOVE_STARTING] = E8;
move_list[move_count][MOVE_TARGET] = C8;
move_list[move_count][MOVE_TAG] = TAG_BCASTLEQS;
move_list[move_count][MOVE_PIECE] = BK;
move_count+=1;
}
}
}
}
}
}
}
}
if (depth == 1) {
return move_count;
}
var nodes:usize = 0;
var priorNodes:usize = undefined;
const copyEp = ep_global;
const copy_castle :[4]bool = [4]bool {
castle_rights_global[0],
castle_rights_global[1],
castle_rights_global[2],
castle_rights_global[3],
};
for (0..move_count) |move_index| {
const startingSquare = move_list[move_index][MOVE_STARTING];
const targetSquare = move_list[move_index][MOVE_TARGET];
const piece = move_list[move_index][MOVE_PIECE];
const tag = move_list[move_index][MOVE_TAG];
var captureIndex:usize = NO_SQUARE;
if (is_white_global == true) {
is_white_global = false;
} else {
is_white_global = true;
}
switch (tag) {
0, 26 => { //none
bitboard_array_global[piece] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
1, 27 => { //check cap
bitboard_array_global[piece] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
if (piece >= WP and piece <= WK) {
for (6..12) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
} else { //is black
for (WP..BP) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
}
ep_global = NO_SQUARE;
},
2 => { //white ep
//move piece
bitboard_array_global[WP] |= SQUARE_BBS[targetSquare];
bitboard_array_global[WP] &= ~SQUARE_BBS[startingSquare];
//remove
bitboard_array_global[BP] &= ~SQUARE_BBS[targetSquare + 8];
ep_global = NO_SQUARE;
},
3 => { //black ep
//move piece
bitboard_array_global[BP] |= SQUARE_BBS[targetSquare];
bitboard_array_global[BP] &= ~SQUARE_BBS[startingSquare];
//remove white pawn square up
bitboard_array_global[WP] &= ~SQUARE_BBS[targetSquare - 8];
ep_global = NO_SQUARE;
},
4 => { //WKS
//white king
bitboard_array_global[WK] |= SQUARE_BBS[G1];
bitboard_array_global[WK] &= ~SQUARE_BBS[E1];
//white rook
bitboard_array_global[WR] |= SQUARE_BBS[F1];
bitboard_array_global[WR] &= ~SQUARE_BBS[H1];
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
ep_global = NO_SQUARE;
},
5 => { //WQS
//white king
bitboard_array_global[WK] |= SQUARE_BBS[C1];
bitboard_array_global[WK] &= ~SQUARE_BBS[E1];
//white rook
bitboard_array_global[WR] |= SQUARE_BBS[D1];
bitboard_array_global[WR] &= ~SQUARE_BBS[A1];
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
ep_global = NO_SQUARE;
},
6 => { //BKS
//white king
bitboard_array_global[BK] |= SQUARE_BBS[G8];
bitboard_array_global[BK] &= ~SQUARE_BBS[E8];
//white rook
bitboard_array_global[BR] |= SQUARE_BBS[F8];
bitboard_array_global[BR] &= ~SQUARE_BBS[H8];
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
ep_global = NO_SQUARE;
},
7 => { //BQS
//white king
bitboard_array_global[BK] |= SQUARE_BBS[C8];
bitboard_array_global[BK] &= ~SQUARE_BBS[E8];
//white rook
bitboard_array_global[BR] |= SQUARE_BBS[D8];
bitboard_array_global[BR] &= ~SQUARE_BBS[A8];
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
ep_global = NO_SQUARE;
},
8 => { //BNPr
bitboard_array_global[BN] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
9 => { //BBPr
bitboard_array_global[BB] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
10 => { //BQPr
bitboard_array_global[BQ] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
11 => { //BRPr
bitboard_array_global[BR] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
12 => { //WNPr
bitboard_array_global[WN] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
13 => { //WBPr
bitboard_array_global[WB] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
14 => { //WQPr
bitboard_array_global[WQ] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
15 => { //WRPr
bitboard_array_global[WR] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
},
16 => { //BNPrCAP
bitboard_array_global[BN] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (WHITE_START_INDEX..BP) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
17 => { //BBPrCAP
bitboard_array_global[BB] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (WHITE_START_INDEX..BP) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
18 => { //BQPrCAP
bitboard_array_global[BQ] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (WHITE_START_INDEX..BP) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
19 => { //BRPrCAP
bitboard_array_global[BR] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (WHITE_START_INDEX..BP) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
20 => { //WNPrCAP
bitboard_array_global[WN] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (BP..12) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
21 => { //WBPrCAP
bitboard_array_global[WB] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (BP..12) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
22 => { //WQPrCAP
bitboard_array_global[WQ] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (BLACK_START_INDEX..12) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
23 => { //WRPrCAP
bitboard_array_global[WR] |= SQUARE_BBS[targetSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[startingSquare];
ep_global = NO_SQUARE;
for (BP..12) |i| {
if ((bitboard_array_global[i] & SQUARE_BBS[targetSquare]) != 0) {
captureIndex = i;
break;
}
}
bitboard_array_global[captureIndex] &= ~SQUARE_BBS[targetSquare];
},
24 => { //WDouble
bitboard_array_global[WP] |= SQUARE_BBS[targetSquare];
bitboard_array_global[WP] &= ~SQUARE_BBS[startingSquare];
ep_global = targetSquare + 8;
},
25 => { //BDouble
bitboard_array_global[BP] |= SQUARE_BBS[targetSquare];
bitboard_array_global[BP] &= ~SQUARE_BBS[startingSquare];
ep_global = targetSquare - 8;
},
else => {
unreachable;
}
}
if (piece == WK) {
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
} else if (piece == BK) {
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
} else if (piece == WR) {
if (castle_rights_global[WKS_CASTLE_RIGHTS] == true) {
if ((bitboard_array_global[WR] & SQUARE_BBS[H1]) == 0) {
castle_rights_global[WKS_CASTLE_RIGHTS] = false;
}
}
if (castle_rights_global[WQS_CASTLE_RIGHTS] == true) {
if ((bitboard_array_global[WR] & SQUARE_BBS[A1]) == 0){
castle_rights_global[WQS_CASTLE_RIGHTS] = false;
}
}
} else if (piece == BR) {
if (castle_rights_global[BKS_CASTLE_RIGHTS] == true) {
if ((bitboard_array_global[BR] & SQUARE_BBS[H8]) == 0) {
castle_rights_global[BKS_CASTLE_RIGHTS] = false;
}
}
if (castle_rights_global[BQS_CASTLE_RIGHTS] == true) {
if ((bitboard_array_global[BR] & SQUARE_BBS[A8]) == 0) {
castle_rights_global[BQS_CASTLE_RIGHTS] = false;
}
}
}
priorNodes = nodes;
nodes += perftInline(depth - 1, ply + 1);
is_white_global = !is_white_global;
switch (tag) {
0, 26 => { //check
bitboard_array_global[piece] |= SQUARE_BBS[startingSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[targetSquare];
},
1, 27 => { //check cap
bitboard_array_global[piece] |= SQUARE_BBS[startingSquare];
bitboard_array_global[piece] &= ~SQUARE_BBS[targetSquare];
if (piece >= WP and piece <= WK) {
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
} else { //is black
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
}
},
2 => { //white ep
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WP] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[BP] |= SQUARE_BBS[targetSquare + 8];
},
3 => { //black ep
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BP] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[WP] |= SQUARE_BBS[targetSquare - 8];
},
4 => { //WKS
//white king
bitboard_array_global[WK] |= SQUARE_BBS[E1];
bitboard_array_global[WK] &= ~SQUARE_BBS[G1];
//white rook
bitboard_array_global[WR] |= SQUARE_BBS[H1];
bitboard_array_global[WR] &= ~SQUARE_BBS[F1];
},
5 => { //WQS
//white king
bitboard_array_global[WK] |= SQUARE_BBS[E1];
bitboard_array_global[WK] &= ~SQUARE_BBS[C1];
//white rook
bitboard_array_global[WR] |= SQUARE_BBS[A1];
bitboard_array_global[WR] &= ~SQUARE_BBS[D1];
},
6 => { //BKS
//white king
bitboard_array_global[BK] |= SQUARE_BBS[E8];
bitboard_array_global[BK] &= ~SQUARE_BBS[G8];
//white rook
bitboard_array_global[BR] |= SQUARE_BBS[H8];
bitboard_array_global[BR] &= ~SQUARE_BBS[F8];
},
7 => { //BQS
//white king
bitboard_array_global[BK] |= SQUARE_BBS[E8];
bitboard_array_global[BK] &= ~SQUARE_BBS[C8];
//white rook
bitboard_array_global[BR] |= SQUARE_BBS[A8];
bitboard_array_global[BR] &= ~SQUARE_BBS[D8];
},
8 => { //BNPr
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BN] &= ~SQUARE_BBS[targetSquare];
},
9 => { //BBPr
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BB] &= ~SQUARE_BBS[targetSquare];
},
10 => { //BQPr
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BQ] &= ~SQUARE_BBS[targetSquare];
},
11 => { //BRPr
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BR] &= ~SQUARE_BBS[targetSquare];
},
12 => { //WNPr
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WN] &= ~SQUARE_BBS[targetSquare];
},
13 => { //WBPr
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WB] &= ~SQUARE_BBS[targetSquare];
},
14 => { //WQPr
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WQ] &= ~SQUARE_BBS[targetSquare];
},
15 => { //WRPr
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WR] &= ~SQUARE_BBS[targetSquare];
},
16 => { //BNPrCAP
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BN] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
17 => { //BBPrCAP
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BB] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
18 => { //BQPrCAP
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BQ] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
19 => { //BRPrCAP
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BR] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
20 => { //WNPrCAP
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WN] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
21 => { //WBPrCAP
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WB] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
22 => { //WQPrCAP
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WQ] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
23 => { //WRPrCAP
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WR] &= ~SQUARE_BBS[targetSquare];
bitboard_array_global[captureIndex] |= SQUARE_BBS[targetSquare];
},
24 => { //WDouble
bitboard_array_global[WP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[WP] &= ~SQUARE_BBS[targetSquare];
},
25 => { //BDouble
bitboard_array_global[BP] |= SQUARE_BBS[startingSquare];
bitboard_array_global[BP] &= ~SQUARE_BBS[targetSquare];
},
else => {
unreachable;
}
}
castle_rights_global[0] = copy_castle[0];
castle_rights_global[1] = copy_castle[1];
castle_rights_global[2] = copy_castle[2];
castle_rights_global[3] = copy_castle[3];
ep_global = copyEp;
//if (epGlobal != general_NO_SQUARE)
//{
// std::cout << " ep: " << SQ_CHAR_X[epGlobal] << SQ_CHAR_Y[epGlobal] << '\n';
//}
//if (ply == 0)
//{
//PrMoveNoNL(startingSquare, targetSquare);
//std.debug.print(": {}\n", .{nodes - priorNodes});
//}
}
return nodes;
}
pub fn runPerftInline(depth:i8) void {
const start_time: i64 = std.time.milliTimestamp();
const nodes = perftInline(depth, 0);
const stop_time: i64 = std.time.milliTimestamp();
const elapsed_milliseconds = stop_time - start_time;
std.debug.print("Nodes: {}\n", .{nodes});
std.debug.print("Elapsed time: {}\n", .{elapsed_milliseconds});
}
pub fn main() void {
ParseFenGlobal(FEN_STARTING_POSITION, 0);
runPerftInline(6);
}