notes
notes copied to clipboard
Resource limited chess engine tournament
Now live at https://rlc-chess.com !
It would be nice if there existed a crossover of demoscene competitions or Dwitter (which focus on achieving the maximum effect with minimum resources) and chess engine competitions (something with a known objective function). So here is one :)
Inspiration: https://www.youtube.com/watch?v=DpXy041BIlA
Tournament categories
The first category will have the following limits:
- max. 5kb .wasm binary file size
- max. 5000 instruction steps per move
If a qualifying program met the static requirements of its category, but exceeds the dynamic bounds during execution, it loses the game. In any case, the objective is creating small/efficient/fun chess bots and let them compete. I have created a Discord Server for this here: https://discord.gg/CyW4hgz4US
More possible categories (combinations possible!)
- compiled program binary size limit (1k bytes, 10k, 100k, ...)
- max. instructions executed per move decision, or per possible legal move
- total move limit it can split up itself over the entire game + per move increment
- different instruction cost tables (time based vs. putting a handicap on i32.mul instructions etc.)
- maximum memory allocation
- different game variants (standard, antichess, chess960, ...)
- with memory or memoryless (reinstantiated every move)
- with randomness source or without
Runtime
We'll be using WebAssembly as runtime, because it is deterministic and supports running untrusted code, and there are a few languages that support it as a compilation target (AssemblyScript, Rust, C/C++, ...). Also, some chess programs like Stockfish were already ported to it.
For the tournament evaluation I'll be using pywasm because it now supports resource limits! For ratings, I'll probably use trueskill.
WebAssembly format
The .wasm binary should export a function move(): i32
that returns a legal move encoded as described above.
Furthermore, it can access the following external functions that take arguments and return values encoded also as shown above:
@external("env", "color")
declare function color(): i32;//returns whether the player is black or white (0 or 1)
@external("env", "board")
declare function board(index: i32): i32;//returns the piece at the given board position
@external("env", "rights")
declare function rights(): i32;//returns en passant and castling rights
Optionally, the tournament category may also allow access to
@external("env", "legal")//returns the nth legal move
declare function legal(index: i32): i32;
@external("env", "maxlegal")//returns the number of possible legal moves
declare function maxlegal(): i32;
@external("env", "randint")//returns a random number between 0 and max (exclusive)
declare function randint(max: i32): i32;
@external("env", "log")//for debugging purposes
declare function log(msg: i32) : i32;
Encodings
Bot Example
This AssemblyScript program will move a pawn if possible, but otherwise chooses a random legal move.
@external("env", "board")
declare function board(index: i32): i32;//returns the piece at the given board position
@external("env", "maxlegal")//returns the number of possible legal moves
declare function maxlegal(): i32;
@external("env", "randint")//returns a random number between 0 and max (exclusive)
declare function randint(max: i32): i32;
@external("env", "legal")//returns the nth legal move
declare function legal(index: i32): i32;
// This is called on every move, it should return a legal move in the correct encoding
// An instance of a program only plays for one side at a time
export function move(): i32 {
// Iterate over all legal moves
for (var i=0;i<maxlegal();i++) {
// Query the board for the piece at the source square of the legal move
var piece = board(legal(i)&(64-1))
// If it is a white or black pawn... (a program may play as black or white, we didn't check
// what color we are, but since legal moves only use our own pieces, we can check this way)
if (piece == 1 || piece == 2) {
// Use this legal move
return legal(i);
}
}
// Otherwise just use a random legal move
return legal(randint(maxlegal()));
}
How to participate
I have uploaded a repo that contains basic AssemblyScript setup instructions and testing code here:
https://github.com/void4/relich
Feel free to write your program in any other language, I just need the resulting .wasm binary.
Join the Discord and submit your program there, remember, this for fun, so your program can be completely terrible :D
If there's more interest I'll create a website for this.
Precedents
There are a few engines with small size in mind, including historical ones, many due to real physical memory limits like
and entries into obfuscated/code golf competitions