Stalemate Tablebases

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Dries
Posts: 9
Joined: Sun Jan 17, 2021 11:26 am
Full name: Dries De Clercq

Stalemate Tablebases

Post by Dries »

Recently, I discovered that you could have a "stalemate in 1" just like you can have a "mate in 1".

Here's a nice example of a stalemate in 1.

[d]3Q4/8/B1k5/Kp6/8/b7/8/8 b - - 0 1

It's black to move and black would be lost unless he goes for the stalemate. So it makes complete sense to go for it. And black can do so. Notice that black can still move all of his 3 pieces. But after one move, black will be stalemated. Black would play 1. ...Ba3-b4+. It's the only move that would get him a draw. Now the white king is under attack and there's only one legal move for white, to capture the black bishop. White plays 2.Ka5xb4. And all the sudden, black is stalemated. It's almost like a victory for black although it's just a draw.

Here's an example of a stalemate in 2.

[d]3Q4/8/8/8/8/1kp5/8/1KB3b1 b - - 0 1

These things made me wonder. Did anyone ever made a tablebase to find all the stalemates that can be forced for a certain number of pieces?
And what would be the deepest stalemate that could be found in some particular endgame?

I don't think it's that important to build such a tablebase. But I find it very interesting. I was already considering building my own by adjusting the gaviota tablebases, since the source code was available and since it featured DTM (distance to mate).

I thought about just replacing "checkmate" with "stalemate". I mean, instead of finding all the possible checkmates from where you'd build your tablebases from, using retrograde analysis, you could start with finding all the possible stalemates. And then you could move back. What are all the positions in which one player cannot avoid a stalemate? Those would be, I suppose, "- Stalemate in 1" instead of "- Mate in 1". And from there, you could find all the positions from where you can reach a "- Stalemate in 1". And so on. So one side would want to avoid the stalemate while the other side would want to achieve it. Quite the same as with regular tablebases, but by substituting "checkmate" with "stalemate". There's some difference. Cause the player who achieves a checkmate moves last. While the player who achieves a stalemate, doesn't move last.

This would perhaps be simple enough and quite interesting by itself. Though it's not without problems. What if you can force a stalemate while you could actually have won with some other move? You'd find such positions when building such a tablebase while such positions do not seem to make to much sense. I suppose you could filter them out. That would be better already.

But there are other issues as well. What if one side could avoid giving the stalemate but he would get checkmated instead? Such positions wouldn't be found either with the previous approach. Even though it would make sense to give the stalemate to the other side if you'd lose otherwise.

One other more optional issue is this: What if one side can force a stalemate for himself even though he could have forced another way of achieving a draw? Cause why would you go for a "Stalemate in 5" or a "Stalemate in 10" if you can achieve a draw by some simple repetition?

I thought about doing these things myself at first. But that would be a bit too hard. But I guess you never know, perhaps some people would really want to achieve such a tablebase. It's far less important than a regular tablebase. But I think it would be much smaller though. And I'm sure the results would be very interesting.
Dries
Posts: 9
Joined: Sun Jan 17, 2021 11:26 am
Full name: Dries De Clercq

Re: Stalemate Tablebases

Post by Dries »

Oh yeah... and here's a stalemate in 4. But black could also reach a draw by repetition.

[d]3Q4/K1k3r1/8/3R4/8/8/8/8 b - - 0 1

1. ...Kc6 2. Kb8 Rb7 3. Ka8 Ra7 4. Kb8 Ra8 5. Kxa8

I found these positions while searching for underpromotions. In this position, white should have promoted to a Rook instead of a Queen.
User avatar
Guenther
Posts: 4605
Joined: Wed Oct 01, 2008 6:33 am
Location: Regensburg, Germany
Full name: Guenther Simon

Re: Stalemate Tablebases

Post by Guenther »

Dries wrote: Sun Feb 21, 2021 9:31 am ...

These things made me wonder. Did anyone ever made a tablebase to find all the stalemates that can be forced for a certain number of pieces?
And what would be the deepest stalemate that could be found in some particular endgame?

I don't think it's that important to build such a tablebase. But I find it very interesting. I was already considering building my own by adjusting the gaviota tablebases, since the source code was available and since it featured DTM (distance to mate).

I thought about just replacing "checkmate" with "stalemate". I mean, instead of finding all the possible checkmates from where you'd build your tablebases from, using retrograde analysis, you could start with finding all the possible stalemates. And then you could move back. What are all the positions in which one player cannot avoid a stalemate? Those would be, I suppose, "- Stalemate in 1" instead of "- Mate in 1". And from there, you could find all the positions from where you can reach a "- Stalemate in 1". And so on. So one side would want to avoid the stalemate while the other side would want to achieve it. Quite the same as with regular tablebases, but by substituting "checkmate" with "stalemate". There's some difference. Cause the player who achieves a checkmate moves last. While the player who achieves a stalemate, doesn't move last.

This would perhaps be simple enough and quite interesting by itself. Though it's not without problems. What if you can force a stalemate while you could actually have won with some other move? You'd find such positions when building such a tablebase while such positions do not seem to make to much sense. I suppose you could filter them out. That would be better already.

But there are other issues as well. What if one side could avoid giving the stalemate but he would get checkmated instead? Such positions wouldn't be found either with the previous approach. Even though it would make sense to give the stalemate to the other side if you'd lose otherwise.

One other more optional issue is this: What if one side can force a stalemate for himself even though he could have forced another way of achieving a draw? Cause why would you go for a "Stalemate in 5" or a "Stalemate in 10" if you can achieve a draw by some simple repetition?

I thought about doing these things myself at first. But that would be a bit too hard. But I guess you never know, perhaps some people would really want to achieve such a tablebase. It's far less important than a regular tablebase. But I think it would be much smaller though. And I'm sure the results would be very interesting.
I found your post quite interesting. Stalemate really is something special and a lot of people simply dislike it, as it can be considered
a bit alien, or a discontinuity inside chess rules (because it is awarded half a point).

Also searching for longest forced stalemates has some charm.

Your post inspired me to filter stalemates (with pgn-extract) out of some quality (computerchess) database and then looking at the gamelist done by SCID, because here I can see immediately how much material is left in the end position and positions with more material left are much more
interesting positions than certain endgames which simply result in stalemate by best play (pawn opposition, 2N, B+blind pawn etc.)

The first one I found (with more end material) is already very entertaining. I included the pgn too, because it shows that even very strong
programs have problems with the unexpected (probably pruning of seemingly 'crap moves'). The pgn shows the big evals until the plot
was revealed. 81...c2?? just draws and fails to forced stalemate!

[d]r4k2/3p3Q/3Pbq2/7R/5p2/2p2P2/5B2/6K1 b - - 5 1

[pgn][Event "?"]
[Site "?"]
[Date "2019.02.07"]
[Round "5644"]
[White "Fizbo 2"]
[Black "Ethereal 11.25"]
[Result "1/2-1/2"]
[ECO "B30"]
[Opening "Sicilian"]
[Variation "Nimzovich-Rossolimo attack (without ...d6)"]
[TimeControl "3600+15"]
[PlyCount "178"]

1.e4
{book}
1...c5
{book}
2.Nf3
{book}
2...Nc6
{book}
3.Bb5
{book}
3...e6
{book}
4.Bxc6
{book}
4...bxc6
{book}
5.d3
{book}
5...Ne7
{book}
6.Qe2
{book}
6...Ng6
{book}
7.h4
{book}
7...h5
{book}
8.e5
{book}
8...f6
{book}
9.Nbd2
{+0.52/21 124}
9...Qa5
{-0.71/29 547}
10.a3
{+0.44/20 79}
10...Rb8
{-0.73/29 233}
11.Qe4
{+0.68/23 93}
11...f5
{-0.62/31 264}
12.Qe3
{+0.73/23 135}
12...Ba6
{-0.52/31 234}
13.b3
{+0.73/22 112}
13...Qc3
{-0.88/31 459}
14.Ra2
{+1.07/25 104}
14...Rxb3
{-0.33/32 81}
15.O-O
{+1.07/26 107}
15...Rb7
{-0.20/31 90}
16.Ne4
{+1.01/25 88}
16...Qa5
{-0.78/30 95}
17.Bd2
{+0.95/25 145}
17...Qb6
{0.00/33 73}
18.Qg5
{+0.43/25 117}
18...Kf7
{0.00/34 55}
19.Nd6+
{+0.58/26 138}
19...Bxd6
{0.00/34 55}
20.exd6
{+0.58/1 0}
20...c4
{0.00/35 242}
21.Bc3
{+0.52/26 141}
21...Qd8
{-0.30/31 100}
22.Qe3
{+0.52/26 163}
22...cxd3
{-0.71/31 222}
23.cxd3
{+0.47/26 180}
23...Qb6
{-0.66/28 49}
24.Ne5+
{+1.50/26 88}
24...Nxe5
{-0.79/35 145}
25.Qxe5
{+1.50/1 0.015}
25...Rg8
{-0.97/33 50}
26.Rb2
{+1.67/27 111}
26...Qd8
{-1.18/30 40}
27.Rxb7
{+1.66/27 87}
27...Bxb7
{-0.96/34 44}
28.Rb1
{+1.65/29 139}
28...Ba8
{-1.00/32 44}
29.Qc5
{+1.77/28 119}
29...Kg6
{-1.06/27 31}
30.Rb4
{+1.77/26 119}
30...Kh7
{-0.99/32 38}
31.a4
{+1.77/27 158}
31...a6
{-0.80/30 95}
32.Kh2
{+2.06/25 145}
32...g5
{-0.82/31 42}
33.g3
{+1.86/25 112}
33...Kg6
{-0.80/30 32}
34.hxg5
{+1.86/25 81}
34...Qxg5
{-0.57/31 63}
35.Rf4
{+1.78/24 118}
35...Rb8
{0.00/28 36}
36.Bd4
{+1.66/24 88}
36...Re8
{-0.53/28 94}
37.Qa7
{+1.54/22 78}
37...Qd8
{-0.34/29 45}
38.Qc5
{+1.52/23 71}
38...Qg5
{-0.37/27 20}
39.Bb2
{+1.63/24 153}
39...Rb8
{-0.74/30 67}
40.Bc3
{+1.54/23 49}
40...Kf7
{-0.18/29 45}
41.d4
{+1.45/23 121}
41...Rb1
{-0.21/30 70}
42.Bd2
{+1.16/23 50}
42...Qf6
{-0.55/30 54}
43.Be3
{+1.21/25 62}
43...Qg6
{-0.32/30 40}
44.Rh4
{+1.16/24 45}
44...Qg7
{-0.12/28 24}
45.Rf4
{+1.16/24 55}
45...Qg6
{-0.13/25 23}
46.Qc2
{+1.38/24 67}
46...Ra1
{0.00/32 22}
47.Qc3
{+0.91/25 48}
47...Rd1
{0.00/34 24}
48.Qb3
{+0.90/25 51}
48...Ra1
{0.00/35 16}
49.Qb8
{+1.41/25 46}
49...Qg8
{-0.65/30 30}
50.Qb2
{+1.16/25 36}
50...Re1
{-0.71/27 33}
51.Qd2
{+1.65/25 42}
51...Ra1
{-0.61/27 16}
52.Qc3
{+1.19/26 38}
52...Rb1
{-0.64/28 23}
53.Qd3
{+1.07/25 76}
53...Rb8
{-0.27/28 52}
54.Qxa6
{+1.08/24 69}
54...c5
{-0.10/25 20}
55.Qd3
{+0.96/24 49}
55...Qg7
{0.00/28 13}
56.Qd1
{+1.05/20 23}
56...c4
{0.00/31 20}
57.a5
{+0.87/21 50}
57...h4
{0.00/31 20}
58.g4
{+0.03/22 53}
58...Bd5
{0.00/30 47}
59.Qc1
{+0.01/23 28}
59...Kg8
{+0.96/26 46}
60.f3
{-0.47/21 22}
60...Rb5
{+1.50/27 35}
61.Qd2
{-0.73/20 16}
61...Rb3
{+1.10/24 17}
62.a6
{-0.94/21 26}
62...Ra3
{+1.30/27 26}
63.Qf2
{-0.98/22 12}
63...Qf6
{+0.90/25 25}
64.Kh3
{-0.82/19 15}
64...Rxa6
{+1.02/29 21}
65.gxf5
{-1.06/19 13}
65...exf5
{+1.43/28 18}
66.Rxh4
{-1.45/21 16}
66...Ra3
{+1.52/30 13}
67.Qe2
{-1.31/21 14}
67...Be6
{+1.41/29 11}
68.Bf2
{-1.59/20 13}
68...Kf7
{+2.57/30 56}
69.Kg2
{-2.01/19 13}
69...c3
{+3.66/27 45}
70.d5
{-1.66/20 18}
70...Bxd5
{+3.85/25 17}
71.Rh7+
{-2.34/20 14}
71...Kg6
{+2.97/26 13}
72.Rh3
{-2.58/22 21}
72...Be6
{+3.62/25 12}
73.Qb5
{-2.58/20 7.5}
73...Kf7
{+3.45/26 28}
74.Rh7+
{-2.88/20 17}
74...Kg8
{+3.17/27 14}
75.Rh3
{-2.88/22 16}
75...Ra8
{+3.59/26 11}
76.Qb7
{-2.82/22 13}
76...Re8
{+3.49/26 17}
77.Qb1
{-3.42/22 18}
77...Kf8
{+3.59/27 17}
78.Kg1
{-3.01/18 15}
78...f4
{+6.55/30 35}
79.Rh5
{-4.73/21 18}
79...Rc8
{+7.53/28 17}
80.Qc2
{-4.75/21 11}
80...Ra8
{+7.88/30 15}
81.Qh7
{-6.31/22 16}
81...c2
{+7.96/28 15}
82.Qxc2
{-6.82/22 14}
82...Qg7+
{+7.77/27 15}
83.Kh2
{-3.72/22 20}
83...Ra2
{+7.58/15 15}
84.Qc8+
{-1.71/22 12}
84...Kf7
{+7.87/15 15}
85.Kh1
{-1.72/24 14}
85...Rxf2
{+7.68/11 15}
86.Rf5+
{0.00/26 14}
86...Kg6
{+3.72/25 15}
87.Rg5+
{0.00/25 14}
87...Kxg5
{0.00/31 15}
88.Qc5+
{0.00/27 17}
88...Kh4
{0.00/31 15}
89.Qh5+
{0.00/30 14}
89...Kxh5
{0.00/43 8.2 Draw by stalemate}
1/2-1/2[/pgn]

Huge problems for SF12 finally starting a big fail low since depth 33

(for readabilty I have kept just the main depth lines until depth 33)

Code: Select all

Version: WinBoard 4.9.1 + Stockfish_12-64
2410 >first : memory 272
2410 >first : egtpath syzygy C:\Syzygy_5
2410 >first : setboard r4k2/3p3Q/3Pbq2/7R/5p2/2p2P2/5B2/6K1 b - - 5 1
5090 <first : 0 0 0 0 NNUE evaluation using nn-82215d0fd0df.nnue enabled

5090 <first :   1     366      0        121 f6g7 h7g7 f8g7
5090 <first :   2     514      0        173 f6g7 h7g7 f8g7 g1h2
5100 <first :   3     385      0        253 f6g7 h7g7 f8g7 g1h2 a8f8
5100 <first :   4     432      0        362 f6g7 h7g7 f8g7 f2d4 g7g6 d4c3
5100 <first :   5     462      0        455 f6g7 h7g7 f8g7 f2d4 g7g6 d4c3
5100 <first :   6     448      0       1845 a8a2 g1g2 f6g7 h7g7 f8g7 h5c5 a2c2
5100 <first :   7     397      0       2552 a8a2 g1g2 f6g7 h7g7 f8g7 h5c5 a2c2 c5g5 g7f6 g5c5
5100 <first :   8     455      1       3573 a8a2 g1g2 a2d2 h5c5 d2f2 g2f2
5110 <first :   9     395      2       7603 a8a1 g1g2 a1a2 h7h8 f6h8 h5h8 f8f7 h8c8 a2c2 c8c7 f7g6 c7c5
5110 <first :  10     460      3      10921 a8a1 g1g2 a1a2 h7h8 f6h8 h5h8 f8f7 h8c8 c3c2
5160 <first :  11     167      8      33064 a8c8 h5c5 c8c5 h7e7 f6e7 d6e7 f8e7 f2c5 e7f7 c5d6 e6d5 d6f4 d5f3
5210 <first :  12     440     12      53323 a8a1 g1h2 c3c2 h5c5 c2c1q c5c1 a1c1 h7e7 f6e7 d6e7 f8e7
5270 <first :  13     314     18      85656 a8a1 g1g2 a1a2 h7e7 f6e7 h5h8 f8f7 h8h7 f7g6 d6e7 a2a8 f2d4 g6h7 d4c3 e6f7 g2g1 a8a2
5310 <first :  14     437     22     104393 a8a1 g1h2 c3c2 h5c5 c2c1q c5c1 a1c1 h7e7 f6e7 d6e7 f8e7
5540 <first :  15     189     45     217682 a8a1 g1h2 c3c2 h7c2 a1a2 c2c5 f6g6 h5h8 f8f7 h2h1 a2a1 h1h2 a1f1 c5d4 g6f5 d4c5 f5c5 f2c5 f1f3
6800 <first :  16      38    171     774919 f6g7 h7g7 f8g7 h5c5 a8a1 g1g2 a1d1 c5c3 g7f6 c3c8 f6f5 f2c5 f5e5 g2f2 d1a1 c8d8 a1a2 f2e1
7730 <first :  17      28    265    1160999 f6g7 h7g7 f8g7 h5c5 a8a1 g1g2 a1d1 c5c3 e6d5 f2h4 g7g6 g2f2 d1h1 h4e7 h1h2 f2g1 h2d2 g1f1 d2d4 f1e1 d5c6 e1e2 d4b4
8750 <first :  18      54    366    1601004 a8a1 g1h2 a1a2 h5c5 f6g7 h7h4 g7g3 h4g3 f4g3 h2g3 c3c2 f3f4 e6b3 f2d4 a2a4 d4b2 f8f7 g3f3 f7e6 f3e3 e6d6 c5h5 a4b4 h5g5
9210 <first :  19     100    413    1821635 a8a1 g1h2 f6g7 h7e4 c3c2 e4f4 f8e8 h5b5 a1b1 b5a5 e6d5 a5d5 c2c1q f4e4 e8d8 f2h4 d8c8 d5c5 c8b8 c5c1 b1c1 h4f2 g7h6 h2g2 h6d6 e4e3
10270 <first :  20      50    519    2314592 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 h5f5 f8g8 c2c8 g8h7 f5h5 h7g6 c8c5 g7f6 h2g2 e6f5 h5h2 a2c2 c5b4 g6g5 g2f1 f5d3 f1g1 f6a1 b4e1 a1e1 f2e1
10330 <first :  21     141    524    2339869 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 h5f5 f8g8 c2c8 g8h7 f5h5 h7g6 c8c5 g7f6 h2g2 e6f5 h5h2 a2c2 c5b4 f5d3 b4a3 f6g5 g2h1 g5d5 h2g2 g6f5 a3a4 d5f3 a4d7 f5e5
10460 <first :  22     405    537    2413901 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 g7h6 f4h4 h6d6 h2g2 d6d2 h4e4 e8d8 g2g3 d2g5 e4g4
10790 <first :  23     371    570    2619152 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 h5f5 f8g8 c2c8 g8h7 f5h5 h7g6 c8c5 a2f2 h2g1 f2c2 c5g5 g6f7 g5g7 f7g7 h5h4 g7f6 h4f4 f6e5 f4a4 e6d5 f3f4 e5e6 a4a3 c2g2 g1f1 g2g4 f1e1 g4f4
11630 <first :  24     455    655    3237267 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 h5f5 f8g8 c2c8 g8h7 f5h5 h7g6 c8c5 a2f2 h2g1 f2c2 h5g5 g6h6 g5g7 c2c5 g7g2 c5g5 g1f2 g5g2 f2g2 h6g6 g2g1 g6f6 g1f1 f6e5 f1e1 e5d6
12880 <first :  25     494    779    4196397 c3c2 h5c5 a8a1 g1h2 c2c1r h7e7 f6e7 d6e7 f8e7 c5c1 a1c1 f2d4 e7d6 h2g2 e6d5 d4f6 d6e6 f6g7 e6f5 g7f8 d5f3 g2f3 c1c3 f3f2 f5e4
13940 <first :  26     512    885    4966979 c3c2 h5c5 a8a1 g1g2 c2c1q h7e7 f6e7 d6e7 f8e7 c5c1 a1c1 f2h4 e7d6 g2f2 c1c2 f2e1 e6d5 e1d1 c2h2 h4g5 d5f3 d1c1 d6e5 g5e7 h2g2 e7b4 d7d5 b4c3 e5e4
16720 <first :  27     553   1163    7113918 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 a2d5 h2h3 d5e6 h3h2 g7h6 f4h4 h6f6 h2g3 f6g5 h4g4 e6g4 f3g4 g5e5 g3f3 e5d6 g4g5 e8f7 f2e3 d6d5 f3g3 d5d3 g3f4 f7e6 g5g6 d3f5 f4g3
19030 <first :  28     551   1394    8801026 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 a2d5 h2h3 d5e6 h3h2 g7e5 h2g3 e5g5 f4g4 e6g4 f3g4 g5e5 g3f3 e5d6 f2e3 e8f7 f3e2 d6c6 g4g5 c6e4 e2f2 f7e6
22320 <first :  29     569   1723   11219094 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 a2d5 h2h3 d5e6 h3h2 g7e5 h2g3 e5g5 f4g4 e6g4 f3g4 g5e5 g3f3 e5d5 f3g3 d5d3 g3f4 d3d6 f4e4 e8f7 e4f3 d6d3 f3f4 d7d5 f2h4 f7e6 h4d8 d5d4 g4g5 d3f5 f4g3 d4d3
24810 <first :  30     569   1972   12986720 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 a2d5 h2h3 d5e6 h3h2 g7e5 h2g3 e5g5 f4g4 e6g4 f3g4 g5e5 g3f3 e5d5 f3g3 d5d3 g3f4 d3d6 f4e4 e8f7 e4f3 d6d3 f3f4 d7d5 f2h4 f7e6 h4d8 d5d4 f4g5 d3c4 g5g6 d4d3
32290 <first :  31     579   2721   17991535 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 a2d5 h2h3 d5e6 h3h2 g7e5 h2g3 e5g5 f4g4 e6g4 f3g4 g5e5 g3f3 e5d5 f3f4 d5d6 f4e4 e8f7 e4f3 d6d3 f3g2 f7e6 f2h4 d3e4 g2g3 e4e3 g3g2 d7d5 h4d8 d5d4 g4g5
47270 <first :  32     652   4218   28427499 c3c2 h7c2 f6g7 g1h1 a8a1 h1h2 a1a2 c2a2 e6a2 h5f5 f8e8 f5f4 a2d5 f2h4 g7b2 h2g3 b2c1 h4e7 c1g1 g3h4 g1f2 h4h5 d5f7 h5h6 f2d2 h6g5 f7e6 e7f6 d2e3 f6d4 e3e2 g5g6 e2g2 g6f6 g2h2
49160 <first :  33     644   4408   29522452 c3c2 h7c2
49170 <first : ?
49570 <first :  33     636   4448   29767364 c3c2 h7c2
49570 <first : ?
49950 <first :  33     624   4486   29974770 c3c2 h7c2
49950 <first : ?
50410 <first :  33     606   4532   30268826 c3c2 h7c2
50410 <first : ?
51140 <first :  33     581   4606   30711328 c3c2 h7c2
51150 <first : ?
52270 <first :  33     549   4719   31247951 c3c2 h7c2
52280 <first : ?
https://rwbc-chess.de

trollwatch:
Chessqueen + chessica + AlexChess + Eduard + Sylwy
User avatar
Guenther
Posts: 4605
Joined: Wed Oct 01, 2008 6:33 am
Location: Regensburg, Germany
Full name: Guenther Simon

Re: Stalemate Tablebases

Post by Guenther »

This is beautiful too! 67.Qxe6?? leads to forced stalemate draw.

[d]7k/6rP/2p1p3/2Pp1qN1/PP1P1P2/4Q3/3BK2R/1r6 w - - 1 67

[pgn][Event "?"]
[Site "?"]
[Date "2020.04.08"]
[Round "66188"]
[White "Deep Shredder 13"]
[Black "SlowChess Blitz Classic 2.0"]
[Result "1/2-1/2"]
[ECO "B03"]
[Opening "Alekhine's defense"]
[Variation "Four pawns attack, Trifunovic Variation"]
[TimeControl "3600+15"]
[PlyCount "141"]

1.e4
{book}
1...Nf6
{book}
2.e5
{book}
2...Nd5
{book}
3.d4
{book}
3...d6
{book}
4.c4
{book}
4...Nb6
{book}
5.f4
{book}
5...Bf5
{book}
6.Nc3
{book}
6...e6
{book}
7.Nf3
{book}
7...Be7
{book}
8.Be3
{book}
8...O-O
{book}
9.Bd3
{+0.32/30 135}
9...Bxd3
{-0.88/24 214}
10.Qxd3
{+0.38/30 84}
10...d5
{-0.80/26 129}
11.c5
{+0.39/31 113}
11...Nc4
{-0.44/27 129}
12.Bf2
{+0.39/31 77}
12...Nc6
{-0.56/25 97}
13.b3
{+0.37/32 104}
13...Nb4
{-0.60/27 141}
14.Qe2
{+0.38/30 72}
14...Na3
{-0.64/26 96}
15.Rc1
{+0.36/32 78}
15...Qe8
{-0.64/25 155}
16.O-O
{+0.47/29 86}
16...b6
{-0.64/25 94}
17.Rfd1
{+0.38/29 82}
17...a5
{-0.60/25 94}
18.Qb2
{+0.37/31 193}
18...Nb5
{-0.80/25 86}
19.Na4
{+0.38/29 78}
19...Rb8
{-0.48/25 63}
20.Qd2
{+0.33/28 76}
20...Na3
{-0.60/23 102}
21.h3
{+0.32/31 117}
21...b5
{-0.64/23 62}
22.Nb2
{+0.32/33 69}
22...Nc6
{-0.52/25 62}
23.Re1
{+0.32/39 140}
23...Qd7
{-0.52/23 62}
24.Re2
{+0.33/32 220}
24...b4
{-0.55/24 146}
25.Na4
{+0.38/32 87}
25...Qc8
{-0.56/24 60}
26.Qd3
{+0.39/29 53}
26...Kh8
{-0.57/23 60}
27.g4
{+0.42/31 49}
27...g6
{-0.68/23 60}
28.Kg2
{+0.41/28 73}
28...Ra8
{-0.68/22 60}
29.h4
{+0.57/27 78}
29...Rg8
{-0.76/23 89}
30.Rh1
{+0.76/27 103}
30...h6
{-0.76/22 48}
31.Ree1
{+0.87/25 71}
31...Kh7
{-1.12/22 53}
32.Qd2
{+0.94/27 93}
32...Qa6
{-1.33/23 106}
33.Be3
{+0.98/27 81}
33...Rg7
{-1.20/21 47}
34.h5
{+1.12/29 124}
34...gxh5
{-1.87/21 137}
35.g5
{+1.60/28 74}
35...Rg6
{-2.05/23 73}
36.Rxh5
{+1.60/27 89}
36...Bf8
{-2.05/23 45}
37.Kf2
{+2.12/27 61}
37...Kh8
{-1.92/22 49}
38.gxh6
{+2.10/29 84}
38...Be7
{-2.04/22 65}
39.h7
{+2.02/29 110}
39...Nb5
{-1.60/24 57}
40.Reh1
{+2.14/30 57}
40...Nc3
{-1.96/23 68}
41.Nxc3
{+2.51/29 111}
41...bxc3
{-2.16/21 24}
42.Qxc3
{+2.69/29 106}
42...Nb4
{-2.32/22 44}
43.Ng5
{+2.75/28 69}
43...Nd3+
{-2.36/21 44}
44.Kg3
{+2.67/30 30}
44...Rg7
{-2.67/22 91}
45.a3
{+3.20/27 29}
45...f5
{-2.88/21 50}
46.exf6
{+3.41/27 60}
46...Bxf6
{-3.96/22 86}
47.Qd2
{+3.88/28 96}
47...Rb8
{-4.04/21 42}
48.Rh6
{+4.01/29 67}
48...Rf8
{-3.96/21 42}
49.Rxf6
{+4.29/28 58}
49...Rxf6
{-4.24/21 44}
50.Rd1
{+4.13/29 60}
50...Nb2
{-4.48/21 67}
51.Qxb2
{+4.41/28 44}
51...Rh6
{-4.68/21 41}
52.Rd2
{+4.46/30 40}
52...Qb5
{-4.56/22 92}
53.Qc2
{+4.60/29 28}
53...c6
{-4.96/24 85}
54.Rf2
{+5.11/29 185}
54...Rf6
{-5.04/20 38}
55.Kg2
{+5.18/26 21}
55...Rh6
{-5.52/24 86}
56.Kf3
{+5.25/27 34}
56...Rh5
{-5.20/20 37}
57.a4
{+5.55/25 19}
57...Qb8
{-5.24/22 44}
58.Ke2
{+5.66/25 32}
58...Rh1
{-6.08/23 128}
59.Qd3
{+5.80/23 17}
59...Rg1
{-7.04/22 118}
60.Bd2
{+6.31/26 83}
60...Qf8
{-6.96/21 53}
61.Bxa5
{+6.39/26 24}
61...Rb7
{-6.92/20 30}
62.Qh3
{+6.98/26 49}
62...Rg7
{-9.04/24 143}
63.Bd2
{+7.74/25 32}
63...Qe8
{-8.08/20 26}
64.Rh2
{+9.03/23 15}
64...Qg6
{-7.40/21 42}
65.Qe3
{+8.19/26 14}
65...Rb1
{-9.52/25 57}
66.b4
{+9.37/27 33}
66...Qf5
{-7.00/20 19}
67.Qxe6
{+10.00/28 26}
67...Re7
{0.00/26 19}
68.Qxe7
{0.00/36 16}
68...Re1+
{0.00/31 19}
69.Kxe1
{0.00/39 15}
69...Qb1+
{0.00/36 19}
70.Kf2
{0.00/53 13}
70...Qg1+
{0.00/35 14}
71.Kxg1
{0.00/62 25 Draw by stalemate}
1/2-1/2[/pgn]
https://rwbc-chess.de

trollwatch:
Chessqueen + chessica + AlexChess + Eduard + Sylwy
Dries
Posts: 9
Joined: Sun Jan 17, 2021 11:26 am
Full name: Dries De Clercq

Re: Stalemate Tablebases

Post by Dries »

Those are impressive stalemates. When I look at them, they made little sense at first just as well. Seems like senseless sacrifices. But they're not. I can imagine a chess engine may look over such "weird moves".
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Stalemate Tablebases

Post by hgm »

The FairyGen EGT generator has an option to consider stalemating a win. But not one to consider it a loss. Like you say, it is an entirely different case, with the opposit player to move.

I suppose it would have to be done by first doing the initialization for the reverse end-game, to find the stalemates. And then build the EGT for the end-game itself, but seed the identified stalemates as wins for the stalemated side. Depending on the way you want to treat checkmates by that side, you could also seed these as wins in the normal way, or use the stalemated positions as the only won seeds. And then start the retrograde generation from there.

I did something similar once for identifying 'fortress draws'. Which I defined as ways for the weak side to prevent losing that would not capture one of the pieces of the strong side. (Which would be 'tactical draws'.) I did that by first generating the EGT for the reverse end-game, while treating every conversion to a non-lost position in a successor end-game with fewer pieces for the strong side(as well as normal checkmates) as a win. What then is left as a non-win must be a fortress draw.
Dries
Posts: 9
Joined: Sun Jan 17, 2021 11:26 am
Full name: Dries De Clercq

Re: Stalemate Tablebases

Post by Dries »

Yes, I seem to understand a bit what you mean about your strategy of finding fortresses. Cause when a piece is captured in a fortress, it's not a loss for the weak side. So by first finding the captures that result in a win for the strong side, those that remain could then later on be seen as a win for the side who wants to achieve the fortress. I'm not totally sure I understand though. I sure have some difficulty in relating this to these stalemate tablebases. I didn't think it totally through. But I thought about it a bit more and I see one way of doing it.

It would also be to start out with computing all the possible stalemates. And then to work back. The one who moves last (and first when working backwards), would be the side that wants to avoid the stalemate. But there would be some positions in which that side could avoid the stalemate but that side would then get checkmated instead. And it would, of course, be preferable to not avoid the stalemate if you'd lose instead. So the positions that would loose, would have to be known already. So the regular tablebases should be probed as well. And if the side that wants to avoid the stalemate, cannot avoid the stalemate unless that side would get checkmated instead, those positions should be added to the stalemate tablebases.

After computing all those "- Stalemates in 1", the other side takes his turn. The other side wants to achieve the stalemate. But it wouldn't make much sense to achieve the stalemate if you could win instead. So I guess you could probe the regular tablebases to find out which positions would be winning. Those should be excluded.

But not only should we have to exclude the positions that would be winning. Cause it wouldn't make to much sense either to go for a forced stalemate if you can get a draw in some other way. So the side that wants to achieve the stalemate, should only be able to make a move which would result in a position that would lead to a forced stalemate or to a loss. Which would then mean that the only best move for the side that wants to achieve the stalemate, would be to go for the forced stalemate. And since the positions that are drawn, are not in the regular tablebases, all drawn positions are actually known.

So it's possible to do all of this if you'd have the regular tablebases already at your disposal when building the stalemate tablebases.

But honestly, I'm a lousy programmer. Would take me quite a bit of effort to achieve such a thing. If I'd achieve it at all. I don't think I'd be doing it for the time being. It's of course, all open for anyone to do it.
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Stalemate Tablebases

Post by hgm »

Indeed, if you would consider being stalemated an inferior outcome to delivering checkmate, but still preferable over fortress draws, (which in practice must end in repetition or 50-move draws) I would do it by first generating the regular EGT which would give Distance to Mate, and only after that start calculating back from the stalemates, using still higher DTM codes. E.g. use the code that otherwise would have meant mate-in-60 (if no real mate took that long) for indicating stalemated-in-0 (= stalemated), but not winnable by checkmate.

This is a technique you could use in general for games with a more diversified outcome than win/draw/loss: start generating the EGT for the highest-rewarded game end, and when that finishes, continue with the next-highest reward, using the remaining 'distance-to-success' codes, etc. That way the DTx codes would still correspond to the desirability of the position.

My EGT generators usually only keep only one bit of information for the 'strong' side on move (indicating 'won' or 'other'), and the process starts by setting to 'won' the positions where the strong side can capture the weak King. After that all moves of the weak side that would go to such a position are not just losing, but actually illegal. (In any later iteration that would not be true, as many perfectly legal moves can also be losing.) So when I test all weak-side-on-move positions for the first time to see whether they (still) have a non-losing move, and they have none, they are not automatically lost (as they would be in later iterations), but are mates. I then have to check whether that position would be won won with the strong side on move to determine if it is a checkmate or a stalemate. Normally only the checkmates would be labeled as losses (DTM=0), and the generation process would continue from those. The stalemates would forever remain 'undecided', which when the generation process runs out of steam automatically means 'not won'.

In your case you could already label the stalemates with DTM code 60 (say), and after the generation process runs out of steam at DTM < 60, restart it from DTM = 60. (Normally it operates on DTM=N to generate all DTM=N+1, for ever increasing N.)
Dries
Posts: 9
Joined: Sun Jan 17, 2021 11:26 am
Full name: Dries De Clercq

Re: Stalemate Tablebases

Post by Dries »

Yeah, generating both makes sense and using a high DTM to start from for the stalemates, makes sense too. Makes it a bit simpler. Thanks.

So umm.. how did it go, when generating the fortresses? Did you discover a lot?
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Stalemate Tablebases

Post by hgm »

Not really; I mainly used it to prove there were none. I needed that to get a better interpretation on which combinations of pieces were able to beat which other combinations. Especially with powerful pieces a 3+2-men end-game (E.g. KQBKQ) has an enormous number of non-wins, making it very hard to judge whether it was a generally won or a generally drawn end-game. I needed a method to determine whether these where due to the attacker quickly losing a piece by tactics, or whether the single piece was really able to hold out indefinetely (fortress draw). And I wasn't doing that for orthodox Chess pieces, but for the various pieces of Chess with Different Armies, in order to prepare the 'drawishness' table for my engine KingSlayer-CwDA.