/// Position::attackers_to_pseudo_royals computes a bitboard of all pieces
/// of a particular color attacking at least one opposing pseudo-royal piece
Bitboard Position::attackers_to_pseudo_royals(Color c) const {
+ assert(extinction_pseudo_royal());
Bitboard attackers = 0;
Bitboard pseudoRoyals = st->pseudoRoyals & pieces(~c);
Bitboard pseudoRoyalsTheirs = st->pseudoRoyals & pieces(c);
- while (pseudoRoyals) {
+ while (pseudoRoyals)
+ {
Square sr = pop_lsb(pseudoRoyals);
- if (blast_on_capture()
+ if ( blast_on_capture()
&& pseudoRoyalsTheirs & attacks_bb<KING>(sr))
// skip if capturing this piece would blast all of the attacker's pseudo-royal pieces
continue;
attackers |= attackers_to(sr, c);
}
+ // Look for duple check
+ if (var->dupleCheck)
+ {
+ Bitboard b;
+ Bitboard allAttackers = 0;
+ Bitboard pseudoRoyalCandidates = st->pseudoRoyalCandidates & pieces(~c);
+ while (pseudoRoyalCandidates)
+ {
+ Square sr = pop_lsb(pseudoRoyalCandidates);
+ if (!(blast_on_capture() && (pseudoRoyalsTheirs & attacks_bb<KING>(sr)))
+ && (b = attackers_to(sr, c)))
+ allAttackers |= b;
+ else
+ // If at least one isn't attacked, it is not a duple check
+ return attackers;
+ }
+ attackers |= allAttackers;
+ }
return attackers;
}
result = sf.gives_check("atomic", "8/8/kK6/8/8/8/Q7/8 b - - 0 1", [])
self.assertFalse(result)
+ # pseudo-royal duple check
+ result = sf.gives_check("spartan", "lgkcckw1/hhhhhhhh/1N3lN1/8/8/8/PPPPPPPP/R1BQKB1R b KQ - 11 6", [])
+ self.assertTrue(result)
+ result = sf.gives_check("spartan", "lgkcckwl/hhhhhhhh/6N1/8/8/8/PPPPPPPP/RNBQKB1R b KQ - 5 3", [])
+ self.assertFalse(result)
+ result = sf.gives_check("spartan", "lgkcckwl/hhhhhhhh/8/8/8/8/PPPPPPPP/RNBQKBNR w KQ - 0 1", [])
+ self.assertFalse(result)
+
# Shako castling discovered check
result = sf.gives_check("shako", "10/5r4/2p3pBk1/1p6Pr/p3p5/9e/1PP2P4/P2P2PP2/ER3K2R1/8C1 w K - 7 38", ["f2h2"])
self.assertTrue(result)