# The ray filter

The `ray` filter is used to find patterns of pieces that are arranged along a straight line.

A `ray` filter consists of the keyword `ray` followed by an optional directions followed by a list of set filters enclosed in parentheses:

```ray (A a )
ray up (A a P)
ray vertical (A A A a k)```

Note: most of the time in CQL, the simpler xray is all that is needed instead of `ray`.

A ray on the chessboard is the set of squares along a straight line from a given start point along one of the 8 basic directions .

For example, there is an `up` ray from the start point `e2`. That ray has seven squares, `e2-8`:

ray from e2 to e8

Each ray orders the squares on that ray. The ordering is determined by the direction of the ray. If squares s and t are on the ray, then s is earlier than t if t can be reached from s by moving along the ray's basic direction.

For example, in the `up` ray starting on `e2`, the square `e3` is earlier than `e7`. But in a `down` ray starting on `e8`, the square `e7` is earlier than `e2`.

The basic directions of a ray filter are the basic directions contained in the set of directions indicated by its direction parameter (recall that some directions represent a set of basic directions: `vertical` represents the set containing `up` and `down` for example. If there is no direction parameter to the `ray` filter, the direction parameter is taken to be `anydirection`, all the 8 basic directions.

Let R be the following `ray` filter:

`  ray dirs (s1 s2 ... sn)`
where dirs indicates a set of basic directions and each si is a set filter.

A ray matches the `ray` filter R if there is a sequence `S` of `n` distinct squares on the ray such that

• The `i`'th square of `S` is a member of the set represented by the set filter si
• The direction of the ray is a member of the set of basic directions indicated by dirs
• There are no pieces between two consecutive squares in S

R is also a set filter representing the set of squares `s` that terminate some sequence `S` above.

## Examples of rays

This filter is true whenever a black knight is pinned by a white rook:
`ray orthogonal (R n k)`

To match a position where some piece is pinned by a rook of either color, use:

```  flipcolor
ray orthogonal (R a k)```

Suppose the current position is the position after

```
1. e4 e5
2. Nf3 Nc6```

some rays

One ray that would match the position is

`  ray diagonal (c6 e4 f3)`

That is because starting at `c6` the ray moves diagonally, skipping over empty squares (one empty square in this case at `d5` and the reaches `e4`, and then, skipping over zero empty squares, reaches `f3`.

If this position were the current position, then `n` represents the squares `[c6,g8]`; `P` represents the squares `[a2,b2,c2,d2,e4,f2,g2,h2]` and `N` represents the squares `[f3,b1]`. Thus, the pictured ray would also match the filter

`  ray diagonal (n P N)`

Likewise, the diagram depicts a matching

`  ray (e1 e4 e5 e8)`
Therefore, the following two filters would also match the diagrammed position:
```ray up (K P p k)
ray up (K _ P p _ k)```

Some other matching rays in the position:

```ray right (r b q k)
ray northeast (R P p p r)
ray diagonal (B P h6)
ray (Q c2)
ray orthogonal (K P)```
However, the following ray filter would not match the position:
`  ray (K p)`

This is because there is a white pawn between the king at `e1` and the best target of such a ray, the black pawn at `e5`.

# Examples

The `ray` filter is used in bristol1.cql and wurzburg-plachutta.cql