Piece variables

Just like squares can be named by square variables, pieces can be named by piece variables. A piece variable is introduced with the piece keyword, and the syntax is nearly the same as for square. (Read the section on square first, as it is similar).

For example, suppose the current position is the following:

Now, from the above current position, what pieces does the following filter represent?

piece $pinner in R
ray attack ($pinner a k)
This is a piece filter that matches a position in which a white Rook pins a black piece (and is equivalent to ray attack (R a k).)

To work out the pieces (actually, the squares on which the pieces reside) that the filter represents, we successively set $pinner to each white rook:

  • Re1 Ke3 ke5 fails because Ke3 is not a black piece
  • Ra5 bb5 ke5 succeeds
  • Re8 ne6 ke5 succeeds
  • Rh8 rg7 ke5 fails because it is not a ray attack, although it would succeed if attack was removed.
  • Rh5 pg5 pf5 ke5 fails because there are two black pieces between R and k instead of one.
Therefore, our filter represents the two white rooks on a5 and e8, or more exactly the squares [a5,e8]

A piece variable is associated with a particular piece. We write that the particular piece is bound to the piece variable in this case. The piece variable is also associated with a set of squares in a position:

  • If the piece variable's particular piece is present in the position, the piece variable's set of squares is the square on which that particular piece lies.
  • Otherwise, the piece variable's set of squares is empty
The key difference between the piece and the square filters is that the square to which a square variable is bound never changes, even as the current position changes. But the square associated with a piece variable does change as the current position changes: as the particular piece moves - or promotes - the square updates.

Another difference is that a piece variable can never represent an empty square: it can only represent a piece and the square on which that piece lies.

Syntax of piece filter

The syntax of the piece filter is almost the same as the syntax of the square filter:
piece variable_name in in_set
 filter_1
 filter_2
 ...
The piece filter matches the current position if there is some nonempty square s in the set in_set in the current position such that, when the variable_name is bound to the square s, each of the filters filter_1, filter_2... is true.

The associated set of a piece filter is the set of all squares s above such that all the filters are true.

For example, consider the following piece filter:

piece $promoting in Pa-h2
 next* $promoting on a-h8
The next* filter is true whenever its argument is true now or at some later position. Thus, since $promoting is a piece variable,
next* $promoting on a-h8
will be true in the current position whenever
$promoting on a-h8
is true, either in the current position or a later position. This last filter is true exactly when the particular piece that $promoting is bound to is on the 8th rank. Since the particular piece was initially bound to a pawn, the original piece filter checks for excelsiors: a pawn, starting on its original square, that eventually promotes.

The origin square

Each piece variable also has an associated origin square. This is the square that its particular piece was on at the time the variable was assigned to that particular piece. The origin square of a particular piece is accessed using the origin filter, which takes a single piece variable as its argument, for example
origin $promoting
Thus, to find excelsiors in which the promoting White pawn returns to its original square on the second rank, we would use the following filter:
piece $promoting in Pa-h2
 next*
     {$promoting on origin $promoting
      not P on $promoting}
Here,
$promoting on origin $promoting
means that, in the current position, the particular piece that $promoting was bound to is on the square it was on when it was first assigned to the variable $promoting. Below is a typical example:

J. Van Reek
En Passant
1987

A slightly more compact way to look for these types of excelsiors is in the examples file examples/excelsior-return.html.

Using ranges with the piece filter

A numeric range can follow the word piece in a piece filter. In that case, the piece filter only matches if the number of squares in its associated set lies within that range. Thus,
 piece 2 8 $pawn in Pa-h2
  next* move from $pawn promote A
will match a position where multiple White pawns on the second rank eventually promote (see excelsior-multiple.cql for a an example with sort and flipcolor.)

Examples