Friday 8 March 2019

Syzygy Endgame Explorer (SEE) released

For older posts about SEE, please check the posts with label "SEE".

You can download the latest version from here (for Windows):
SEE v 0.2

Syzygy Endgame Explorer (SEE) is a software written by Árpád Rusz for "mining" the Syzygy endgame tablebases. The software is still in the early phases of development but my goal is to write a tool similar to CQL which searches tablebases instead of pgn files.

The tool can find interesting positions (e.g. mutual zugzwangs, checkmates, stalemates, fortresses), it can also identify positions where interesting moves are the only winning or drawing ones (e.g. a piece moves to a corner square or it is sacrificed, minor promotions), and it can find interesting move sequences (e.g. a knight manoeuvres from a corner square to another corner square). It can "compose" a "study" (almost) by itself. An example:


White wins

1. Kf2 Kg4 2. Ke3 Kf5 3. Kd4 Ke6 4. Kc5 Ng5 5. a4 Ke7 6. Kc6 Ne6 7. Nd5+ Kd8 8. a5 Kc8 9. a6 Kb8 10. Kb6 Ka8 11. a7


mutual zugzwang

11... Nf8 12. Nc7#

SEE is written in C++, and currently it is just a Stockfish engine with an additional UCI command "see". Now it only runs from the command line, but I am planning to add a specialized GUI too to this project.

Before you use it, you need to get some Syzygy tablebases. SEE only needs the "wdl" files.
All 3-5 man tablebases can be downloaded from here:
Syzygy345.zip

Unzip the zip file to (for example) C:\Syzygy345.
You can find other links to download the 6 and 7 man tablebases here but the tablebases up to 5 man should be enough to start "mining".

Also, you will need a text file with SEE commands.
E.g we can have a file (zz.txt) with the following pgn-style lines:

[Tablebase "KPk"]

[Position "1"]
[Piece2 "e4"]
[Eval "draw/loss"]

The usage is very simple.

1) Double click on the SEE 0.2.exe file's icon to launch the software.
2) Type in the following line to give the path for the Syzygy Tablebases:

setoption name SyzygyPath value C:\Syzygy345

or (for example)

setoption name SyzygyPath value C:\Syzygy345;D:\Syzygy6;E:\Syzygy7

if you have tablebases in more directories.

3) Type:
see zz.txt + ENTER

4) SEE will output on the screen in FEN notation the 8 possible mutual zugzwang positions from the K + P vs K endgame having the white pawn on e4.

Some other examples:

Example 1

******ex1.txt*******
[Tablebase "KPk"]
[OutputTXT "KPk.txt"]
[OutputScreen "no"]

[Position "1"]
[Piece2 "a-d"]
********************

All positions from the KPvK tablebase will be saved into a text file instead of being showed on the screen. The white pawn ('Piece2') will be placed only on the left side of the board (file a to d). The side to move by default is white.

Example 2

******ex2.txt*******
[Tablebase "KPk"]
[OutputPGN "KPk.pgn"]
[OutputScreen "no"]

[Position "1"]
[Piece1 "rank1"]
[Piece2 "fileA"]
[Eval "win"]
********************

The winning positions will be saved in a pgn file. The white king ('Piece1') will be placed only on the first rank and the white pawn ('Piece2') only on the a-file.

Example 3

******ex3.txt*******
[Tablebase "KPk"]

[Position "1"]
[SideToMove "black"]
[Eval "stalemate"]
********************

SEE will find all positions where Black is in a stalemate.

Example 4

******ex4.txt*******
[Tablebase "kKQ"]

[Position "1"]
[SideToMove "black"]
[Eval "checkmate"]
********************

SEE will find all positions where Black is checkmated. The tablebase now is K + Q vs K. The results will be ordered by the first piece (all checkmates with bKa1, followed by all checkmates with bKb1, etc.). We could enumerate the pieces in the Tablebase tag starting even by the black king because any order of the pieces is allowed.

Example 5

******ex5.txt*******
[Tablebase "Kkq"]

[Position "1"]
[Piece1 "tr"]
[Eval "checkmate"]
********************

SEE will find all positions where the white king is checkmated by the black queen. In a pawnless tablebase, it is advisable to use the constraint [Piece1 "tr"] forcing the first piece to the a1-d1-d4 triangle in order to eliminate positions which are different only by reflections or rotations.

Example 6

******ex6a.txt*******
[Tablebase "KPk"]

[Position "1"]
[Eval "win"]
[OnlyMove "yes"]
[Move "Pb7b8R"]
********************

This time we are searching for positions where the only winning move is a rook promotion on b8! There are two such positions (the wK can also be on b4):

Another way to write the commands is the following:

******ex6b.txt*******
[Tablebase "KPk"]

[Position "1"]
[Eval "win"]
[OnlyMove "yes"]
[MovedPiece "P"]
[From "b7"]
[To "b8"]
[PromotedPiece "R"]
********************

Example 7

******ex7.txt*******
[Tablebase "KBkrp"]

[Position "1"]
[Piece1 "fileE"]
[Piece2 "fileE"]
[Piece3 "fileE"]
[Piece4 "fileE"]
[Piece5 "fileE"]
[Eval "draw"]
[OnlyMove "yes"]
[Capture "no"]
********************

Now all pieces are constrained to the e-file. We are looking for positions with only drawing moves in a symmetrical setup. This move cannot be a capture. SEE will output Martin Minski's study.

Example 8

******ex8.txt*******
[Tablebase "KPk"]

[Position "1"]
The bK attacks the pawn, the wK defends it:
[Attack "3->2 1->2"]
********************

We are looking for positions where the bK attacks the pawn, and the wK defends it. The line after the [Position] keyword is a comment, and it is ignored by SEE. All lines not starting with a keyword are ignored. Don't put comments in a keyword line.

Example 9

******ex9.txt*******
[Tablebase "KPk"]

[Position "1"]
[SideToMove "black"]
[Attack "3->2"]
[NoAttack "1->2"]
[Check "no"]
********************

We are looking for positions where the bK attacks the pawn, and the wK doesn't defend it. The bK shouldn't be in check.

Example 10

******ex10.txt*******
[Tablebase "KPk"]

[Position "1"]
[WhitePawn "e4"]
[AttackedByWhite "a1"]
[NotAttackedByWhite "c3"]
[AttackedByBlack "h8"]
[Empty "g7"]
********************

This will match a position having the square a1 attacked by white, the square h8 attacked by black, the square c3 not attacked by white. The position should have a wP on e4 and an empty square g7.

Example 11

If we want all K + Q vs K positions but we try to eliminate the positions which are different only by reflections or rotations we should use 3 searches in a row:

******ex11a.txt*******
[Tablebase "KkQ"]
[OutputTXT "KQk.txt"]
[OutputScreen "no"]

[Position "1"]
[Piece1 "b1-d1-d3"]
[Piece2 "all"]
[Piece3 "all"]
********************

The lines indicating that a piece can be on all squares of the board can be safely deleted because "all" is the default value.

******ex11b.txt*******
[Tablebase "KkQ"]
[OutputTXT "KQk.txt"]
[OutputScreen "no"]

[Position "1"]
[Piece1 "a1-d4"]
[Piece2 "b1-h1-g8"]
[Piece3 "all"]
********************

******ex11b.txt*******
[Tablebase "KkQ"]
[OutputTXT "KQk.txt"]
[OutputScreen "no"]

[Position "1"]
[Piece1 "a1-d4"]
[Piece2 "a1-h8"]
[Piece3 "a1-h1-h8"]
********************

Example 12

******ex12.txt*******
[Tablebase "KPkb"]

[Position "1"]
[Eval "m1"]
********************

This search finds the "Mate in 1" positions.

Example 13

******ex13.txt*******
[Tablebase "KPkb"]

[Position "1"]
[Piece2 "e-h"]
[Eval "virtual"]
********************

This search finds the "virtual stalemate" positions. These positions look like stalemates but with the wrong side to move. Because of zugzwang, the "stalemated" side will actually win!

Example 14

******ex14.txt*******
[Tablebase "KPk"]

[Position "1"]
[Piece1 "a2-g8"]
[Piece2 "a2-g8"]
[Piece3 "a2-g8"]
********************

All pieces are on the a2-g8 diagonal.

Example 15

******ex15a.txt*******
[Tablebase "KPk"]

[Position "1"]
[Piece1 "a1"]
[Piece1 "h1"]
[Piece1 "a8"]
[Piece1 "h8"]
********************

The wK is on a corner square.

The same effect can be achieved by using the value "corners":

******ex15b.txt*******
[Tablebase "KPk"]

[Position "1"]
[Piece1 "corners"]
********************

Example 16

******ex16.txt*******
[Tablebase "KRPPkrp"]

[Position "1"]
[Piece1 "bb2282620633743360"]
[Piece2 "bb2282620633743360"]
[Piece3 "bb2282620633743360"]
[Piece4 "bb2282620633743360"]
[Piece5 "bb2282620633743360"]
[Piece6 "bb2282620633743360"]
[Piece7 "bb2282620633743360"]
********************

You can even use a bitboard to specify more complex square collections on the board (I use "Bitbord's Little Helper" by Julien Marcel to generate them). Now all pieces will be restricted to a cross-shaped space (squares d7-d3 plus c6 and e6).

Example 17

******ex17.txt*******
[Tablebase "KPkb"]

[Position "1"]
[Piece2 "b6"]
[Eval "win"]
[OnlyMove "yes"]

[Position "2"]
[Eval "checkmate"]
********************

This search finds the "Mate in 1" positions. It is similar to ex12.txt.

Example 18

******ex18.txt*******
[Tablebase "KNkn"]

[Position "1"]
[Eval "win"]
[OnlyMove "yes"]

[Position "2"]
[FEN "k7/n1K5/1N6/8/8/8/8/8"]
********************

The position which was given by the FEN tag is the following:

This search will find all positions from which this checkmate can be reached by an only winning move.

Example 19

******ex19.txt*******
[Tablebase "KRkq"]

[Position "1"]
[Eval "draw"]
[OnlyMove "yes"]
[Capture "no"]

[Position "2"]

[Position "3"]
[Eval "stalemate"]
********************

This search will find stalemate combinations like the following:

1. Re3+! Qxe3 stalemate

Example 20

******ex20a.txt*******
[Tablebase "KRkn"]
[OutputTXT "KRkn_zz.txt"]

[Position "1"]
[Eval "draw/loss"]
********************


mutual zugzwang

This search results in a list of 136 mutual zugzwang positions in the KRkn_zz.txt file. That file can be reused in another search. Let's see if any of the mutual zugzwang positions can be reached by a 10-move-long sequence of only winning moves for white!

******ex20b.txt*******
[Tablebase "KRkn"]
[OutputPGN "KRkn_zz_D10.pgn"]
[FENList "KRkn_zz.txt"]

//Move 1
[Position "1w"]
[Piece1 "a1-d1-d4"]
[Eval "win"]
[OnlyMove "yes"]
[Position "1b"]

//Move 2
[Position "2w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "2b"]

//Move 3
[Position "3w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "3b"]

//Move 4
[Position "4w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "4b"]

//Move 5
[Position "5w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "5b"]

//Move 6
[Position "6w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "6b"]

//Move 7
[Position "7w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "7b"]

//Move 8
[Position "8w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "8b"]

//Move 9
[Position "9w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "9b"]

//Move 10
[Position "10w"]
[Eval "win"]
[OnlyMove "yes"]
[Position "10b"]
[CheckFENList "yes"]
********************

The following position is found:


White wins

The "solution" of this "study" is:

1. Ke2 Ng6 2. Ke3 Kc2 3. Rb5 Kc3 4. Ke4 Nf8 5. Rd5 Ne6 6. Re5 Nd8 7. Re8 Nb7 8. Rc8+ Kd2 9. Kd4 Na5 10. Rc3 +- Now we reach a position from the list!


mutual zugzwang

Example 21

******ex21a.txt*******
[Tablebase "KPk"]
[OutputTXT "KPk.txt"]

[Position "1"]
********************

This search finds all legal positions in this tablebase (with WTM). The output file can be reused in other searches (e.g. to separate wins and draws):

******ex21b.txt*******
[Tablebase "KPk"]
[Input "KPk.txt"]
[OutputTXT "KPk_win.txt"]

[Position "1"]
[Eval "win"]
********************

******ex21c.txt*******
[Tablebase "KPk"]
[Input "KPk.txt"]
[OutputTXT "KPk_draw.txt"]

[Position "1"]
[Eval "draw"]
********************

Example 22

******ex22.txt*******
[Tablebase "KBNkq"]
[OutputPGN "positional_draw.pgn"]

[Position "1w"]
[Piece1 "a1-d1-d4"]
[Eval "draw"]
[OnlyMove "yes"]
[Identical "A"]
[Different "B"]

[Position "1b"]

[Position "2w"]
[Eval "draw"]
[OnlyMove "yes"]

[Position "2b"]

[Position "3w"]
[Eval "draw"]
[OnlyMove "yes"]
[Different "B"]

[Position "3b"]

[Position "4w"]
[Eval "draw"]
[OnlyMove "yes"]

[Position "4b"]

[Position "5w"]
[Eval "draw"]
[OnlyMove "yes"]
[Identical "A"]
********************

This search will find positional draws (fortresses, perpetual threats to build a fortress, and perpetual checks). The position should repeat only after the fifth move, not earlier. Some examples:

1. Bb2 Qh1+ 2. Ka2 Kd3 3. Ba1 Qa8+ 4. Kb1 Kc4 5. Bb2 = Fortress

1. Ka2 Qg8+ 2. Kb1 Qg1+ 3. Ka2 Qa7+ 4. Kb1 Qh7+ 5. Ka2 = Black needs to give further checks, otherwise white will build the classical fortress.

1. Ka2! Qc4+ 2. Kb1! Qf1+ 3. Ka2 Qa6+ 4. Kb1 Qd3+ 5. Ka2 = The bishop cannot be captured due a fork on e2.

1. Nd4+ Ka3 2. Nc2+ Kb3 3. Ne3+ Ka3 4. Nc2+ Ka4 5. Nd4+ = Perpetual check

Example 23

******ex23a.txt*******
[Tablebase "KRkq"]
[OutputTXT "KRkq_pin.txt"]

[Position "1"]
[Piece2 "fileD"]
[Piece3 "fileD"]
[Piece4 "fileD"]
[SideToMove "black"]
[Check "no"]
********************

This search will find all positions where the queen is pinned by the rook along the d-file.

******ex23b.txt*******
[Tablebase "KRkq"]
[OutputTXT "KRkq_pin_in_1.txt"]
[FENList "KRkq_pin.txt"]

[Position "1"]
[Eval "draw"]
[OnlyMove "yes"]

[Position "2"]
[CheckFENList "yes"]
********************

Using the results of the previous search, now we find all positions where the queen is going to be pinned by the rook along the d-file after the first move.

Example 24

******ex24a.txt*******
[Tablebase "KRkq"]
[OutputTXT "KRkq_skewer.txt"]

[Position "1"]
[Piece2 "fileD"]
[Piece3 "fileD"]
[Piece4 "fileD"]
[SideToMove "black"]
[Eval "loss"]
********************

This search will find all positions where the queen is skewered by the rook along the d-file.

******ex24b.txt*******
[Tablebase "KRkq"]
[OutputTXT "KRkq_skewer_in_1.txt"]
[FENList "KRkq_skewer.txt"]

[Position "1"]
[Eval "win"]
[OnlyMove "yes"]

[Position "2"]
[CheckFENList "yes"]
********************

Using the results of the previous search, now we find all positions where the king and queen are going to be skewered by the rook along the d-file after the first move.

Example 25

******ex25a.txt*******
[Tablebase "KRkq"]
[OutputTXT "KRkq_fork.txt"]

[Position "1"]
[Piece2 "fileD"]
[Piece3 "fileD"]
[Piece4 "fileD"]
[SideToMove "black"]
[Eval "draw"]
[Attack "2->3 2->4"]
********************

This search will find all positions where the queen and king are forked by the rook along the d-file.

******ex25b.txt*******
[Tablebase "KRkq"]
[OutputTXT "KRkq_fork_in_1.txt"]
[FENList "KRkq_fork.txt"]

[Position "1"]
[Eval "draw"]
[OnlyMove "yes"]

[Position "2"]
[CheckFENList "yes"]
********************

Using the results of the previous search, now we find all positions where the king and queen are going to be forked by the rook along the d-file after the first move.

Example 26

******ex26.txt*******
[Tablebase "KRNNkq"]
[OutputTXT "KRNNkq_mirrormate.txt"]

[Position "1"]
[Eval "checkmate"]
[SideToMove "black"]
[Piece5 "g6"]
[Empty "f5"]
[Empty "g5"]
[Empty "h5"]
[Empty "f6"]
[Empty "h6"]
[Empty "f7"]
[Empty "g7"]
[Empty "h7"]
********************

The search which uses this file finds all mirrormates with the black king on g6. In a mirrormate the checkmated king is surrounded only by empty squares.


mirrormate (Arestov, 2013)

Example 27

******ex27a.txt*******
[Tablebase "KQkq"]
[OutputTXT "KQkq_M1.txt"]
[OutputScreen "no"]

[Position "1"]
[Eval "m1"]
********************

******ex27b.txt*******
[Tablebase "KQkq"]
[Input "KQkq_M1.txt"]
[OutputTXT "KQkq_M1_double.txt"]
[OutputPGN "KQkq_M1_double.pgn"]
[OutputScreen "no"]

[Position "1"]
[SideToMove "black"]
[Eval "m1"]
********************

Using these files in two searches, we can find all positions where, having the move, both sides win by checkmate in 1.


Mate in 1 (duplex)

Other examples

The list of SEE tags:

  • [Tablebase]
  • [Input]
  • [OutputTXT]
  • [OutputPGN]
  • [OutputScreen]
  • [Position]
  • [Piece1]
  • [Piece2]
  • [Piece3]
  • [Piece4]
  • [Piece5]
  • [Piece6]
  • [Piece7]
  • [BlackKing]
  • [BlackQueen]
  • [BlackRook]
  • [BlackBishop]
  • [BlackKnight]
  • [BlackPawn]
  • [WhiteKing]
  • [WhiteQueen]
  • [WhiteRook]
  • [WhiteBishop]
  • [WhiteKnight]
  • [WhitePawn]
  • [SideToMove]
  • [Eval]
  • [OnlyMove]
  • [Move]
  • [MovedPiece]
  • [To]
  • [From]
  • [PromotedPiece]
  • [CapturedPiece]
  • [Capture]
  • [Check]
  • [Empty]
  • [AttackedByWhite]
  • [AttackedByBlack]
  • [NotAttackedByWhite]
  • [NotAttackedByBlack]
  • [Attack]
  • [NoAttack]
  • [FEN]
  • [FENList]
  • [CheckFENList]
  • [Identical]
  • [Different]
  • [Symmetry]

The list of [Eval] values:

  • "win", "draw", "loss", "not_win", "not_draw", "not_loss"
  • Any eval1/eval2 combination where the two evals takes any value from the above list. E.g. "loss/loss" means a full-point mutual zugzwang
  • "all"
  • "checkmate"
  • "stalemate"
  • "m1"
  • "virtual"

Square collections:

  • "all"
  • "none"
  • "a1", "a2",..., "h8"
  • "~a1", "~a2",..., "~h8" is the set of all squares from the board except the given square
  • "fileA", "fileB",..., "fileH"
  • "~fileA", "~fileB",..., "~fileH" is the set of all squares from the board except the given file
  • "rank1", "rank2",..., "rank8"
  • "~rank1", "~rank2",..., "~rank8" is the set of all squares from the board except the given rank
  • "a1-h8", "a2-h2", "e2-e7" etc. means the squares between two given squares (the end points are included)
  • "a-c" gives all squares from file "a", "b" and "c"
  • "1-2" gives all squares from rank "1" and "2"
  • "a4-d4-d2-a2" gives all square from a rectangular region bounded by the given four squares. Make sure you start with the upper left corner.
  • "half" = "a-d"
  • "tr" = "a1-d1-d4" a triangular region bounded by the given three squares
  • "b1-d1-d3", "a1-h1-h8", "a8-h8-a1", "a1-h1-a8", "a8-h8-h1", "b1-h1-h7", "a8-g8-a2", "a1-g1-a7", "b8-h8-h2" Yet only these predifined values are available for triangular regions.

Symmetry axes and points:

  • "fileA", "fileB",..., "fileH"
  • "rank1", "rank2",..., "rank8"
  • "a1-h8"
  • "h8-a1" (colour symmetry)
  • "d-e" (colour symmetry)
  • "4-5" (colour symmetry)
  • "d5-e5-e4-d4" (colour symmetry)

No comments: