constexpr Direction UpRight = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
constexpr Direction UpLeft = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
- Bitboard TRank8BB = pos.mandatory_pawn_promotion() ? rank_bb(relative_rank(Us, pos.promotion_rank(), pos.max_rank()))
- : zone_bb(Us, pos.promotion_rank(), pos.max_rank());
+ Bitboard TRank8BB = pos.sittuyin_promotion() ? Bitboard(0) : zone_bb(Us, pos.promotion_rank(), pos.max_rank());
Bitboard TRank7BB = shift<Down>(TRank8BB);
// Define squares a pawn can pass during a double step
Bitboard TRank3BB = forward_ranks_bb(Us, relative_rank(Us, pos.double_step_rank_min(), pos.max_rank()))
// Passed pawns will be properly scored later in evaluation when we have
// full attack info.
- if (passed && is_ok(s + Up) && (r < pos.promotion_rank() || !pos.mandatory_pawn_promotion()))
+ if (passed && is_ok(s + Up) && !pos.sittuyin_promotion())
e->passedPawns[Us] |= s;
// Score this pawn
- if ((support | phalanx) && (r < pos.promotion_rank() || !pos.mandatory_pawn_promotion()))
+ if ((support | phalanx) && !pos.sittuyin_promotion())
{
int v = Connected[r] * (2 + bool(phalanx) - bool(opposed)) * (r == RANK_2 && pos.captures_to_hand() ? 3 : 1)
+ 22 * popcount(support);
{
// We have already handled promotion moves, so destination
// cannot be on the 8th/1st rank.
- if (mandatory_pawn_promotion() && rank_of(to) == relative_rank(us, promotion_rank(), max_rank()))
+ if (mandatory_pawn_promotion() && rank_of(to) == relative_rank(us, promotion_rank(), max_rank()) && !sittuyin_promotion())
return false;
if ( !(pawn_attacks_bb(us, from) & pieces(~us) & to) // Not a capture
[passchess:chess]
pass = true
+
+[makhouse:makruk]
+startFen = rnsmksnr/8/pppppppp/8/8/PPPPPPPP/8/RNSKMSNR[] w - - 0 1
+pieceDrops = true
+capturesToHand = true
+firstRankPawnDrops = true
+promotionZonePawnDrops = true
+immobilityIllegal = true
"""
sf.load_variant_config(ini_text)
result = sf.legal_moves("janggi", fen, [])
self.assertEqual(result, ["e10e10"])
+ # pawn promotion of dropped pawns beyond promotion rank
+ result = sf.legal_moves("makhouse", "rnsmksnr/8/1ppP1ppp/p3p3/8/PPP1PPPP/8/RNSKMSNR[p] w - - 0 4", [])
+ self.assertIn("d6d7m", result)
+ self.assertNotIn("d6d7", result)
+
def test_short_castling(self):
legals = ['f5f4', 'a7a6', 'b7b6', 'c7c6', 'd7d6', 'e7e6', 'i7i6', 'j7j6', 'a7a5', 'b7b5', 'c7c5', 'e7e5', 'i7i5', 'j7j5', 'b8a6', 'b8c6', 'h6g4', 'h6i4', 'h6j5', 'h6f7', 'h6g8', 'h6i8', 'd5a2', 'd5b3', 'd5f3', 'd5c4', 'd5e4', 'd5c6', 'd5e6', 'd5f7', 'd5g8', 'j8g8', 'j8h8', 'j8i8', 'e8f7', 'c8b6', 'c8d6', 'g6g2', 'g6g3', 'g6f4', 'g6g4', 'g6h4', 'g6e5', 'g6g5', 'g6i5', 'g6a6', 'g6b6', 'g6c6', 'g6d6', 'g6e6', 'g6f6', 'g6h8', 'f8f7', 'f8g8', 'f8i8']
moves = ['b2b4', 'f7f5', 'c2c3', 'g8d5', 'a2a4', 'h8g6', 'f2f3', 'i8h6', 'h2h3']