feat: scripts for automated chess tournaments and analysis
This commit is contained in:
parent
4ee30bd278
commit
1d651de4a0
82
contrib/fast-chess-branch.sh
Executable file
82
contrib/fast-chess-branch.sh
Executable file
@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
# Runs a fast-chess (https://github.com/Disservin/fastchess) tournament based
|
||||
# on two branches of the chess_inator
|
||||
# (https://github.com/dogeystamp/chess_inator) engine.
|
||||
#
|
||||
# Example usage:
|
||||
#
|
||||
# cd chess_tournaments
|
||||
# fast-chess-branch.sh quiescence no-quiescence -openings file=8moves_v3.pgn format=pgn order=random -each tc=300+0.1 -rounds 12 -repeat -concurrency 8 -recover -sprt elo0=0 elo1=10 alpha=0.05 beta=0.05
|
||||
#
|
||||
# Do not use `main` as a branch, or any other branch already checked out in
|
||||
# another directory. You need to be in a chess_inator Git repository to run
|
||||
# this script. Ensure that the repository you're in is a throw-away worktree.
|
||||
# Create one using
|
||||
#
|
||||
# git worktree add ../chess_tournaments
|
||||
#
|
||||
# inside the original chess_inator repo.
|
||||
# Also, get an opening book from Stockfish's books:
|
||||
#
|
||||
# curl -O https://github.com/official-stockfish/books/raw/refs/heads/master/8moves_v3.pgn.zip
|
||||
#
|
||||
# The sprt mode is a statistical hypothesis testing mode that will tell you how
|
||||
# probably the first branch is better than the second branch. The Elo ratings
|
||||
# given are the "indifference zone" where the result is acceptable. To check
|
||||
# that the engine hasn't had a regression, set them to [-10, 0]. To check for
|
||||
# an improvement, use [0, 10]. Alpha and beta are probabilities for statistical
|
||||
# errors. The tournament automatically ends when a statistically significant
|
||||
# result is obtained.
|
||||
#
|
||||
# By default, a PGN file will be exported with the games played, and the
|
||||
# fast-chess SPRT output will be appended. This comment may interfere with
|
||||
# importing the PGN. But Lichess will ignore it, so it's probably fine.
|
||||
|
||||
set -e
|
||||
|
||||
BRANCH1="$1"
|
||||
BRANCH2="$2"
|
||||
|
||||
# if this line fails it's because you don't have enough arguments
|
||||
shift 2
|
||||
|
||||
COMM1=$(git rev-parse --short "$BRANCH1")
|
||||
COMM2=$(git rev-parse --short "$BRANCH2")
|
||||
|
||||
mkdir -p games
|
||||
|
||||
PGN=games/"$BRANCH1"__"$BRANCH2".pgn
|
||||
|
||||
rm -f engine1 engine2
|
||||
if [ -f "$PGN" ]; then
|
||||
rm -i "$PGN"
|
||||
fi
|
||||
|
||||
git switch "$BRANCH1"
|
||||
cargo build --release
|
||||
cp target/release/chess_inator engine1
|
||||
|
||||
git switch "$BRANCH2"
|
||||
cargo build --release
|
||||
cp target/release/chess_inator engine2
|
||||
|
||||
OUTPUT=$(mktemp)
|
||||
|
||||
fastchess \
|
||||
-engine cmd=engine1 name="c_i $BRANCH1 ($COMM1)" \
|
||||
-engine cmd=engine2 name="c_i $BRANCH2 ($COMM2)" \
|
||||
-pgnout file="$PGN" \
|
||||
timeleft=true \
|
||||
$@ \
|
||||
2>&1 | tee -a "$OUTPUT"
|
||||
|
||||
printf "\n{" >> "$PGN"
|
||||
|
||||
# match between ------- markers in fastchess output, strip newline and then output to PGN
|
||||
awk '/-{50}/{f+=1; print; next} f%2' "$OUTPUT" \
|
||||
| head -c -1 \
|
||||
>> "$PGN"
|
||||
|
||||
printf "}" >> "$PGN"
|
||||
|
||||
rm "$OUTPUT"
|
39
contrib/tl_to_clk.py
Normal file
39
contrib/tl_to_clk.py
Normal file
@ -0,0 +1,39 @@
|
||||
# /usr/bin/env python
|
||||
|
||||
"""
|
||||
Converts PGN files from fast-chess's `tl` time left notation to the standard `%clk` clock time notation.
|
||||
|
||||
May be buggy; other comments may break this script.
|
||||
Takes stdin and converts to stdout.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
pgn_value = sys.stdin.read()
|
||||
|
||||
|
||||
def convert(m: re.Match[str]) -> str:
|
||||
seconds_total = float(m.group(1))
|
||||
mins, secs = divmod(seconds_total, 60)
|
||||
hrs, mins = divmod(mins, 60)
|
||||
|
||||
secs = round(secs, 4)
|
||||
mins = round(mins)
|
||||
hrs = round(hrs)
|
||||
|
||||
return f"{{ [%clk {hrs}:{mins:02}:{secs}] }}"
|
||||
|
||||
pgn_value = re.sub(
|
||||
pattern=r"{book}",
|
||||
repl="",
|
||||
string=pgn_value,
|
||||
)
|
||||
|
||||
print(
|
||||
re.sub(
|
||||
pattern=r"{.*?tl=(.*?)s.*?}",
|
||||
repl=convert,
|
||||
string=pgn_value,
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue
Block a user