From: Fabian Fichter Date: Fri, 30 Apr 2021 14:50:29 +0000 (+0200) Subject: Support diagonal cannon movements X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=3317fb1d30ea501df0dd6e6afc3ec3df118f2fd5;p=fairystockfish.git Support diagonal cannon movements --- diff --git a/src/bitboard.cpp b/src/bitboard.cpp index cf7a45e..d00eb51 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -45,9 +45,10 @@ Magic CannonMagicsV[SQUARE_NB]; Magic HorseMagics[SQUARE_NB]; Magic ElephantMagics[SQUARE_NB]; Magic JanggiElephantMagics[SQUARE_NB]; +Magic CannonDiagMagics[SQUARE_NB]; Magic* magics[] = {BishopMagics, RookMagicsH, RookMagicsV, CannonMagicsH, CannonMagicsV, - HorseMagics, ElephantMagics, JanggiElephantMagics}; + HorseMagics, ElephantMagics, JanggiElephantMagics, CannonDiagMagics}; namespace { @@ -62,6 +63,7 @@ namespace { Bitboard HorseTable[0x500]; // To store horse attacks Bitboard ElephantTable[0x400]; // To store elephant attacks Bitboard JanggiElephantTable[0x1C000]; // To store janggi elephant attacks + Bitboard CannonDiagTable[0x33C00]; // To store diagonal cannon attacks #else Bitboard RookTableH[0xA00]; // To store horizontal rook attacks Bitboard RookTableV[0xA00]; // To store vertical rook attacks @@ -71,6 +73,7 @@ namespace { Bitboard HorseTable[0x240]; // To store horse attacks Bitboard ElephantTable[0x1A0]; // To store elephant attacks Bitboard JanggiElephantTable[0x5C00]; // To store janggi elephant attacks + Bitboard CannonDiagTable[0x1480]; // To store diagonal cannon attacks #endif // Rider directions @@ -252,6 +255,8 @@ void Bitboards::init_pieces() { AttackRiderTypes[pt] |= RIDER_CANNON_H; if (std::find(RookDirectionsV.begin(), RookDirectionsV.end(), d) != RookDirectionsV.end()) AttackRiderTypes[pt] |= RIDER_CANNON_V; + if (std::find(BishopDirections.begin(), BishopDirections.end(), d) != BishopDirections.end()) + AttackRiderTypes[pt] |= RIDER_CANNON_DIAG; } for (Direction d : pi->hopperQuiet) { @@ -259,6 +264,8 @@ void Bitboards::init_pieces() { MoveRiderTypes[pt] |= RIDER_CANNON_H; if (std::find(RookDirectionsV.begin(), RookDirectionsV.end(), d) != RookDirectionsV.end()) MoveRiderTypes[pt] |= RIDER_CANNON_V; + if (std::find(BishopDirections.begin(), BishopDirections.end(), d) != BishopDirections.end()) + MoveRiderTypes[pt] |= RIDER_CANNON_DIAG; } // Initialize move/attack bitboards @@ -320,6 +327,7 @@ void Bitboards::init() { init_magics(HorseTable, HorseMagics, HorseDirections, HorseMagicInit); init_magics(ElephantTable, ElephantMagics, ElephantDirections, ElephantMagicInit); init_magics(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections, JanggiElephantMagicInit); + init_magics(CannonDiagTable, CannonDiagMagics, BishopDirections, CannonDiagMagicInit); #else init_magics(RookTableH, RookMagicsH, RookDirectionsH); init_magics(RookTableV, RookMagicsV, RookDirectionsV); @@ -329,6 +337,7 @@ void Bitboards::init() { init_magics(HorseTable, HorseMagics, HorseDirections); init_magics(ElephantTable, ElephantMagics, ElephantDirections); init_magics(JanggiElephantTable, JanggiElephantMagics, JanggiElephantDirections); + init_magics(CannonDiagTable, CannonDiagMagics, BishopDirections); #endif init_pieces(); diff --git a/src/bitboard.h b/src/bitboard.h index dd3d2c7..1c105de 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -147,6 +147,7 @@ extern Magic CannonMagicsV[SQUARE_NB]; extern Magic HorseMagics[SQUARE_NB]; extern Magic ElephantMagics[SQUARE_NB]; extern Magic JanggiElephantMagics[SQUARE_NB]; +extern Magic CannonDiagMagics[SQUARE_NB]; extern Magic* magics[]; @@ -382,7 +383,7 @@ template inline Bitboard rider_attacks_bb(Square s, Bitboard occupied) { assert(R == RIDER_BISHOP || R == RIDER_ROOK_H || R == RIDER_ROOK_V || R == RIDER_CANNON_H || R == RIDER_CANNON_V - || R == RIDER_HORSE || R == RIDER_ELEPHANT || R == RIDER_JANGGI_ELEPHANT); + || R == RIDER_HORSE || R == RIDER_ELEPHANT || R == RIDER_JANGGI_ELEPHANT || R == RIDER_CANNON_DIAG); const Magic& m = R == RIDER_ROOK_H ? RookMagicsH[s] : R == RIDER_ROOK_V ? RookMagicsV[s] : R == RIDER_CANNON_H ? CannonMagicsH[s] @@ -390,6 +391,7 @@ inline Bitboard rider_attacks_bb(Square s, Bitboard occupied) { : R == RIDER_HORSE ? HorseMagics[s] : R == RIDER_ELEPHANT ? ElephantMagics[s] : R == RIDER_JANGGI_ELEPHANT ? JanggiElephantMagics[s] + : R == RIDER_CANNON_DIAG ? CannonDiagMagics[s] : BishopMagics[s]; return m.attacks[m.index(occupied)]; } @@ -399,7 +401,7 @@ inline Square lsb(Bitboard b); inline Bitboard rider_attacks_bb(RiderType R, Square s, Bitboard occupied) { assert(R == RIDER_BISHOP || R == RIDER_ROOK_H || R == RIDER_ROOK_V || R == RIDER_CANNON_H || R == RIDER_CANNON_V - || R == RIDER_HORSE || R == RIDER_ELEPHANT || R == RIDER_JANGGI_ELEPHANT); + || R == RIDER_HORSE || R == RIDER_ELEPHANT || R == RIDER_JANGGI_ELEPHANT || R == RIDER_CANNON_DIAG); const Magic& m = magics[lsb(R)][s]; // re-use Bitboard lsb for riders return m.attacks[m.index(occupied)]; } diff --git a/src/magic.h b/src/magic.h index d8f305a..33649ab 100644 --- a/src/magic.h +++ b/src/magic.h @@ -999,6 +999,128 @@ B(0x220400000A80040, 0x806080020810010C), B(0xA000200000000080, 0x1040801A0081208), }; + Bitboard CannonDiagMagicInit[SQUARE_NB] = { + B(0x811801000400, 0x312260280280202), + B(0x44A000402022680, 0x1020224880420005), + B(0x8000C80800200880, 0x2000810060080C0), + B(0x2010300240428040, 0x40240002C004E30), + B(0x1018010404010004, 0x1001010018081E0), + B(0x2042040010080090, 0x100000008410300), + B(0x400080020102000, 0x4500005300000000), + B(0x2D00C80420010200, 0x804003280020008), + B(0x8038820024420, 0x6010010080012040), + B(0x1202028004200088, 0x50018100004000C6), + B(0xA02010F0410081, 0x20013001000009A), + B(0x4013002041030588, 0x4802004110000004), + B(0x110020802000081, 0x202001800908002), + B(0x22010404103, 0x2020882080491200), + B(0x60000220400580, 0x85902800100100), + B(0x100080800050100, 0x200010220021088), + B(0x8088840404200080, 0x140011040104000), + B(0x4008508080082015, 0x8010100200580048), + B(0x4010400420201001, 0x260002080A80808), + B(0xC2002004A0008008, 0x8020082000110840), + B(0xA000A0820042400, 0x810408082100420), + B(0x80231808100004, 0x204002000800400), + B(0x8296144044004900, 0x4A1003008001840), + B(0x80A0020A0011008, 0x800104846080810), + B(0x803800801041000, 0x1030500102000404), + B(0x240C00900800850, 0x1804000108810000), + B(0x800400000088800, 0x800021801020000), + B(0x84800409300082, 0x1002D40680044000), + B(0xA110C0000200010, 0x401010001200260), + B(0x8200160204100004, 0x8040004004002022), + B(0x10001000000100C0, 0x84002811000200), + B(0x2000080020014001, 0x42002020000102), + B(0x109040044020018, 0x2020400202001000), + B(0x620000CD0108, 0x40040201008000), + B(0xA1402200A0020, 0x81400400300912), + B(0x20020CF100018020, 0x801A14086404000), + B(0x800801844001, 0x11621488425000), + B(0x10201004A8080, 0x100A000801000010), + B(0x2800411001000800, 0x80224084900020), + B(0x40400024028100, 0x501000400230060), + B(0x404808010080, 0x1201000400100004), + B(0x80802005200, 0x2000200008A0000), + B(0x20800080000022, 0x80040810002010), + B(0x40016004808240, 0x400114000801100), + B(0x8410004204240, 0x20011000604050), + B(0x8000C1009008268, 0x201004000209000), + B(0x10240C000920, 0xE000A5C14003002), + B(0x10184024280008, 0x90240802000000), + B(0x40889081081000, 0x8010050008800000), + B(0x100008C089000019, 0x802032014020010), + B(0x401C1804C00, 0x402501002002020), + B(0x200022000920D0, 0x8000800081300020), + B(0x801000400011, 0x400100044010226), + B(0x4A04010100100000, 0x500400080400000), + B(0xA000050200080000, 0x8500090001010000), + B(0x40400040001812, 0x4403000400100A0), + B(0x20C2250203020004, 0x210001C000080000), + B(0x21000408C6020001, 0x4200830012D1001), + B(0x840082016080A210, 0x2400080801081008), + B(0x40001020000, 0x4041240200083120), + B(0x2C04030010C0818, 0xA670002000818100), + B(0x4704A07085000510, 0x914001000040), + B(0x900210304100100, 0x1010004000281840), + B(0x8202920002002040, 0x810012000003), + B(0x4001400100050, 0x1144000408002000), + B(0x5900200020008100, 0x40200020002004), + B(0x301020002000480, 0x202000C0004), + B(0x20D000201104040, 0x34840100020010), + B(0x800004200080408, 0x40184200100240), + B(0x8430080100404020, 0x90042100244500), + B(0x3800100010220062, 0x50404030200218), + B(0x42E20008002020, 0x2000008200200300), + B(0xE488008280A004, 0x200001010CC80000), + B(0x6018010041109810, 0x800002000242041A), + B(0x40A8002438980, 0x8000810008208009), + B(0x401000480040100, 0x286800404002212), + B(0x821030000100009, 0x2000090200A00000), + B(0x20000100C0008028, 0x5000000100400082), + B(0x80A000048030080, 0x200000120200008), + B(0x6300280800204003, 0x48000105C0040100), + B(0x83008802420C0200, 0x2008020200080100), + B(0x1050C3102200042, 0x20103900010008), + B(0x8040902021408180, 0x12000021806200A4), + B(0x3008204008C10004, 0x680110100010401), + B(0x204321100421000, 0x400E204820494000), + B(0x8000044022404048, 0x4024010090024021), + B(0x140201424050, 0x280A000130008000), + B(0x900340808004002, 0x21026008000380), + B(0x82808000300444, 0x20002000A2001141), + B(0x140180100406002, 0x4004480001000004), + B(0x4808420800841900, 0x14008C0041000000), + B(0x2008600009000480, 0x9008020001400000), + B(0x2000100800100002, 0x2004100820210020), + B(0x2062010401A8100, 0x12200108420090), + B(0x1403188200032, 0x40048166105000), + B(0x410020020140041, 0x4400348102940040), + B(0x414040209208041, 0x4402400028B004), + B(0x8008010100421202, 0x401418002008800), + B(0x4000020010062200, 0xA02009148048000), + B(0x4443080082008B, 0x104014022801010), + B(0x42B440A0C000800, 0x9001009016111020), + B(0x400000214002, 0x8008080209020009), + B(0x480C414A001900, 0x3400100400210200), + B(0x1006008800604, 0x20240004030A050), + B(0x4C022401002A8300, 0x405008400000600), + B(0x3104000800A1042, 0x2004800204406200), + B(0xA09010280008200C, 0x4004000208C4168), + B(0x2800401120C20120, 0x4A00450200022030), + B(0x88001800304C0200, 0x204288102080000), + B(0x8044004201440101, 0x400820080C024022), + B(0xA000100C080, 0x4B40341004008081), + B(0x94802001300810, 0x140206008000800), + B(0x40002020202820, 0x280680404000040), + B(0xA820800004200, 0x80E1401012000491), + B(0x804000010020C000, 0x9403020200802000), + B(0x8C0001284201400, 0xC000100C01620800), + B(0x4010004002200414, 0x403080080200000), + B(0x140400A100800101, 0x10054C031080400), + B(0x20012C2400880082, 0x7000880020C03200), + B(0x204040300004, 0x840800041101002), + }; #undef B #endif diff --git a/src/position.cpp b/src/position.cpp index 4504b55..dbc3a65 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -890,9 +890,10 @@ Bitboard Position::attackers_to(Square s, Bitboard occupied, Color c, Bitboard j diags |= attacks_bb(~c, FERS, s, occupied) & pieces(c, KING); diags |= attacks_bb(~c, FERS, s, occupied) & pieces(c, WAZIR); diags |= attacks_bb(~c, PAWN, s, occupied) & pieces(c, SOLDIER); - diags |= attacks_bb(~c, BISHOP, s, occupied) & pieces(c, ROOK); - // TODO: fix for longer diagonals - diags |= attacks_bb(~c, ALFIL, s, occupied) & ~attacks_bb(~c, ELEPHANT, s, occupied & ~janggiCannons) & pieces(c, JANGGI_CANNON); + diags |= rider_attacks_bb(s, occupied) & pieces(c, ROOK); + diags |= rider_attacks_bb(s, occupied) + & rider_attacks_bb(s, occupied & ~janggiCannons) + & pieces(c, JANGGI_CANNON); b |= diags & diagonal_lines(); } @@ -1256,8 +1257,9 @@ bool Position::gives_check(Move m) const { Bitboard occupied = type_of(m) == DROP ? pieces() : pieces() ^ from; if (diagType && (attacks_bb(sideToMove, diagType, to, occupied) & square(~sideToMove))) return true; - // TODO: fix for longer diagonals - else if (pt == JANGGI_CANNON && (attacks_bb(sideToMove, ALFIL, to, occupied) & ~attacks_bb(sideToMove, ELEPHANT, to, occupied) & square(~sideToMove))) + else if (pt == JANGGI_CANNON && ( rider_attacks_bb(to, occupied) + & rider_attacks_bb(to, occupied & ~janggiCannons) + & square(~sideToMove))) return true; } diff --git a/src/position.h b/src/position.h index 8bd3623..f79b80f 100644 --- a/src/position.h +++ b/src/position.h @@ -1031,9 +1031,8 @@ inline Bitboard Position::attacks_from(Color c, PieceType pt, Square s) const { if (diagType) b |= attacks_bb(c, diagType, s, pieces()) & diagonal_lines(); else if (movePt == JANGGI_CANNON) - // TODO: fix for longer diagonals - b |= attacks_bb(c, ALFIL, s, pieces()) - & ~attacks_bb(c, ELEPHANT, s, pieces() ^ pieces(pt)) + b |= rider_attacks_bb(s, pieces()) + & rider_attacks_bb(s, pieces() ^ pieces(pt)) & ~pieces(pt) & diagonal_lines(); } @@ -1062,9 +1061,8 @@ inline Bitboard Position::moves_from(Color c, PieceType pt, Square s) const { if (diagType) b |= attacks_bb(c, diagType, s, pieces()) & diagonal_lines(); else if (movePt == JANGGI_CANNON) - // TODO: fix for longer diagonals - b |= attacks_bb(c, ALFIL, s, pieces()) - & ~attacks_bb(c, ELEPHANT, s, pieces() ^ pieces(pt)) + b |= rider_attacks_bb(s, pieces()) + & rider_attacks_bb(s, pieces() ^ pieces(pt)) & ~pieces(pt) & diagonal_lines(); } diff --git a/src/types.h b/src/types.h index 97aa456..38de559 100644 --- a/src/types.h +++ b/src/types.h @@ -416,7 +416,8 @@ enum RiderType : int { RIDER_HORSE = 1 << 5, RIDER_ELEPHANT = 1 << 6, RIDER_JANGGI_ELEPHANT = 1 << 7, - HOPPING_RIDERS = RIDER_CANNON_H | RIDER_CANNON_V, + RIDER_CANNON_DIAG = 1 << 8, + HOPPING_RIDERS = RIDER_CANNON_H | RIDER_CANNON_V | RIDER_CANNON_DIAG, LAME_LEAPERS = RIDER_HORSE | RIDER_ELEPHANT | RIDER_JANGGI_ELEPHANT, ASYMMETRICAL_RIDERS = RIDER_HORSE | RIDER_JANGGI_ELEPHANT, NON_SLIDING_RIDERS = HOPPING_RIDERS | LAME_LEAPERS, diff --git a/src/variants.ini b/src/variants.ini index b388f2d..0f70dbc 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -96,7 +96,7 @@ # - all base moves/atoms (W, F, etc.) # - all directional modifiers (f, b, etc.) # - unlimited distance sliders for W/R and F/B directions -# - hoppers for W/R directions, i.e., pR +# - hoppers for W/R and F/B directions, i.e., pR and pB # - lame leapers (n) for N and A directions, i.e., nN and nA ### Piece values diff --git a/tests/js/package.json b/tests/js/package.json index 51f076b..896e22d 100644 --- a/tests/js/package.json +++ b/tests/js/package.json @@ -4,7 +4,7 @@ "description": "A high performance WebAssembly chess variant library based on Fairy-Stockfish", "main": "ffish.js", "scripts": { - "test": "mocha --timeout 20000", + "test": "mocha --timeout 40000", "dev": "node index" }, "author": [