Suicide chess engine acting as desktop engine, web page, mobile application, Internet chess server and library
Test it online at http://ecrucru.free.fr/?page=anticrux !
AntiCrux is a library written in JavaScript that plays a single variant of chess named "AntiChess", "Suicide chess" or also "Loosing chess". You can play against the computer with :
For technical reasons inherited from JavaScript and its (somehow particular) design, AntiCrux will never reach the highest and unbeatable ELO ratings. Its level is rather normal and the 20 available levels implement various techniques and rules to play like a human as much as possible. It is then a good tool to increase your skills with fun !
About the variant AntiChess, the objective consists in losing all your own pieces or reaching a stalemate. For that, you will probably have to force the moves. The rules are very simple and change a lot the dynamics of the game :
AntiChess960 is another variant for which the pieces of the first line are shuffled in a precise order. It offers 959 new start positions, the 519th one being the classical position. The other rules are not changed.
The logic of loosing all one's pieces leads to a really different way of thinking. When you start to lose, you can still expect to win at the end. The number of materials counts but the way you play at any moment as well.
AntiCrux | Windows | Linux | Macintosh | NodeJS | jsUCI | Android | iOS | Windows Phone |
---|---|---|---|---|---|---|---|---|
Web desktop UI | Yes | Yes | Yes | - | - | Yes | Yes | (Not tested) |
Web mobile UI | Yes | Yes | Yes | - | - | Yes | Yes | (Not tested) |
Application for smartphones | - | - | - | - | - | Yes | No | Yes (Not tested) |
NPM package | Yes | Yes | Yes | Yes | - | - | - | - |
Engine UCI | Yes | Yes | Yes | Yes | Yes | - | - | - |
Server | Yes | Yes | Yes | Yes | No | - | - | - |
ELO | Yes | Yes | Yes | Yes | No | - | - | - |
Quality | Yes | Yes | Yes | Yes | No | - | - | - |
Note : the symbol "-" denotes that a feature is not applicable.
AntiCrux is delivered as source code at Github :
git clone https://github.com/ecrucru/anticrux.git
The package on NPM has a correct version but it won't be updated anymore. Consider it as discontinued.
npm install anticrux
As a chess player, you simply have to double-click on the file index.html
to launch the web-interface in your default browser. The tested ones have different behaviours :
You have several tabs :
Without any local installation, just check online at http://ecrucru.free.fr/?page=anticrux and you will get the same enjoyment.
The mobile version is a light-weighted version of the web-interface which fits with tiny screens.
By using the technologies behind Adobe PhoneGap and Apache Cordova, it is possible to create a standalone, multi-platform and authorization-free application for your smartphone. The application used to be compiled by Adobe PhoneGap Build until it stopped on 1st October 2020.
The downloadable and latest APK file for Android is attached to the release 0.3.1 on Github :
For Android 4+, follow these steps :
The file for Windows Phone has not been rescued. The file for iOS never existed.
To use the different modules of AntiCrux out of a web-browser, you must install Node.js. With a packet manager under Linux, you can type :
apt-get install nodejs nodejs-legacy
If you are a software developer, few additional tools may be added globally :
npm install -g uglify-js jshint yuidocjs
To test if your installation is working, you can run the following test :
node --expose-gc anticrux-demo.js
As a convenient alternative, you may use jsUCI to run the compatible modules. This tool is not recommended because it offers fewer capabilities compared to NodeJS. In practice, just replace any occurrence of node.exe --expose-gc
by jsuci_1_2.exe
(adapt the name to fit with the relevant version).
You need first to install Node.js.
To access the engine remotely over a network, you can execute AntiCrux as a chess server. By default, it listens to local connections on the port 5000 and you can't create more than one instance on the same port.
Start the server by double-clicking on the script run_server.bat
(Windows) or run_server.sh
(Linux). To change the default level of the server, follow the indications written on the home screen when you connect.
Because it mimics the commands of the Free Internet Chess Server (FICS), AntiCrux Server is compatible with any ICS client that doesn't support timeseal.
telnet localhost 5000
"AntiCrux Server" /icshost=localhost /icsport=5000
Arena is not really supported because it applies the rules of chess on the variant. It can be mitigated with the following settings :
pyChess is not supported.
You need first to install Node.js.
AntiCrux Engine acts like an UCI-compatible engine that can be connected to any modern desktop application. You will keep your habits and you will be able to create computer matches ! The played variants are suicide
, giveaway
and antichess
. They all refer to the same gameplay.
Some restrictions apply :
To verify that AntiCrux Engine reacts correctly, open a terminal and run :
node --expose-gc anticrux-engine.js
Then type UCI commands from scratch :
uci
setoption name UCI_Variant value suicide
setoption name Skill Level value 12
isready
ucinewgame
position startpos moves a3
go infinite
Debug
: this option is reserved for the developers to track all the issues that may arise during the use of the engine. If the option is not activated by default, the log is not effective until the option is turned on with the relevant instruction setoption
. In other words, you may miss the few first UCI messages.MultiPV
: it is the ability to show N alternate moves by decreasing order of importance along with the final move.Precise Score
: if the move is forced, a deep analysis doesn't occur unless you activate this option. It slows down the engine but you get a better evaluation of the score.Same Value
: the pieces are assigned the same value so that only their count matters on the board.Skill Level
: the level is the difficulty of the game. The higher, the bigger the memory footprint.UCI_Variant
: it defines the chess variants supported by the engine.You need to use at least WinBoard 4.9 else you will be told that the variant suicide
is not supported.
In WinBoard, add a new engine and set the following options :
AntiCrux
"C:\full-path-to-nodejs\node.exe"
--expose-gc "C:\fullpath-to-anticrux\anticrux-engine.js"
/variant=suicide
C:\fullpath-to-anticrux\
This settings will end up with an equivalent line added to the list of engines :
"AntiCrux" -fcp 'C:\fullpath-to-nodejs\node.exe --expose-gc "C:\fullpath-to-anticrux\anticrux-engine.js"' -fd "C:\fullpath-to-anticrux\anticrux\" -fn "AntiCrux" -fUCI /variant=suicide
Restart WinBoard. On the main dialog "WinBoard Startup", select AntiCrux from the drop-down lists to start a new game against it.
During the game, if you do an incorrect move under certain conditions, the engine will probably leave the game because WinBoard doesn't send a correct position to analyze.
To start an AntiChess960 game, go to "File > New shuffle game..." and pick a number random. This will not launch a game with the classical rules.
To activate the logo in WinBoard, copy the picture located at images/anticrux.bmp
to the same folder as the file anticrux-engine.js
, then rename the copied picture as logo.bmp
.
The following procedure applies from pyChess 0.99 released on September 2017. Any use of earlier versions is not recommended.
Run pyChess. In the menu "Edit > Engines", add a new engine by selecting anticrux-engine.js
.
Then set --expose-gc
for the parameters of the environment.
The working directory is the one where the engine is stored.
To start a new game, you must use the menu "File > New game" or click on the big weather icon of the welcome screen. You may not find the engine in the drop-down list of the welcome screen because it doesn't play the classical chess. From the dialog of the new game, do select the variant called "Suicide" or "Giveaway", then select the engine and the applicable level with the slider.
The following HTML template helps you to debug the UCI engine from a web-browser. First, the commands should be listed in an array. Then you read the output in your browser.
<html>
<head>
<script src="https://github.com/ecrucru/anticrux/raw/master/anticrux.js"></script>
<script src="https://github.com/ecrucru/anticrux/raw/master/anticrux-engine.js"></script>
</head>
<body>
<script type="text/javascript">
var i, cmds = [
'uci',
'isready',
'ucinewgame'
];
if (acengine)
for (i=0 ; i<cmds.length ; i++)
acengine.process(cmds[i]);
</script>
</body>
</html>
This tool generates a PGN file to estimate the level of AntiCrux in regard of other UCI-compatible chess engines. For now, only AntiCrux and the special Stockfish-based engine developed by @ddugovic and compiled by @niklasf (the project does not exist anymore) are considered because they are related to JavaScript.
To get reliable games, the processing will take hours (or days !). To accelerate the generation, you may launch in parallel with the scripts run_elo.bat
(Windows) or run_elo.sh
(Linux) as many processes as your computer has CPU.
The script has 3 main changeable parameters :
job.genGames
: should the script play games and append the result to the PGN file ?job.numGames
: how many games should be generated per CPU ?job.genStats
: should the script estimate AntiCrux's rating based on the rules provided by the chess federation FIDE ?At the end, you get the following output in the console :
The ratings for the engine "AC" are :
- AC Level 8 is rated 1605 (initially 1640) after 72 games (+30/=0/-42).
- AC Level 9 is rated 1705 (initially 1742) after 80 games (+47/=1/-32).
- AC Level 10 is rated 1759 (initially 1736) after 84 games (+42/=2/-40).
The ratings for the engine "SF" are :
- SF Level 3 is rated 1514 (initially 1350) after 372 games (+122/=11/-239).
- SF Level 4 is rated 1476 (initially 1500) after 345 games (+134/=13/-198).
- SF Level 5 is rated 2017 (initially 1850) after 362 games (+264/=14/-84).
- SF Level 6 is rated 2501 (initially 2150) after 346 games (+293/=1/-52).
These results are composed of :
The estimations follow the rules edicted by the chess federation FIDE. The principles are :
When the statistics are displayed, a CSV file anticrux-elo.csv
is generated in the background (refer to the options of the script). It is built to allow you to draw the evolution of the ELO rating in a spreadsheet. You can then decide visually what is the most suitable rating for a given level.
To improve the reliability of the determination, we can use a statistical approach with "BayesElo". This application takes a PGN file and calculates the ELO rating :
> bayeselo.exe
ResultSet>readpgn anticrux-elo.pgn
639 game(s) loaded, 0 game(s) with unknown result ignored.
ResultSet>elo
ResultSet-EloRating>mm 1 1
ResultSet-EloRating>exactdist
ResultSet-EloRating>ratings
Rank Name Elo + - games score oppo. draws
1 Stockfish Level 8 1052 232 152 125 100% -13 0%
4 Stockfish Level 5 322 92 87 128 66% 110 0%
5 AntiCrux Level 9 155 281 274 10 50% 184 0%
11 AntiCrux Level 15 0 262 317 14 18% 431 7%
12 Stockfish Level 4 -28 87 86 103 44% 105 3%
14 AntiCrux Level 4 -52 251 271 13 31% 218 0%
21 Stockfish Level 1 -593 106 125 137 6% 222 0%
23 AntiCrux Level 1 -783 313 491 13 0% 363 0%
ResultSet-EloRating>x
ResultSet>x
The calculated ELO is displayed according to an offset equal to zero. To get the absolute ELO, we should add a value. By choice, this value is determined by the minimization of the difference between FIDE and BayesElo.
Finally, in the library, the ELO is given by a formula based on the natural logarithm.
suicide
, giveaway
and antichess
Precise Score
debug
, history
, journal
, shutdown
and stored
Same Value
MultiPV
AntiCrux is released under the terms of the "GNU Affero General Public License version 3".
/*
AntiCrux - Suicide chess engine acting as desktop engine, web page, mobile application, Internet chess server and library
Copyright (C) 2016-2018, ecrucru
https://github.com/ecrucru/anticrux/
http://ecrucru.free.fr/?page=anticrux
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
Some files of the package contain derivative works subject to the following licenses :
/*
Copyright (C) 2002-2006 Catalin Francu <cata@francu.com>
Some files of the package contain a derivative work based on Nilatac released under GPL v2+.
https://github.com/CatalinFrancu/nilatac/
http://catalin.francu.com/nilatac/
*/
The beautiful chess pieces made by Colin Burnett on Wikipedia are released under the terms of the "Creative Commons Attribution-ShareAlike license version 3.0" (CC BY-SA 3.0).
It is important to know how the options influence a move AntiCrux makes.
Schematically, AntiCrux plays all the possible moves level by level to find a better situation. Finding the possible moves becomes exponential rapidly. Exploring more than 4 half-moves can be complicated. Because AntiChess insists on the forced moves, the number of possible moves can be reduced a lot, allowing the algorithm to explore deeper with an higher efficiency.
Playing one piece is an half-move generating a new position called node. This node will lead to new nodes if there are available moves for the next player. The nodes are connected and the players take turns in the play. This game is modelled with a tree structure whose branches can be cut for its hidden treasure : the right move to play !
The positions are valuated from the bottom. Then by rules of aggregation, the upper levels are weighted based on the number of moves, the strength of the remaining pieces, etc... Once the top level is reached, AntiCrux can pick the move with the best score. It is your job to beat the AI !
The algorithm adopts some randomness to never play the same game. With high levels, the randomness is more reduced.
It is the version of the algorithm implemented for AntiCrux.
The maximal depth is the number of half-moves which can be explored. The value is restricted to the amount of available memory on your computer. Mathematically, there are more possible positions at the beginning of the game, so it is normal to be less restricted by the depth at the end of the game.
The value can be increased drastically if you enable minimizeLiberty. But the game will always play the forced moves even if it is not the best move. This is especially true at the beginning of the game.
If you don't want that, you should reach the maximal depth dynamically at any moment. So you can set the maximal depth to 99, define a maximal number of nodes relevant with the size of your memory (maxNodes).
The number of positions to be analyzed impacts the consumption of memory. When there is not enough memory, the browser will crash and your game will be lost.
If you put the value to zero, the maximal number of nodes is defined by the depth to be reached. The risk of crash is then very high. So this option is more relevant at the end of the game where the possibilities are reduced.
The number of nodes is a known restriction to allow AntiCrux to finish a game properly. If a node is not evaluated because of this limit, AntiCrux may play inaccurately and it will rely on your own arbitration. Make a challenge "Rook vs. King" to see how undeterministic the situation is despite the fact that the rook can win if it has the right initial position.
The simplification consists in playing the forced moves all the time even if is not the best move from a general point of view. It also contributes to reduce the number of nodes and the variety of the game.
The minimization of the liberty of your opponent doesn't necessarily pick the right move. Sometimes it is better to leave more than 1 opportunity of reply to be able to enlarge the strategy. This is very noticeable in the position 4k1nr/7Q/8/8/8/3P4/6PP/6rR b - -
:
This option is relevant when AntiCrux.options.ai.minimizeLiberty is activated. The higher the figure, the higher the nodes and the lower the depth. The recommended values are 1 (forced moves where possible) or 2 (tolerable liberty without forced moves).
When you scan the nodes at the deepest level, the processing order is always the same. To bring some randomness in the game, the randomization of the moves at each level is a good option.
When it is not up to you to play, you can expect your opponent to play his best move. This makes the situation very pessimistic for you. If your opponent is weak, you can turn off this option and you will be able to make higher damages if the chance is on your side.
This option weakens the AI because it relies on the systematic mistake of the opponent to take an advantage if there is an opportunity to win or lose.
It is often used in coordination with the option AntiCrux.options.ai.worstCase.
The best move is assigned a certain score. However, the second best move may be not so different. The tolerance makes additional moves eligible for the best move to play. The higher the tolerance, the less effective the strategy, the more interesting the gameplay.
This option favors the proximity between the pieces independently from their color. It ensures that the pieces meet each other to get trapped. Consequently, it reduces the diversity of the moves and it increases the ability of the AI to win.
The first analysis takes the smallest average distance between every pieces. The second analysis keeps the shortest move in order that the piece doesn't travel too much all over the board. The third analysis is a random pick (if needed).
This option weakens the algorithm by removing randomly some possible moves above a minimal number of moves.
The number is expressed as a percentage between 0 and 100.
This option activates the worst play ever. It just picks randomly among the possible moves.
Mechanically, it deactivates the other options based on the decision tree.
The pieces in Unicode are color-dependent and must be rendered independently from the theme used for the user interface. If your interface is dark, the black pieces are normally rendered in white. So this option cancels this effect.
When you play Black, the board must be rotated at 180°.
When the symbols are activated, some nice Unicode characters will replace the standard letters :
If the unicode characters are not displayed (example: ♛ and ♕), you have to turn off the option.
The option is a number between 1 and 960. It defines a position where the pieces of the first line are shuffled is a precise order.
The classical position is equal to 519. You can read more on Wikipedia.
The option activates the coordinates all around the board.
When the option is disabled, the board is more compact.
To play faster when the moves are forced, you can choose to not perform a deep analysis to evaluate the position of the artificial intelligence.
The statistics will be updated the next time several moves are possible. So this option accelerates the game play.
To not interfere with your thinking, the statistics are not generated when you play. You can use a hint on demand from the general user interface.
The option allows the discovery of the expected next moves. Because of the complexity of the rules, the output is for informational purposes only.
An higher depth for the assistant implies the anticipation of more moves and an higher reliability of the suggested moves at low depth.
This option is used for debugging purposes in the process of developing AntiCrux.
This option assigns the same value to all the pieces. The engine will then only count the pieces on the board and will not try to sacrifice the queen as soon as possible for example.
Some engines don't accept the rule "en passant". So to comply with this restriction, you can (de)activate this chess rule.
With this option, you immediately promote paws as queen. You cannot choose for another piece.
The queen can move also like the knight. It doesn't affect the weight used for the valuation of this piece.
This option rotates the board by 90° to simulate an error in the preparation of the game. Every cell of the board has then the wrong color.
This human-related option renders the board differently. It may be used to reduce the readability of the game but the players must still follow the basic rules. The possible modes are :
The export to FEN and PGN is not impacted.
This option randomizes the start positions of the pieces across the board. On contrary to AntiChess960, the pieces are really mixed up and your attack must be carefully planned in advance to take advantage of the obvious disorder.
The options above are combined into predefined levels in a range from 1 to 20. They serve for AntiCrux Server and AntiCrux Engine.
Please note that the web-interface offers all the options individually and fewer predefined levels.
Level | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
maxDepth | 3 | 8 | 6 | 5 | 4 | 5 | 6 | 6 | 6 | 6 | 8 | 8 | 8 | 10 | 10 | 20 | 99 | 99 | 99 | 99 |
maxNodes | 100 | 50k | 40k | 30k | 30k | 40k | 50k | 60k | 70k | 80k | 90k | 100k | 200k | 300k | 400k | 500k | 600k | 700k | 850k | 1M |
minimizeLiberty | - | - | - | - | - | - | - | X | X | X | X | X | X | X | X | X | X | X | X | X |
maxReply | 1 | 99 | 4 | 3 | 3 | 3 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 |
randomizedSearch | X | X | X | X | X | X | X | X | X | X | X | X | X | X | - | - | - | - | - | - |
worstCase | - | - | - | - | - | - | - | - | - | X | X | X | X | X | X | X | X | X | X | X |
opportunistic | - | - | - | X | X | X | X | X | X | X | X | X | - | - | - | - | - | - | - | - |
tolerance | 100 | 20 | 18 | 16 | 14 | 12 | 10 | 9 | 8 | 7 | 6 | 5 | 3 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
distance | - | - | - | - | - | - | - | - | - | - | - | X | X | X | X | X | X | X | X | X |
openingBook | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 2 | 4 | 4 | 6 | 6 | 8 | 10 | 12 | 12 | 12 |
handicap | 0 | 80 | 60 | 40 | 20 | 10 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
oyster | X | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
The board is a mono-dimensional 8x8 array of 64 cells. Black is at the top and White is at the bottom, whatever the rotation of the board.
The pieces are represented with an arbitrary internal identifier :
The pieces are owned by a player :
The moves are identified by different notation systems :
Algebraic notation : e3
, Ra6
, Nfxe5
, h8=Q
... This classical notation for the moves is practical for the human players but it necessitates a complex processing to convert it into 2 couples of X/Y coordinates. It is used when the moves have to be publicly displayed or exported.
Index-based notation : every cell is assigned to a sequential counter. It starts with 0
(A8) and ends with 63
(H1). This notation is internally used to highlight the moves because it requires no conversion when AntiCrux loops on a mono-dimensional array.
A | B | C | D | E | F | G | H | |
---|---|---|---|---|---|---|---|---|
8 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
6 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
5 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
4 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
3 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
2 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
1 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
51201
(5+12+01) is equal to cxb8=Q
.A | B | C | D | E | F | G | H | |
---|---|---|---|---|---|---|---|---|
8 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 |
7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
6 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
5 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
4 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
3 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
2 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
1 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
A | B | C | D | E | F | G | H | |
---|---|---|---|---|---|---|---|---|
8 | A | B | C | D | E | F | G | H |
7 | I | J | K | L | M | N | O | P |
6 | Q | R | S | T | U | V | W | X |
5 | X | Z | _ | µ | 0 | 1 | 2 | 3 |
4 | 4 | 5 | 6 | 7 | 8 | 9 | a | b |
3 | c | d | e | f | g | h | i | j |
2 | k | l | m | n | o | p | q | r |
1 | s | t | u | v | w | x | y | z |
Any field or method beginning with an underscore is a private member which is not expected to be called directly by a third-party application, unless you know exactly what you are doing.
A node is an object which represents a state of the board with additional information. It is linked with other nodes to describe the possible target positions through a network of moves. The principal node is the "root node" (a private attribute), so by using the public methods of the library, you should not have to handle the nodes on your own. That's why the parameter pNode is generally optional.
Note : to get an extended help about the API, you can refer to the comments written in the library itself. Or they can be read from a web-browser by using YuiDoc. Run the script run_yuidoc_server.bat
(Windows) or run_yuidoc_server.sh
(Linux), then access to http://localhost:3000