Skip to content

Commit

Permalink
Merge pull request #35 from miguel-ambrona/[email protected]
Browse files Browse the repository at this point in the history
Version 2.3
  • Loading branch information
miguel-ambrona authored Jan 14, 2024
2 parents d50784f + 752cfa1 commit a038f89
Show file tree
Hide file tree
Showing 8 changed files with 1,040 additions and 803 deletions.
103 changes: 59 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ to a position, which return a list of objects (typically, positions).

- `move` (or `m` for short): performs as forward move.

- `legal`: analyzes the legality of the position and its history.
This may label the position as:
- *illegal* (FIDE illegal), when the position is unreachable from
the starting position via a sequence of legal moves (that is,
not considering FIDE Article 5.2.2 about "dead positions").
- *zombie*, when it is FIDE legal, but all possible legal retractions
are from dead positions.
- No label on if FIDE legal and non-zombie.

This command also analyzes whether a position is alive/dead when the
position is the result of a retraction or it is part of a longer sequence
of moves, possibly labeling the position as "dead".

- `DP` : labels the position as "DP" (dead position) or "alive".

- `flip`: flips the turn. This also resets the halfmove clock,
and the en-passant flags to `?` (but preserves castling rights).
The position(s) after a flip become the "game array", i.e., they
Expand All @@ -57,17 +72,17 @@ to a position, which return a list of objects (typically, positions).

- `ep` : returns the en-passant privileges of the given position.

- `DP` : labels the position as "DP" (dead position) or "alive".

- A solve command (which stops the potential `>>=` chain). The following solve
commands are supported:
- A solve command. The following solve commands are supported:
- `#[0-9]+[.5]?`: *forced mate* in the given number of moves.
- `h#[0-9]+[.5]?`: *help mate* in the given number of moves.
- `h=[0-9]+[.5]?`: *help stalemate* in the given number of moves.
- `hdp[0-9]+[.5]?`: *help dead position* in the given number of moves.
- `h~=[0-9]+[.5]?`: *help draw* (stalemate or dead) in the given number of
moves.

This transforms the position into the final position of every solution.
(The monadic chain `>>=` may continue from those.)

A solve command can be succeded (after a blank space) with a piece type in
round brackets (to choose from `p`, `n`, `b`, `r`, `q`, `k`).
This will constrain the last move to have been performed by a piece of the
Expand All @@ -81,11 +96,11 @@ For example:
```
// Julio Sunyer, 1923 (The Chess Amateur)
>>> 4k3/8/8/7K/8/8/8/8 b - - >>= r >>= r >>= h#1
g6xRh5 h8xQh5 then e8g8 h5h7#
g6xRh5 h8xQh5 e8g8 h5h7# 5rk1/8/6K1/7Q/8/8/8/8 w - - 1 2
nsols 1
// Andrew Buchanan, 2001 (1 Retros mailing list 24th Jan)
>>> k7/8/2K5/8/8/8/8/8 ? >>= turn
>>> k7/8/2K5/8/8/8/8/8 ? >>= legal >>= turn
b
nsols 1
```
Expand All @@ -96,80 +111,81 @@ nsols 1
well-formed positions (exactly one king per side, no pawns on 1st or 8th rank,
etc) even if they are illegal.
Furthermore, in virtue of FIDE Article 5.2.2, all positions preceeding a
**dead** position should be **alive**.
Our retractor still displays those that are dead, but it labels them.
*dead* position should be *alive*.
Our retractor still displays those that are dead, but it labels them if
the command `legal` is used.

- We perform minimal legality checks on a position, by checking whether it
admits at least an alive retraction.
Positions that are identified to be illegal with this simple check are labeled
as so and displayed.
admits at least a retraction.
This means at the moment our legality analysis is a semi-decision procedure.
If a position is labeled as "illegal", it is definitely illegal.
However, non-labeled positions could be legal and escape our current logic.
*We are working on making this legality check more complete*.

- Even though we display illegal and dead (retracted from dead) positions,
they do not carry on to the next command. For example, 6 possible well-formed
retractions are shown after the following command:
```
>>> 8/8/8/8/2Q5/k7/1pP5/K7 w - - >>= r
8/8/8/8/2Q5/kp6/2P5/K7 b - - ? 0 b3b2
8/8/8/8/2Q5/k1p5/1PP5/K7 b - - ? 0 (illegal) c3xPb2
8/8/8/8/2Q5/k1p5/1QP5/K7 b - - ? 0 (dead) c3xQb2
8/8/8/8/2Q5/k1p5/1RP5/K7 b - - ? 0 (dead) c3xRb2
8/8/8/8/2Q5/k1p5/1BP5/K7 b - - ? 0 (dead) c3xBb2
8/8/8/8/2Q5/k1p5/1NP5/K7 b - - ? 0 (dead) c3xNb2
>>> 8/8/8/8/2Q5/k7/1pP5/K7 w - - >>= r >>= legal
↶b3b2 8/8/8/8/2Q5/kp6/2P5/K7 b - - ? 0
↶c3xPb2 illegal dead 8/8/8/8/2Q5/k1p5/1PP5/K7 b - - ? 0
↶c3xQb2 dead 8/8/8/8/2Q5/k1p5/1QP5/K7 b - - ? 0
↶c3xRb2 dead 8/8/8/8/2Q5/k1p5/1RP5/K7 b - - ? 0
↶c3xBb2 dead 8/8/8/8/2Q5/k1p5/1BP5/K7 b - - ? 0
↶c3xNb2 dead 8/8/8/8/2Q5/k1p5/1NP5/K7 b - - ? 0
nsols 1
```
However, 5 of them were labeled as either illegal or dead.
If we then apply another command, e.g. `>>= h=1.5`, these 5 will not be
considered in the analysis, only the very first one
`8/8/8/8/2Q5/kp6/2P5/K7 b - - ? 0 b3b2`.
`8/8/8/8/2Q5/kp6/2P5/K7 b - - ? 0`.

- In case our dead position subroutine fails to determine whether a position
is *dead*, the following error message will be raised:
```
>>> B2b4/8/4k3/8/1p1p1p1p/1PpP1P1P/K1P4b/RB6 b - - 0 1 >>= hdp0
>>> B2b4/8/4k3/8/1p1p1p1p/1PpP1P1P/K1P4b/RB6 b - - 0 1 >>= DP
RuntimeError: CHA failed on B2b4/8/4k3/8/1p1p1p1p/1PpP1P1P/K1P4b/RB6 b - - 0 1
```
In a successful execution, every computation regarding dead positions is
*sound* and *correct* in the sense that the tool either finds a helpmate
(proving the position is alive) or definitely proves that the position is dead.
*sound* in the sense that the tool either finds a helpmate (proving the
position is alive) or definitely proves that the position is dead.

- FEN tokens can be unspecified with `?`, in which case, the tool will consider
all plausible values of that token. For example, the following considers that
the en-passant flag takes values `-` or `g6`.
```
>>> 6br/4Bp1k/5P2/5PpK/4B1P1/8/8/8 w - ? ? 100 >>= r
6br/4Bppk/5P2/5P1K/4B1P1/8/8/8 b - - ? 99 g7g5
nsols 1
>>> 6br/4Bp1k/5P2/5PpK/4B1P1/8/8/8 w - ? ? 100
6br/4Bp1k/5P2/5PpK/4B1P1/8/8/8 w - - ? 100
6br/4Bp1k/5P2/5PpK/4B1P1/8/8/8 w - g6 ? 100
nsols 2
```

- Not all 6 FEN tokens are necessary. If fewer tokens are specified, the
remaining will be filled with `?`. For example:
```
>>> 8/7Q/8/4BB2/2PP1P2/3NkN2/PP2P1P1/4K2R w >>= r
8/7Q/8/4BB2/2PPkP2/3N1N2/PP2P1P1/4K2R b K - ? 0 e4e3
8/7Q/8/4BB2/2PPkP2/3NPN2/PP2P1P1/4K2R b K - ? 0 e4xPe3
8/7Q/8/4BB2/2PPkP2/3NQN2/PP2P1P1/4K2R b K - ? 0 (illegal) e4xQe3
8/7Q/8/4BB2/2PPkP2/3NRN2/PP2P1P1/4K2R b K - ? 0 (illegal) e4xRe3
8/7Q/8/4BB2/2PPkP2/3NBN2/PP2P1P1/4K2R b K - ? 0 e4xBe3
8/7Q/8/4BB2/2PPkP2/3NNN2/PP2P1P1/4K2R b K - ? 0 e4xNe3
nsols 4
```
remaining will be filled with `?`.

- When the halfmove clock is specified, it will be considered in the computation
of retractions. That is, if it is specified to be `0`, the last move must have
been a capture or a pawn move. Analogously, when it is strictly positive, all
retractions will be officer non-captures.
For example:
```
>>> k7/8/2K5/8/8/8/8/8 b - - 0 50 >>= r
k7/3K4/2p5/8/8/8/8/8 w - - ? 50 d7xPc6
k7/3K4/2q5/8/8/8/8/8 w - - ? 50 d7xQc6
k7/3K4/2r5/8/8/8/8/8 w - - ? 50 d7xRc6
>>> k7/8/2K5/8/8/8/8/8 b - - 0 50 >>= r >>= legal
↶d7xPc6 k7/3K4/2p5/8/8/8/8/8 w - - ? 50
↶d7xQc6 k7/3K4/2q5/8/8/8/8/8 w - - ? 50
↶d7xRc6 k7/3K4/2r5/8/8/8/8/8 w - - ? 50
...
nsols 21
```
but
```
>>> k7/8/2K5/8/8/8/8/8 b - - 1 50 >>= r
>>> k7/8/2K5/8/8/8/8/8 b - - 1 50 >>= r >>= legal
↶d7c6 dead k7/3K4/8/8/8/8/8/8 w - - 0 50
↶d5c6 dead k7/8/8/3K4/8/8/8/8 w - - 0 50
↶b5c6 dead k7/8/8/1K6/8/8/8/8 w - - 0 50
↶c7c6 zombie k7/2K5/8/8/8/8/8/8 w - - 0 50
↶c5c6 dead k7/8/8/2K5/8/8/8/8 w - - 0 50
↶d6c6 dead k7/8/3K4/8/8/8/8/8 w - - 0 50
↶b6c6 zombie k7/8/1K6/8/8/8/8/8 w - - 0 50
nsols 0
```

Expand All @@ -181,14 +197,14 @@ nsols 1
term `half-duplex` next to the specification. For example:
```
>>> 8/8/2B5/5Q2/8/4p2P/4k2K/8 w - - >>= h#3 half-duplex
f5b1 e2f2 c6h1 e3e2 b1f1 e2f1n#
f5b1 e2f2 c6h1 e3e2 b1f1 e2f1n# 8/8/8/8/8/7P/4pk1K/5Q1B b - - 1 3
nsols 1
```
Furthermore, if the term `duplex` is specified, both WTM and BTM positions
will be considered.

- For the impatient folk, you can run Deadpos with flag `--fast` to
significtly speed-up the analysis of dead positions. This means the analysis
significantly speed-up the analysis of dead positions. This means the analysis
may miss some complicated dead positions and there is no way to know about it.
Use this flag if you want to find cooks (if they exist, they will probably
be found with this method) or you are designing a problem. However, in order
Expand All @@ -197,7 +213,6 @@ nsols 1

- You can disable the progress bar with `--no-progress-bar`.

- You can use flag `--verbose` to get a more detailed output.

## Feedback

Expand Down
4 changes: 2 additions & 2 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ get-retractor:
cd ../lib/retractor && eval `(opam env)` && dune build

test:
cat ../test/test-vectors.txt | python3 deadpos.py --verbose --no-progress-bar > /tmp/test-vectors.out
cat ../test/test-vectors.txt | python3 deadpos.py --no-progress-bar > /tmp/test-vectors.out
diff ../test/test-vectors.out /tmp/test-vectors.out

pdb-tests:
cat ../test/PDB.txt | grep -v Slow | python3 deadpos.py --verbose --no-progress-bar > /tmp/PDB.out
cat ../test/PDB.txt | grep -v Slow | python3 deadpos.py --no-progress-bar > /tmp/PDB.out
diff ../test/PDB.out /tmp/PDB.out

promote-tests:
Expand Down
Loading

0 comments on commit a038f89

Please sign in to comment.