index Back to help overviewhome Back to home page

CQL - Examples

Using accumulators to count passed pawns

We will show how to use :accumulate and :sumrange to look for games that have at least 3 white passed pawns in a position. A passed pawn is one which does not have an opposing pawn on its file or on adjacent files on its way to promotion. First, we give a position filter that will match any position with a white passed pawn:

; match a position with a white passed pawn
(position
  d2
  :piececount [][d3-7] 0
  :piececount [c3-7,e3-7] 0
  :shift)

Now, to find at least three white passed pawns, we add in some accumulation code:

; match a position with at least three white passed pawns
(position
  d2
  :piececount [][d3-7] 0
  :piececount [c3-7,e3-7] 0
  :shift
  :accumulate white_passer_counter
  :sumrange white_passer_counter 3 8)

Now suppose we want to find positions with at least two black passed pawns. We can use:

;match a position with at least two black passed pawns
(position
  d7
  :piececount [][d2-6] 0
  :piececount [c2-6,e2-6] 0
  :shift
  :accumulate black_passer_counter
  :sumrange black_passer_counter 2 8)

Finally, to find positions with at least two black passers and at least three white passers, we combine these lists:

; match a position with at least three white
; and at least two black passers
(position
  :sumrange white_passer_counter 3 8
  :sumrange black_passer_counter 2 8
  :and (
    (position
      d2
      :piececount [][d3-7] 0
      :piececount [c3-7,e3-7] 0
      :shift
      :accumulate white_passer_counter)
    (position
      d7
      :piececount [][d2-6] 0
      :piececount [c2-6,e2-6] 0
      :shift
      :accumulate black_passer_counter)))

We are searching for positions with at least three passed pawns.

; Find positions with at least three passed pawns.

(match
  (position
    :or (
      (position
        :sumrange counter 3 8
        Pd2
        :piececount [pP][d3-7] 0
        :piececount p[c3-7,e3-7] 0
        :shift
        :flipcolor ; accumulate* is counting each color separately
        :accumulate* counter))))

At least we should mention that these are examples to become clear about the art of :accumulate. In fact all these examples can be realized quite more efficient with the use of :pawncount.

Relation list example

The following position list searches for games in which the configuration

  • e6 e7 e4 d5

occurs shifted or flipped, but in which no pieces from the original position are on the same square as the pattern:

If one modified the :originalsamecount parameter to, say, 0 3 from its current value of 0, then it would be allowed to overlap with at most three squares of the pattern in the original position.

Examples for tagging

Consider the problem of recognizing all games in which the same rook visits all four corners of the board:

(match
  :forany rook [] ; loop over the possible rooks
  (position $rook[a1])
  (position $rook[h1])
  (position $rook[h8])
  (position $rook[a8]))

Here, the :forany keyword in the match list introduces a tag named "rook" which is constrained to range over white or black rooks, or over pawns that eventually promote to one of those.

The first position list matches games in which there is a position such that the tag "rook" represents a rook on a1. The next position list matches games in which there is a position such that the tag represents a rook on h1. The tag represents the same mark, that is, the same piece, between the position lists. The :forany keyword will sequentially bind the tag to each allowed mark.

Since a match list matches a game only if all its constituent position filters match it, the code does what we want here.

Second example, the excelsior theme: a pawn starts at the second rank and then promotes.

(match
  :forany pawn []
  (position
    :initial
    :tagmatch pawn []?[27]
    :gappedsequence ((position :movefrom $pawn :promote ))))

:tagmatch is matching pawns on second or seventh rank in start position, and the position sequence of :gappedsequence is matching if the tagged "pawn" is promoting in any subsequent game position.

Third example: the same piece delivers at least 30 checks in the game.

(match
  :forany checker 
  (position
    :btm
    :attackcount $checker  1
    :matchcount >=30
    :flipcolor))

Fourth example: knight gives mate with its first move.

(match
  :forany knight 
  (position
    :movefrom $knight
    :matchcount 1)
  (position
    :mate
    :attackcount $knight  1))

Examples for move lines

; Match positions with a mate manoeuvre in the style
; of Légal as was seen in the game Falkbeer-N.N., Vienna 1847:
; 1.e4 e5 2.f3 c6 3.d4 exd4 4.c3 dxc3 5.xc3 d6
; 6.c4 g4 7.0-0 e5 8.xe5 xd1 9.xf7+ e7 10.d5#
; We also want to find games where the defeated is already
; giving up after bishop check.

(match
  (position
    :flipcolor ; also look for the color flipped theme
    ; Remember: '!' means 'singular move'.
    :line (xe5 x xf7+ | e7! d5#)))
; Match positions with a mate manoeuvre in the style of Réti,
; as was seen in the game Réti-Tartakower, Vienna 1910:
; 1.e4 c6 2.d4 d5 3.c3 dxe4 4.xe4 f6 5.d3 e5 6.dxe5
; a5+ 7.d2 xe5 8.0-0-0 xe4 9.d8+ xd8 10.g5++ c7
; (10...Ke8 11.Rd8#) 11.d8#
; We also want to find games where the defeated is already
; giving up after queen check.

(match
  (position
    :flipcolor ; also look for the color flipped theme
    ; Remember: '!' means 'singular move'.
    :line (d8+ | xd8! :g5++  []d8#)))

; This will also find the following game:
; 1.e4 c5 2.d4 cxd4 3.c3 d5 4.exd5 xd5 5.f3 g4 6.a4+
; c6 7.xd4 d7 8.b5 0-0-0 9.xa7+ xa7 10.xa7 d1+
; 0–1 Dutch-Sugden, London 1964

Pawn endings

; One side is sacrificing two pawns in a positon with material
; balance, obtains at least one unstoppable passed pawn, and
; is winning the game.

(match
  (position
    :flipcolor    ; also look for the color flipped theme
    :result 1-0   ; White is winning the game
    :gappedsequence (
      (position
        :piececount [] 0          ; it's a pawn ending
        :powerdifference  0           ; material balance
        :pawncount  passed-!inside 0) ; no unstoppable passed pawn yet
      (position
        :btm                            ; Black to move
        :piececount [] 0           ; it's still a pawn ending
          :powerdifference  <=−2         ; two pawns less
        ; at least one unstoppable passed pawn
        :pawncount  passed-!inside >=1))))

More examples

; Smothered Mate

; A smothered mate is a checkmate delivered by a knight
; in which the mated king is unable to move because he is
; surrounded (or smothered) by his own pieces.

(match
  (position
    :flipcolor            ; either color
    :attackcount  [.] 0 ; king is smothered by own pieces
    :mate))               ; and is mate
; Allumwandlung: Match games with pawn promotions into all
; pieces. The order of position lists is not significant.

(match
  (position :promote [])
  (position :promote [])
  (position :promote [])
  (position :promote []))
; Allumwandlung: Match games with pawn promotions into all
; pieces. The order of position lists is not significant.
; It is required that all promotions are done in succession.

(match
  (position :matchconsecutive (
    (position :promote [])
    (position :promote [])
    (position :promote [])
    (position :promote [])))