modelmate.cql
// Download modelmate.cql// PGN output when run on sample.pgn
/* black model mate, sorted by number of non-king, non-pawn white participants. A model mate is a pure mate with the additional requirement that each white piece, except possibly for king and pawns takes part. By "takes part" we mean either attacks the king's field, or gives check, or pins a potential refuter, or obstructs a potential refuter from attacking refutation square. A "potential refuter" is a black piece that could otherwise attack a "refutation square", which is the white king, or a checker, a square between a checker and the white king. When there is a double check, however, then we don't count pins by white or obstructions by white other than to the white king, since those don't affect the check. This file begins by simply including in puremate.cql without change. */ cql(input heijden.pgn) flipcolor{ mate btm KingsField= . attackedby k Checkers= A attacks k function GuardedSquares(x){ KingsField attackedby x | xray (x k KingsField)} function GuardingPieces(s) { piece fy in A s & GuardedSquares(fy)} // Every flight square guarded exactly once square all FlightSquare in KingsField & [_A] GuardingPieces(FlightSquare)==1 //Every selfblocker is either unguarded, or, if it is not double check, // (a) pinned and (b) could interfere with a checker square all SelfBlocker in KingsField & a { SelfBlockerGuards=GuardingPieces(SelfBlocker) if Checkers>1 then SelfBlockerGuards==0 else{ //single-check case SelfBlockerGuards==0 or {SelfBlockerGuards==1 pin through SelfBlocker move pseudolegal from SelfBlocker to (Checkers | between (Checkers k)) or move pseudolegal enpassant from SelfBlocker } } // end the single-check case } //end considering the SelfBlocker function Necessary(Checker){ OtherChecker=Checkers & ~Checker RefutationSquares= OtherChecker | between (OtherChecker k) NonPinnedBlackPiece= {a & ~pin} & ~k NonPinnedBlackPiece attacks RefutationSquares } if Checkers>1 then square all Checker in Checkers Necessary(Checker) /* The code above this line is identical to puremate.cql */ RefuterSquares= K | Checkers | between(Checkers k) PossibleRefuter= move from a to RefuterSquares pseudolegal WhiteParticipants= square Attacker in A Attacker in Checkers or Attacker attacks KingsField or pin through Attacker or Checkers ==1 and pin from Attacker through PossibleRefuter or Checkers ==1 and xray (PossibleRefuter Attacker RefuterSquares) [RNBQ] in WhiteParticipants //every piece participates sort "Number of eligible participating attackers: " [RNBQ] & WhiteParticipants }