How to Search Chess Games by Position Pattern

This guide walks you through using CQLi and Chess Query Language (CQL) to search millions of chess games for specific position patterns, checkmate types, or tactical motifs.

What you need

Step 1: Download CQLi

Download the CQLi binary for your platform from the Downloads page. Extract the zip file to any directory — no installer is required. Verify the installation by running:

cqli -version

You should see output like CQLi version 1.0.7 (c) Robert Gamble. Note that the executable name may differ depending on your platform — for example, cqli.exe on Windows or cqli-arm64 on ARM-based macOS.

Step 2: Obtain a PGN database

You need a PGN (Portable Game Notation) file to search. Some options include:

For testing, a small PGN file with a few hundred games is enough to get started. See the Resources page for more options.

Step 3: Write a CQL query

A CQL query is a plain text file with the .cql extension. The simplest queries are a single filter on one line.

For example, to find every game that ends with a checkmate delivered by an en passant capture, create a file named enpassant-mate.cql with this content:

move enpassant : mate

The move enpassant filter matches positions where the next move played is an en passant capture. The : mate makes this a speculative move filter — it evaluates the mate filter in the position that results from making that move, effectively requiring that the en passant capture delivers checkmate.

A slightly more complex example — finding all Arabian mates (king mated on a corner square by a rook defended by a knight):

mate
flipcolor flip { kh8 Nf6 Rh7 }

Here mate requires the position to be a checkmate, flipcolor handles both White and Black being checkmated, flip handles board reflections to match any corner or orientation, and the braced block specifies the exact piece configuration.

For more query examples, see the Quick Start guide and the Examples page.

Step 4: Run CQLi

From your terminal, run:

cqli -i input.pgn -o matches.pgn enpassant-mate.cql

Replace input.pgn with the path to your PGN database and matches.pgn with the desired output filename. CQLi will:

  1. Read every game from input.pgn
  2. Evaluate your query against every position in every game
  3. Write all matching games to matches.pgn
  4. Report progress and a final count of matching games

You can also pass a query directly on the command line using the -cql option:

cqli -i input.pgn -o matches.pgn -cql 'move enpassant : mate'

To limit processing to the first 100,000 games (useful when testing on a large file), add the -g option:

cqli -i input.pgn -o matches.pgn -g 1 100000 enpassant-mate.cql

Step 5: Review results

Open matches.pgn in any chess GUI — Lichess board analysis, ChessBase, SCID, or any other tool that reads PGN files. CQLi adds a {CQL} comment at the matching position in each game, so you can navigate directly to the relevant move.

For matching Lichess games with a Site tag, you can open the game directly on Lichess to see the full game with engine analysis.

Next steps