Skip to content

Commit

Permalink
Fix cannonshogi (#757)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianfab authored Feb 16, 2024
1 parent 7d42030 commit 0bfa4fc
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
10 changes: 6 additions & 4 deletions src/bitboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ namespace {
const std::map<Direction, int> GrasshopperDirectionsH { {EAST, 1}, {WEST, 1} };
const std::map<Direction, int> GrasshopperDirectionsD { {NORTH_EAST, 1}, {SOUTH_EAST, 1}, {SOUTH_WEST, 1}, {NORTH_WEST, 1} };

enum MovementType { RIDER, HOPPER, LAME_LEAPER, UNLIMITED_RIDER };
enum MovementType { RIDER, HOPPER, LAME_LEAPER, HOPPER_RANGE };

template <MovementType MT>
#ifdef PRECOMPUTED_MAGICS
Expand All @@ -137,7 +137,9 @@ namespace {
if (MT != HOPPER || hurdle)
{
attack |= s;
if (limit && MT != UNLIMITED_RIDER && ++count >= limit)
// For hoppers we consider limit == 1 as a grasshopper,
// but limit > 1 as a limited distance hopper
if (limit && !(MT == HOPPER_RANGE && limit == 1) && ++count >= limit)
break;
}

Expand Down Expand Up @@ -300,7 +302,7 @@ void Bitboards::init_pieces() {
leaper |= safe_destination(s, c == WHITE ? d : -d);
}
pseudo |= sliding_attack<RIDER>(pi->slider[initial][modality], s, 0, c);
pseudo |= sliding_attack<UNLIMITED_RIDER>(pi->hopper[initial][modality], s, 0, c);
pseudo |= sliding_attack<HOPPER_RANGE>(pi->hopper[initial][modality], s, 0, c);
}
}
}
Expand Down Expand Up @@ -420,7 +422,7 @@ namespace {
// apply to the 64 or 32 bits word to get the index.
Magic& m = magics[s];
// The mask for hoppers is unlimited distance, even if the hopper is limited distance (e.g., grasshopper)
m.mask = (MT == LAME_LEAPER ? lame_leaper_path(directions, s) : sliding_attack<MT == HOPPER ? UNLIMITED_RIDER : MT>(directions, s, 0)) & ~edges;
m.mask = (MT == LAME_LEAPER ? lame_leaper_path(directions, s) : sliding_attack<MT == HOPPER ? HOPPER_RANGE : MT>(directions, s, 0)) & ~edges;
#ifdef LARGEBOARDS
m.shift = 128 - popcount(m.mask);
#else
Expand Down
4 changes: 2 additions & 2 deletions src/variants.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1662,8 +1662,8 @@ cannon = u
customPiece1 = a:pR
customPiece2 = c:mBcpB
customPiece3 = i:pB
customPiece4 = w:mRpRFAcpR
customPiece5 = f:mBpBWDcpB
customPiece4 = w:mRpRmFpB2
customPiece5 = f:mBpBmWpR2
promotedPieceType = u:w a:w c:f i:f
startFen = lnsgkgsnl/1rci1uab1/p1p1p1p1p/9/9/9/P1P1P1P1P/1BAU1ICR1/LNSGKGSNL[-] w 0 1

Expand Down
31 changes: 31 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@
customPiece3 = c:hlN
customPiece4 = d:hrN
startFen = 7/7/7/3A3/7/7/7 w - - 0 1
[cannonshogi:shogi]
dropNoDoubled = -
shogiPawnDropMateIllegal = false
soldier = p
cannon = u
customPiece1 = a:pR
customPiece2 = c:mBcpB
customPiece3 = i:pB
customPiece4 = w:mRpRmFpB2
customPiece5 = f:mBpBmWpR2
promotedPieceType = u:w a:w c:f i:f
startFen = lnsgkgsnl/1rci1uab1/p1p1p1p1p/9/9/9/P1P1P1P1P/1BAU1ICR1/LNSGKGSNL[-] w 0 1
"""

sf.load_variant_config(ini_text)
Expand Down Expand Up @@ -317,6 +330,24 @@ def test_legal_moves(self):
result = sf.legal_moves("shogun", SHOGUN, ["c2c4", "b8c6", "b2b4", "b7b5", "c4b5", "c6b8"])
self.assertIn("b5b6+", result)

# In Cannon Shogi the FGC and FSC can also move one square diagonally and, besides,
# move or capture two squares diagonally, by leaping an adjacent piece.
fen = "lnsg1gsnl/1rc1kuab1/p1+A1p1p1p/3P5/6i2/6P2/P1P1P3P/1B1U1ICR1/LNSGKGSNL[] w - - 1 3"
result = sf.legal_moves("cannonshogi", fen, [])
# mF
self.assertIn("c7b6", result)
self.assertIn("c7d8", result)
self.assertNotIn("c7d6", result)
self.assertNotIn("c7b8", result)
# pB2
self.assertIn("c7a9", result)
self.assertIn("c7e5", result)
self.assertNotIn("c7a5", result)
self.assertNotIn("c7e9", result)
# verify distance limited to 2
self.assertNotIn("c7f4", result)
self.assertNotIn("c7g3", result)

# Cambodian queen cannot capture with its leap
# Cambodian king cannot leap to escape check
result = sf.legal_moves("cambodian", CAMBODIAN, ["b1d2", "g8e7", "d2e4", "d6d5", "e4d6"])
Expand Down

0 comments on commit 0bfa4fc

Please sign in to comment.