Closed CPagador closed 7 years ago
Antichess is the same as giveaway with the exception that you do not have the right to castle, so it can be played by providing an FEN where castling rights are disabled. Our implementation differs from suicide in that stalemate always is a win for the stalemated player. Since this is only a minor difference, you can already play suicide with it, but it will return the wrong evaluation in a few exceptional cases.
Suicide should be easy to implement, but losers will require some work. However, so far the main problem is that the antichess engine is quite weak. Implementing variants of this variant will be interesting as soon as the engine is strong.
So SF supports antichess, but UCI_Variant=giveaway? I did a little test against engines that play giveaway (Sjeng 11.2 and Nebiyu 1.45)
[Event "Computer Chess Game"]
[Site "PHENOMII_X4"]
[Date "2016.11.06"]
[Round "2"]
[White "Nebiyu 1.45"]
[Black "Stockfish 8 64 POPCNT (UCI2WB)"]
[Result "0-1"]
[TimeControl "180+2"]
[Variant "giveaway"]
[Annotator "1. -0.04 1... +0.67"]
1. g3 {-0.04/22} Nh6 {+0.67/25 8} 2. b3 {+0.22/25 7} g6 {+2.14/25 2.7} 3.
g4 {+0.06/25 7} Nxg4 {+2.15/1 0.1} 4. Nf3 {-0.54/26 5} Nxf2
{+1000.17/41 2.3} 5. Kxf2 e5 {+1000.16/47 0.8} 6. Nxe5 Ba3 {+1000.15/59 4}
7. Nxg6 {-5.00/28 6} hxg6 {+1000.14/74 4} 8. Nxa3 {-18.26/39 6} Rxh2
{+1000.13/1 0.1} 9. Rxh2 Qh4 {+1000.11/72 4} 10. Rxh4 b5 {+1000.10/74 1.0}
11. Nxb5 a5 {+1000.09/92 4} 12. Nxc7 Ra7 {+1000.08/91 1.1} 13. Nxe8 f6
{+1000.07/126 4} 14. Nxf6 g5 {+1000.06/127 0.3} 15. Nxd7 gxh4
{+1000.05/127 0.2} 16. Nxb8 Bh3 {+1000.04/127 0.2} 17. Bxh3 Ra6
{+1000.03/127 0.2} 18. Nxa6 a4 {+1000.02/1 0.1} 19. bxa4
{Black wins} 0-1
[Event "Computer Chess Game"]
[Site "PHENOMII_X4"]
[Date "2016.11.06"]
[Round "3"]
[White "Sjeng 11.2"]
[Black "Stockfish 8 64 POPCNT (UCI2WB)"]
[Result "0-1"]
[TimeControl "180+2"]
[Variant "giveaway"]
[Annotator "1. -0.13 1... +0.08"]
1. c4 {-0.13/9} c6 {+0.08/28 14} 2. b4 {-0.10/8 17} c5 {+4.45/25 2.2} 3.
bxc5 Nc6 {+5.76/24 0.8} 4. a4 {+0.40/10 19} a5 {+4.12/32 7} 5. d4
{+0.23/10 15} Nxd4 {+9.64/1 0.1} 6. Qxd4 g5 {+19.30/25 3} 7. Bxg5
{+1.03/12 9} Qb6 {+26.64/23 1.0} 8. Qxh8 {+1.84/13 7} Qxc5
{+1000.15/39 2.6} 9. Qxg8 Qxf2 {+1000.14/54 4} 10. Kxf2 d5
{+1000.13/57 1.0} 11. cxd5 {+2.61/12 3} Bh3 {+1000.10/63 3} 12. Nxh3
{+2.34/11 3} b5 {+1000.09/82 4} 13. axb5 {+2.58/11 2.5} Rc8
{+1000.08/92 0.9} 14. Rxa5 {+2.98/10 3} Ra8 {+1000.07/122 4} 15. Rxa8
{-9999.88/27 2.4} Kd7 {+1000.06/127 0.3} 16. Qxf7 {-9999.90/40 1.4} e5
{+1000.05/127 0.2} 17. dxe6 {-9999.92/40 0.4} Kxe6 {+1000.04/1 0.1} 18.
Qxf8 {-9999.94/40 0.4} h6 {+1000.03/127 0.2} 19. Qxh6 {-9999.96/40 0.2} Kf6
{+1000.02/127 0.2}
{Black Mates} 0-1
[Event "Computer Chess Game"]
[Site "PHENOMII_X4"]
[Date "2016.11.06"]
[Round "5"]
[White "Stockfish 8 64 POPCNT (UCI2WB)"]
[Black "Nebiyu 1.45"]
[Result "1-0"]
[TimeControl "180+2"]
[Variant "giveaway"]
[Annotator "1. -0.48 1... +0.08"]
1. g3 {-0.48/25} b6 {+0.08/21 6} 2. c4 {+0.77/25 4} b5 {+2.68/29 7} 3. cxb5
{+0.77/1 0.1} c5 {+0.54/30 7} 4. bxc6 {+3.14/1 0.1} dxc6 {+3.86/34 38} 5.
g4 {+1000.17/44 2.5} Bxg4 {+3.50/28 5} 6. Qc2 {+1000.16/44 0.9} Qxd2
{+3.50/28 5} 7. Nxd2 {+1000.15/44 4} Bxe2 8. Nxe2 {+1000.14/54 0.9} f5
{+3.86/27 6} 9. Qxc6 {+1000.12/68 4} Nxc6 10. Ne4 {+1000.11/67 0.8} fxe4
11. b4 {+1000.10/75 4} Nxb4 12. Rb1 {+1000.09/75 1.2} Nxa2 13. Bh6
{+1000.08/84 4} gxh6 {-8.36/28 6} 14. Nc3 {+1000.07/88 0.9} Nxc3 15. Rb6
{+1000.06/127 2.0} axb6 16. Kd1 {+1000.05/127 0.2} Nxd1 17. Rg1
{+1000.04/127 0.2} Nxf2 18. Rxg8 {+1000.03/1 0.1} Rxg8 19. Bh3
{+1000.02/127 0.1} Nxh3
{White wins} 1-0
[Event "Computer Chess Game"]
[Site "PHENOMII_X4"]
[Date "2016.11.06"]
[Round "6"]
[White "Stockfish 8 64 POPCNT (UCI2WB)"]
[Black "Sjeng 11.2"]
[Result "0-1"]
[TimeControl "180+2"]
[Variant "giveaway"]
[Annotator "1. -0.48 1... -0.08"]
1. g3 {-0.48/25} g5 {-0.08/9 24} 2. c4 {+0.35/25 6} c5 {-0.02/9 21} 3. b4
{+1.17/23 4} cxb4 4. Ba3 {+1.50/28 6} bxa3 5. Nxa3 {+1.50/1 0.1} b5
{+0.28/9 8} 6. cxb5 {+1.91/27 4} Ba6 {-0.12/9 9} 7. bxa6 {+1.91/1 0.1} Nxa6
8. Qc1 {+0.28/27 7} Rc8 {-0.06/9 9} 9. Qxc8 {+2.42/1 0.1} Qxc8 10. Rc1
{+1.29/30 15} Qxc1 11. Kd1 {+3.05/30 6} Qxd1 {+3.25/9 9} 12. e4
{+3.23/27 3} Qxf1 13. Ne2 {+0.25/34 13} Qxf2 14. Ra1 {-0.15/38 15} Qxg3 15.
Nxg3 {-0.46/38 10} g4 {+2.27/10 12} 16. e5 {+1.87/27 2.5} Kd8 {+2.25/9 15}
17. e6 {+6.31/28 5} dxe6 {+2.58/9 6} 18. Nb1 {+4.42/35 14} f5 {+2.90/10 12}
19. Nxf5 {+11.98/1 0.1} exf5 20. h4 {+0.11/33 12} gxh3 21. Nc3 {+0.02/34 6}
Nf6 {+3.51/9 9} 22. Ne4 {-2.09/31 9} fxe4 23. a4 {-1000.18/38 7} Kc7
{+4.51/9 9} 24. d3 {-1000.11/46 4} exd3 25. a5 {-1000.10/61 3} Kb6 26. axb6
{-1000.09/1 0.1} axb6 27. Rxa6 {-1000.08/1 0.1} d2 28. Rxb6 {+7.66/1 0.1}
e6 29. Rxe6 {+2.01/1 0.1} d1=B 30. Rxf6 {+7.28/1 0.1} Bd6 31. Rxd6
{-2.65/1 0.1} h2 32. Rxd1 {-1.32/1 0.1} h1=Q 33. Rxh1 {-2.80/1 0.1} Rg8
{+9999.95/6 0.1} 34. Rxh7 {-0.08/1 0.1} Rg7 {+9999.97/4 0.1} 35. Rxg7
{-1000.01/1 0.1}
{Black Mates} 0-1
Stockfish supports giveaway, but if you provide an FEN with castling rights disabled, e.g. rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w - - 0 1
it plays antichess, since the only difference between these variants is castling. I usually use the term antichess even if it can not be chosen directly through a UCI_Variant option, since this is the ruleset that is used on lichess and that had originally been implemented, whereas the castling rights have been added later (to obtain superset of antichess) that lead to renaming of the option value.
There have been signficant changes to the evaluation for giveaway/antichess recently (e.g. regarding piece values), so I do not know much about the absolute playing strength of the current version, but only the relative strength compared to earlier version that were rather weak.
Are there any rating lists of suicide/giveaway engines or at least an overview of strong engines?
Not sure about rating lists, but winboard engines that plays those variants:
Giveaway: Sjeng 11.2 (strongest,) Nebiyu 1.45
Suicide: Losing Chess Wizard (strongest,) Sjeng, KKFChess, Nebiyu, Pulsar.
There is also this:
https://catalin.francu.com/nilatac/
http://nakshatrachess.blogspot.pe/
Could you compile these source codes to have the executables?
Engines that play Losers: Sjeng, Gerbil, Pulsar, Olithink, KKFChess.
@CPagador Thanks. I have compiled nilatac, but I haven't tried nakshatra yet, because I do not have scons installed on my current system.
Great. Could you share the exe?
I have compiled it on Linux, so I can not provide a Windows executable.
I see. If you could, let us know how strong it is.
I have tried to run it, but it always stops moving due to segmentation faults as soon as it is out of book.
I hope you find some interesting ideas in the source code at least.
I'd like to test SF in suicide chess, but I can't make it work under Winboard with UCI_Variant=giveaway. Could you implement it?
It works fine for me in XBoard with the most recent version of the UCI2WB adapter. However, you should choose the variant giveaway and not suicide, otherwise it might make illegal moves.
Yes, it plays giveaway chess, but if I want it to play against Pulsar or Losing Chess Wizard (wich play suicide but not giveaway), they cannot play suicide chess because Winboard says SF does not support the variant. If I choose variant giveaway, Winboard says Pulsar/LCW does not play the variant.
That means SF only have this two possible (engine) opponents: Sjeng 11.2 and Nebiyu 1.45, which seem to be not competition for it. These are my results at 15'+3":
--------------------------------------------------------------------
1: Stockfish 121116 12.0 / 12 XXXXXX 111111 111111 (+12 -0 =0)
2: Sjeng 11.2 6.0 / 12 000000 XXXXXX 111111 (+6 -6 =0)
3: Nebiyu 1.45 0.0 / 12 000000 000000 XXXXXX (+0 -12 =0)
--------------------------------------------------------------------
18 games: +9 -9 =0
Thanks for posting the test results. Have you used an opening book?
The problem with implementing suicide is not the different ruleset, but to implement it in a clean way without adding a lot of redundant code for a "new" variant. So far we do not have a simple way to add subvariants, but I am working on it. If you want it to pretend to be able to play suicide (while still playing giveaway), you can change the variant's name in line 144 of types.h to "suicide" and compile it again.
Thanks for the hint. I used these positions:
[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "1"]
[White "Suicide"]
[Black "Opening"]
[Result "*"]
[Annotator "Suicide suite"]
1. b3 g6 *
[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "2"]
[White "Suicide"]
[Black "Opening"]
[Result "*"]
[Annotator "Suicide suite"]
1. e3 b6 *
[Event "?"]
[Site "?"]
[Date "????.??.??"]
[Round "3"]
[White "Suicide"]
[Black "Opening"]
[Result "*"]
[Annotator "Suicide suite"]
1. e3 c5 *
I remember that I owe someone a response regarding giveaway/antichess test results, but after many minutes of searching and reading comments on all open issues(!) I cannot seem to find the issue... so I shall respond here and hopefully someone can remind me what I'm responding to.
(Incidentally, that's why I avoid creating unbounded issues like "Looking for improvements in crazyhouse" although I suppose others find such issues useful. Maybe I can learn somehow to be more effective at using GitHub in dealing with so many issues & comments at once.)
I am surprised by the result but I'm not finding anything mistaken in these analyses: http://en.dugovic.mooo.com/Orw9n59n http://en.dugovic.mooo.com/PK0OIRh0
@ddugovic You are probably referring to this closed PR.
So Stockfish beats Sjeng and produces sensible analysis results. @niklasf I think you can now consider adding Stockfish as an antichess AI.
I tried the subvariant branch for suicide chess and it works well. Here are the results:
Score Stockfis Losing C Sjeng 11 KKFChess Pulsar20 Sjaak II
-----------------------------------------------------------------------------------------------------------
1: Stockfish 191116 64 POPCNT (UCI2WB) 37.5 / 40 XXXXXXXX =1111111 1110=1=1 11111111 11111111 11111111 (+36 -1 =3)
2: Losing Chess Wizard full 29.5 / 40 =0000000 XXXXXXXX 01101=11 11111111 111=1111 11111111 (+28 -9 =3)
3: Sjeng 11.2 27.5 / 40 0001=0=0 10010=00 XXXXXXXX 11111011 11111111 11111111 (+26 -11 =3)
4: KKFChess 2.6.7b 11.5 / 40 00000000 00000000 00000100 XXXXXXXX 10001=01 11101111 (+11 -28 =1)
5: Pulsar2009-9b 11.0 / 40 00000000 000=0000 00000000 01110=10 XXXXXXXX 11001111 (+10 -28 =2)
6: Sjaak II 1.3.1a 3.0 / 40 00000000 00000000 00000000 00010000 00110000 XXXXXXXX (+3 -37 =0)
-----------------------------------------------------------------------------------------------------------
120 games: +57 -57 =6
@CPagador Great, thanks for sharing your results. I guess the conditions were the same as in the matches against Sjeng and Nebiyu, right?
@ianfab Yes. 15'+3", Phenom II x4 955, single thread and 512 MB hash.
FICS supports variants suicide and losers. The rules for both say that captures are obligatory. Stockfish with a variant giveaway lost because it didn't capture an offered piece. Do you plan to introduce obligatory capturing?
@lantonov This is implemented, and if it did not capture there must be a serious bug. Could you please provide an FEN or PGN where this occured?
Are you sure the (G)UI selected the variant correctly? Maybe it tried to set UCI_Variant to suicide which leads to Stockfish playing normal chess if you do not use the subvariant branch with suicide support.
The suggestion that FICS selected suicide which led to normal chess is very plausible. No need for pgn because this happened on the first moves: Me with white:
Stockfish with a variant giveaway lost because it didn't capture an offered piece.
@lantonov I could not reproduce (surely you meant 1. e4 b5 2. Bxb5):
setoption name UCI_Variant value giveaway
info string variant giveaway startpos rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
position startpos moves e2e4 b7b5
go depth 10
info depth 1 seldepth 1 multipv 1 score cp -887 nodes 1 nps 500 tbhits 0 time 2 pv f1b5
info depth 2 seldepth 2 multipv 1 score cp -1687 nodes 5 nps 2500 tbhits 0 time 2 pv f1b5 d7d6
info depth 3 seldepth 3 multipv 1 score cp -477 nodes 19 nps 9500 tbhits 0 time 2 pv f1b5 d7d6 b5e8
info depth 4 seldepth 4 multipv 1 score cp -636 nodes 61 nps 30500 tbhits 0 time 2 pv f1b5 g8f6 b5d7 f6e4
info depth 5 seldepth 5 multipv 1 score cp -535 nodes 142 nps 71000 tbhits 0 time 2 pv f1b5 g8f6 b5d7 f6e4 d7e8
info depth 6 seldepth 6 multipv 1 score cp -657 nodes 245 nps 81666 tbhits 0 time 3 pv f1b5 g8f6 b5d7 f6e4 d7e8 d8d2
info depth 7 seldepth 7 multipv 1 score cp -507 nodes 653 nps 217666 tbhits 0 time 3 pv f1b5 d7d5 b5e8 d5e4 e8f7 d8d2 f7g8
info depth 8 seldepth 8 multipv 1 score cp -667 nodes 949 nps 237250 tbhits 0 time 4 pv f1b5 c8b7 b5d7 b7e4 d7e8 e4g2 e8f7 d8d2
info depth 9 seldepth 12 multipv 1 score cp -304 nodes 1394 nps 348500 tbhits 0 time 4 pv f1b5 c8b7 b5d7 b7e4 d7e8 d8d2 e1d2 e4c2 e8f7
info depth 10 seldepth 13 multipv 1 score cp -499 nodes 2314 nps 385666 tbhits 0 time 6 pv f1b5 d7d5 b5e8 d5e4 e8f7 d8d2 f7g8 d2e1 g8h7 e1d1 h7e4 h8h2
bestmove f1b5 ponder d7d5
Yes, I will request again suicide from FICS to see which variants it sets. Sorry for bothering you.
No problem; please if you find something provide the PGN (so I understand what variant to test - right now only the subvariant
branch has suicide variant support, and I think after #131 I'll merge it).
@ddugovic If you intend to merge the subvariant branch, it would be good not to merge #162 before that (it needs more testing anyway), because there are conflicting changes regarding stalemate that I would have to fix in #162.
Ok, thanks, I will try both giveaway and suicide to see how it goes. BTW, FICS also supports the variant losers.
TIL FICS players still play losers chess.
Trying to compile the sources from branch subvariant gave me the following:
$ make build ARCH=x86-64-bmi2 COMP=mingw && killall -qw stockfish && cp -a ./stockfish ~/lila/bin
Config:
debug: 'no'
sanitize: 'no'
optimize: 'yes'
arch: 'x86_64'
bits: '64'
kernel: 'MINGW64_NT-10.0'
os: 'Windows_NT'
prefetch: 'yes'
popcnt: 'yes'
sse: 'yes'
pext: 'yes'
Flags:
CXX: g++
CXXFLAGS: -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2
LDFLAGS: -static
Testing config sanity. If this fails, try 'make help' ...
make ARCH=x86-64-bmi2 COMP=mingw all
make[1]: Entering directory '/home/lanto/suicide'
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o benchmark.o benchmark.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o bitbase.o bitbase.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o bitboard.o bitboard.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o endgame.o endgame.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o evaluate.o evaluate.cpp
evaluate.cpp: In instantiation of 'void {anonymous}::eval_init(const Position&, {anonymous}::EvalInfo&) [with Color Us = (Color)0u]':
evaluate.cpp:1323:19: required from 'Value Eval::evaluate(const Position&) [with bool DoTrace = true]'
evaluate.cpp:1426:53: required from here
evaluate.cpp:363:20: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
!pos.is_anti() &&
~~~~~~~~~~~~~~~^~
#endif
~~~~~~
(pos.non_pawn_material(Us) >= QueenValueMg)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
evaluate.cpp: In instantiation of 'void {anonymous}::eval_init(const Position&, {anonymous}::EvalInfo&) [with Color Us = (Color)1u]':
evaluate.cpp:1324:19: required from 'Value Eval::evaluate(const Position&) [with bool DoTrace = true]'
evaluate.cpp:1426:53: required from here
evaluate.cpp:363:20: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
evaluate.cpp: In instantiation of 'Score {anonymous}::evaluate_king(const Position&, const {anonymous}::EvalInfo&) [with Color Us = (Color)0u; bool DoTrace = true]':
evaluate.cpp:1356:42: required from 'Value Eval::evaluate(const Position&) [with bool DoTrace = true]'
evaluate.cpp:1426:53: required from here
evaluate.cpp:625:54: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
kingDanger += QueenContactCheck * popcount(b & ei.attackedBy2[Them] |
evaluate.cpp:657:69: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
Bitboard dropSafe = (safe | ei.attackedBy[Them][ALL_PIECES] & dqo) & ~pos.pieces(Us);
evaluate.cpp:664:45: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b1 & (ei.attackedBy[Them][ROOK] & safe | dropSafe & h))
evaluate.cpp:674:47: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b2 & (ei.attackedBy[Them][BISHOP] & safe | dropSafe & h))
evaluate.cpp:685:15: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b & safe | k & h & dropSafe)
~~^~~~~~
evaluate.cpp:688:25: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
else if ((b | k & h) & other)
~~^~~
evaluate.cpp: In instantiation of 'Score {anonymous}::evaluate_king(const Position&, const {anonymous}::EvalInfo&) [with Color Us = (Color)1u; bool DoTrace = true]':
evaluate.cpp:1357:42: required from 'Value Eval::evaluate(const Position&) [with bool DoTrace = true]'
evaluate.cpp:1426:53: required from here
evaluate.cpp:625:54: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
kingDanger += QueenContactCheck * popcount(b & ei.attackedBy2[Them] |
evaluate.cpp:657:69: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
Bitboard dropSafe = (safe | ei.attackedBy[Them][ALL_PIECES] & dqo) & ~pos.pieces(Us);
evaluate.cpp:664:45: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b1 & (ei.attackedBy[Them][ROOK] & safe | dropSafe & h))
evaluate.cpp:674:47: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b2 & (ei.attackedBy[Them][BISHOP] & safe | dropSafe & h))
evaluate.cpp:685:15: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b & safe | k & h & dropSafe)
~~^~~~~~
evaluate.cpp:688:25: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
else if ((b | k & h) & other)
~~^~~
evaluate.cpp: In instantiation of 'Score {anonymous}::evaluate_king(const Position&, const {anonymous}::EvalInfo&) [with Color Us = (Color)0u; bool DoTrace = false]':
evaluate.cpp:1356:42: required from 'Value Eval::evaluate(const Position&) [with bool DoTrace = false]'
evaluate.cpp:1427:53: required from here
evaluate.cpp:625:54: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
kingDanger += QueenContactCheck * popcount(b & ei.attackedBy2[Them] |
evaluate.cpp:657:69: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
Bitboard dropSafe = (safe | ei.attackedBy[Them][ALL_PIECES] & dqo) & ~pos.pieces(Us);
evaluate.cpp:664:45: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b1 & (ei.attackedBy[Them][ROOK] & safe | dropSafe & h))
evaluate.cpp:674:47: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b2 & (ei.attackedBy[Them][BISHOP] & safe | dropSafe & h))
evaluate.cpp:685:15: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b & safe | k & h & dropSafe)
~~^~~~~~
evaluate.cpp:688:25: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
else if ((b | k & h) & other)
~~^~~
evaluate.cpp: In instantiation of 'Score {anonymous}::evaluate_king(const Position&, const {anonymous}::EvalInfo&) [with Color Us = (Color)1u; bool DoTrace = false]':
evaluate.cpp:1357:42: required from 'Value Eval::evaluate(const Position&) [with bool DoTrace = false]'
evaluate.cpp:1427:53: required from here
evaluate.cpp:625:54: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
kingDanger += QueenContactCheck * popcount(b & ei.attackedBy2[Them] |
evaluate.cpp:657:69: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
Bitboard dropSafe = (safe | ei.attackedBy[Them][ALL_PIECES] & dqo) & ~pos.pieces(Us);
evaluate.cpp:664:45: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b1 & (ei.attackedBy[Them][ROOK] & safe | dropSafe & h))
evaluate.cpp:674:47: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b2 & (ei.attackedBy[Them][BISHOP] & safe | dropSafe & h))
evaluate.cpp:685:15: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
if (b & safe | k & h & dropSafe)
~~^~~~~~
evaluate.cpp:688:25: warning: suggest parentheses around arithmetic in operand of '|' [-Wparentheses]
else if ((b | k & h) & other)
~~^~~
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o main.o main.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o material.o material.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o misc.o misc.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o movegen.o movegen.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o movepick.o movepick.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o pawns.o pawns.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o position.o position.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o psqt.o psqt.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o search.o search.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o thread.o thread.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o timeman.o timeman.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o tt.o tt.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o uci.o uci.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o ucioption.o ucioption.cpp
g++ -Wall -Wcast-qual -fno-exceptions -fno-rtti -std=c++11 -Wextra -Wshadow -DANTI -DATOMIC -DCRAZYHOUSE -DHORDE -DKOTH -DRACE -DTHREECHECK -DNDEBUG -O3 -DIS_64BIT -msse -msse3 -mpopcnt -DUSE_POPCNT -DUSE_PEXT -mbmi2 -c -o syzygy/tbprobe.o syzygy/tbprobe.cpp
syzygy/tbprobe.cpp:117:1: error: too many initializers for 'const char* [8]'
};
^
<builtin>: recipe for target 'syzygy/tbprobe.o' failed
make[1]: *** [syzygy/tbprobe.o] Error 1
make[1]: Leaving directory '/home/lanto/suicide'
Makefile:427: recipe for target 'build' failed
make: *** [build] Error 2
@lantonov Merged changes from the master branch might have broken subvariants. I will look into it.
@lantonov It should be fixed by #182.
The master compiled without error (with the same warnings).
Thanks, I just merged #182 to branch subvariant
.
Thanks, now subvariant compiles the same as master.
Now I have 2 new variants: suicide and loop
Here is some games with CatNail (uses some version of nilatac)
Event "ICS unrated suicide match"] [Site "freechess.org"] [Date "2016.12.23"] [Round "-"] [White "CatNail"] [Black "FishTest"] [Result "0-1"] [WhiteElo "2055"] [BlackElo "0"] [TimeControl "300"] [Variant "suicide"] [Annotator "1... +0.00"]
[Event "ICS unrated suicide match"] [Site "freechess.org"] [Date "2016.12.23"] [Round "-"] [White "FishTest"] [Black "CatNail"] [Result "1-0"] [WhiteElo "0"] [BlackElo "2055"] [TimeControl "300"] [Variant "suicide"] [Annotator "1. +0.57"]
[Event "ICS unrated suicide match"] [Site "freechess.org"] [Date "2016.12.23"] [Round "-"] [White "CatNail"] [Black "FishTest"] [Result "0-1"] [WhiteElo "2055"] [BlackElo "0"] [TimeControl "300"] [Variant "suicide"] [Annotator "1... +1.11"]
[Event "ICS unrated suicide match"] [Site "freechess.org"] [Date "2016.12.23"] [Round "-"] [White "FishTest"] [Black "CatNail"] [Result "1-0"] [WhiteElo "0"] [BlackElo "2055"] [TimeControl "300"] [Variant "suicide"] [Annotator "1. +0.62"]
[Event "ICS unrated suicide match"] [Site "freechess.org"] [Date "2016.12.23"] [Round "-"] [White "CatNail"] [Black "FishTest"] [Result "0-1"] [WhiteElo "2055"] [BlackElo "0"] [TimeControl "300"] [Variant "suicide"] [Annotator "1... +0.93"]
Since #131 regression test on Windows at 60+10 was successful, I have code reviewed and merged subvariant
into master
.
A game that I lost on FICS (by stayalive):
[Event "ICS unrated suicide match"]
[Site "freechess.org"]
[Date "2016.12.24"]
[Round "-"]
[White "FishTest"]
[Black "stayalive"]
[Result "0-1"]
[WhiteElo "0"]
[BlackElo "2824"]
[TimeControl "180"]
[Variant "suicide"]
[Annotator "1. +0.16"]
1. c4 {+0.16/28 11} c5 2. b4 {+0.71/27 3} cxb4 3. Ba3 {+0.26/30 7} bxa3 4.
Nxa3 {+0.31/28 0.1} a5 5. Qb1 {+1.17/30 7} Ra7 6. Qxh7 {+2.37/27 2.0} Rxh7
7. Nc2 {+2.21/31 6} Rxh2 8. Rxh2 {+1.37/26} a4 9. Nb4 {+1.61/31} d5 10.
Nxd5 {+1.06/32 0.4} Qxd5 11. cxd5 {+0.99/28 0.1} e6 12. dxe6 {+5.82/4} fxe6
13. d3 {+0.31/29 10} Nh6 14. Rxh6 {+5.21/2} gxh6 15. Nh3 {+0.00/34 7} b6
16. e4 {+0.69/23 2.8} Ba6 17. Ke2 {+1.11/24 2.9} Bxd3 18. Kxd3
{+1.19/19 0.1} Be7 19. Re1 {+0.00/33 8} Bg5 20. Nxg5 {+3.08/3} hxg5 21. g3
{-0.56/32 23} a3 22. e5 {+0.81/28 4} Kd7 23. Rd1 {-0.06/32 1.5} g4 24. Bh3
{-0.93/28} gxh3 25. f4 {-0.85/28 2.0} Kc6 26. f5 {-1.06/28 1.8} exf5 27. e6
{-1.65/29 12} f4 28. gxf4 {-1.76/28} Ra8 29. f5 {-0.97/25 4} h2 30. e7
{-0.69/24 1.9} Ra4 31. Rg1 {-2.60/25 10} hxg1=R 32. Kc2 {-3.68/28 9} Rg8
33. e8=Q {-4.67/25 4} Rxe8 34. Kd1 {-4.77/30 1.8} Re2 35. Kxe2 {-0.92/1}
Kc5 36. Kd2 {-1000.13/36 3} Nc6 37. Kc1 {-1000.12/43} Rb4 38. f6
{-1000.11/48} Rb2 39. Kxb2 {-1000.10/65} axb2 40. f7 {-1000.09/63 0.2} b1=R
41. a4 {-1000.08/69 1.1} b5 42. axb5 {-1000.07/76} Rxb5 43. f8=N
{-1000.06/84} Kd4 44. Nh7 {-1000.05/127 0.9} Ne5 45. Nf8 {-1000.04/127 0.2}
Nd7 46. Nxd7 {-1000.03/127} Rb6 47. Nxb6 {-1000.02/127} Kc4 48. Nxc4
{-1000.01/1}
{stayalive wins by losing all material} 0-1
Here is what I read in his notes: "The game of suicide chess, from the normal starting position, has been solved in October 2016. White wins with 1. e3. On 1. e3 b6, 2. a4! is winning." Following on this I found the article: http://magma.maths.usyd.edu.au/~watkins/LOSING_CHESS/losing2014.pdf
Stayalive plays with the engine Losing Chess Wizard. Playing further, however, it turned out that the current version of Stockfish is stronger than LCW. The result for SF so far is: +14 =2 -9. I can provide you pgn if you are interested
The FICS rule for suicide stallmate is: You win if: (b) You have no legal moves to make and have fewer pieces left at the end than your opponent does. The type of pieces remaining make no difference. If the number of pieces is equal, the game would be drawn.
So not every stalemate is a win. Does the SF suicide variant follow the same rule. AFAIK, the International rule for suicide is that every stalemate wins.
@lantonov Yes, for suicide SF uses the FICS rule (implemented here), and for giveaway it uses the international rules.
LCW plays the international rules (giveaway) and that's why it loses some games in FICS suicide.
BTW I'm not going to hard-code opening moves into Stockfish; it's recommended to use some sort of opening book (since WinBoard and other GUIs support opening books).
Unfortunately given that the game is weakly solved (a win for White from the start position) it's challenging to demonstrate an error which isn't caused by an opening mistake. :-(
By the way, I want to start to implement losers, but I am not very familiar with it and I have a question regarding the rules: When you are in check and there are capturing and non-capturing moves available to move out of check, then do you have to capture?
This rule in FICS losers is given as:
If you are in check, you must defend your king as in chess. A defense that involves a capture takes priority over other defenses.
So, I guess you have to capture.
@lantonov Thanks. Yes, the FICS rules are pretty clear on that.
Here I attach pgn with the games played on FICS with Losing Chess Wizard (stayalive)
I am trying to find reliable perft numbers for losers and I tried Sjeng's perft, but the numbers look dubious. Perft of losers deviates from suicide and giveaway starting from depth 3. I have no idea how this can happen at depth 3. Furthermore it is larger than for suicide for depth >= 3, but I would expect it to be smaller. Am I wrong or is Sjeng's perft broken? Any ideas?
By perft I mean this: https://chessprogramming.wikispaces.com/Perft
This link may help (hope so): https://sites.google.com/site/numptychess/perft
Currently, Stockfish supports giveaway variant (called antichess here.) Given that losers and suicide chess are similar to giveaway, would you implement those variants too?