ref: 81ff406eac32db854403b45149d46127a94ebe32
parent: a03b6067b6a3064f49b7f99b60bec83129fb4884
author: zamfofex <zamfofex@twdb.moe>
date: Wed Oct 9 00:48:36 EDT 2024
remove infrequently used tools
--- a/.build.yml
+++ b/.build.yml
@@ -24,10 +24,11 @@
shell=bash ./minify.sh
- strip: |
cd moonfish
- strip --strip-all moonfish play lichess analyse battle ribbon chat book
+ strip --strip-all moonfish play lichess analyse chat
wasm-opt -O4 -o moonfish.wasm moonfish.wasm
- deploy: |
set +x
+
if test "x$GIT_REF" = x || ! test -f neocities-token.txt
then exit 0
fi
@@ -43,21 +44,8 @@
-F "$root"/play=@play \
-F "$root"/lichess=@lichess \
-F "$root"/analyse=@analyse \
- -F "$root"/battle=@battle \
- -F "$root"/ribbon=@ribbon \
-F "$root"/chat=@chat \
-F "$root"/moonfish.sh=@moonfish.sh \
-F "$root"/moonfish.exe=@moonfish.exe \
-F "$root"/moonfish.wasm=@moonfish.wasm \
- -F "$root"/book=@book \
- -F "$root"/book.txt=@book.txt \
https://neocities.org/api/upload
-artifacts:
- - moonfish/moonfish
- - moonfish/moonfish.sh
- - moonfish/moonfish.exe
- - moonfish/moonfish.wasm
- - moonfish/play
- - moonfish/lichess
- - moonfish/analyse
- - moonfish/book
--- a/.gitignore
+++ b/.gitignore
@@ -11,28 +11,19 @@
!/moonfish.vcxproj
!/minify.sh
!/rename.sh
-!/compare.sh
!/moonfish.h
!/chess.c
!/search.c
!/main.c
!/mini.c
-!/book.txt
!/tools
!/tools/tools.h
-!/tools/ugi.h
!/tools/utils.c
!/tools/play.c
!/tools/analyse.c
!/tools/lichess.c
-!/tools/battle.c
-!/tools/ribbon.c
!/tools/chat.c
-!/tools/ugi.c
-!/tools/ugi-uci.c
-!/tools/uci-ugi.c
!/tools/https.h
!/tools/https.c
!/tools/perft.c
-!/tools/book.c
!/tools/learn.c
--- a/README.md
+++ b/README.md
@@ -28,8 +28,6 @@
- using moonfish’s tools
- [using “play” and “analyse”](#using-play-and-analyse)
- [using “book”](#using-book) (for adding simple opening book support to bots without it by wrapping them)
- - [using “battle” and “ribbon”](#using-battle-and-ribbon) (for setting up tournaments between bots)
- - [using “ugi-uci” and “uci-ugi”](#using-ugi-uci-and-uci-ugi) (for using UCI bots in UGI programs and vice-versa)
- [using “chat”](#using-chat) and [using “lichess”](#using-lichess) (for integrating with IRC and Lichess)
- [helping improve moonfish!](#contributing-to-moonfish)
- [license](#license)
@@ -41,7 +39,6 @@
- alpha/beta pruning search
- cute custom UCI TUIs
- custom Lichess integration
-- custom UGI/UCI translators
- custom IRC integration
limitations
@@ -98,7 +95,7 @@
make play analyse
~~~
-“play” and “analyse” are TUI that allows you to play against and analyse with UCI bots respectively.
+“play” and “analyse” are TUIs that allows you to play against and analyse with UCI bots respectively.
After compiling and running them, you may use the mouse to click and move pieces around. (So, they require mouse support from your terminal.)
@@ -130,124 +127,6 @@
# (analyse a game using Leela, showing win/draw/loss evaluation)
./analyse lc0 --show-wdl
~~~
-
-using "book"
----
-
-~~~
-make book
-~~~
-
-Opening book support for moonfish is handled with the “book” utility. You specify a opening book file name to it as well as the command for a UCI bot, and it will intercept that bot’s communication with the GUI to make it play certain openings.
-
-The format for opening book files is very simple: One opening per line with move names in either SAN or UCI format separated by spaces. (Move numbers are no allowed.) Empty lines are ignores, `#` is used for comments. Check out the `book.txt` file for an example.
-
-Invalid opening book files will be rejected early.
-
-~~~
-# (have moonfish play openings from the given file)
-./book --file=book.txt ./moonfish
-~~~
-
-using “battle” and “ribbon”
----
-
-~~~
-make battle ribbon
-~~~
-
-The CLI tools, called “battle” and “ribbon” can be used to (respectively) play a single game between two bots and to play a tournament between any given number of bots.
-
-The “battle” CLI may be used to have two UCI or UGI bots play against each other. Each bot has to be specified between brackets (these ones: `[` and `]`).
-
-~~~
-./battle [ stockfish ] [ lc0 --preload ] > game.pgn
-~~~
-
-The bot specified first will play as white (or p1 for UGI) and the bot specified second will play as black (or p2 for UGI).
-
-The program will write a simplified PGN variant to stdout with the game as it happens.
-
-The program will also annouce to stderr the start and end of the game.
-
-If your bot’s command requires a `]` to be used as an argument, you may use double brackets instead, like `./battle [[ unusual ] --foo ]] [ stockfish ]`. You may use as many brackets as necessary, you just have to match them when closing.
-
-If your bot’s command starts with a dash, you may precede it by `--`, like `./battle [ -- -unusual ] [ stockfish ]`
-
-A FEN string may be passed in to the `battle` command, like `./battle --fen='...' [ stockfish ] [ lc0 ]`
-
-You may also pass in a time control, with time and increment both in milliseconds, like `./battle [ --time=6000+500 stockfish ] [ ./moonfish ]` Since each bot may have a different time control, this has to be specified within the backets for a specific bot. The default is fifteen minutes with ten seconds of increment.
-
-You may also pass in `x` as the first character of the given time control to make it “fixed”, which means that it will be reset after every move. This can be used to set a fixed time per move, for example. For example, `./battle [ --time=1000+0 stockfish ] [ --time --time=x1000+0 ./moonfish ]` will set a countdown clock starting at one second for Stockfish, but allow one second for moonfish for every move.
-
-In order to use a UGI bot, you may also pass in `--protocol=ugi` to that bot, like `./battle [ --protocol=ugi some-bot ] [ stockfish ]`. If both bots are UGI, then the game is not assumed to be chess, and the bot playing as p1 will be queried for the status of the game. In that case, the PGN will contain UGI notation as output directly by the engines, rather than SAN notation.
-
-- - -
-
-“ribbon” is a CLI for setting up a round‐robin tournament between multiple bots with the help of the “battle” program mentioned above and a makefile (currently requiring GNU Make).
-
-It will output a makefile to stdout, which may be used by GNU Make to start the tournament between the given bots.
-
-You may use the `-j` option of GNU Make to configure the number of concurrent games to play. Likewise, you may stop a given tournament with `ctrl-c` and continue it by simply running Make again.
-
-You may modify the makefile to prevent certain games from continuing to be played.
-
-Each bot’s command should be passed in as a single argument to `./ribbon`, including potential `--time=...` and `--protocol=...` options to be interpreted by “battle”.
-
-The file name of an opening book may be passed in, and the file should contain one FEN per line. Empty lines and comments starting with `#` are allowed.
-
-In addition, as a matter of convenience, you may specify `--time=...` to “ribbon” itself, which will be passed in verbatim to “battle”.
-
-~~~
-# prepare a tournament between Stockfish, Leela and moonfish:
-./ribbon stockfish lc0 ./moonfish > makefile
-
-# same as above, but with an argument passed in to Leela:
-./ribbon stockfish 'lc0 --preload' ./moonfish > makefile
-
-# same, but with the time control made explicit:
-./ribbon --time=18000+1000 stockfish 'lc0 --preload' ./moonfish > makefile
-
-# same, but with a different time control for Stockfish:
-# (mind the '--' separating "ribbon" options from the bot options for "battle")
-./ribbon --time=18000+1000 -- '--time=6000+0 stockfish' 'lc0 --preload' ./moonfish > makefile
-
-# start the tournament, with at most two games being played at any given time:
-make -j2
-
-# concatenate the resulting game PGNs into a single file.
-cat *.pgn > result.pgn
-~~~
-
-In addition, you may specify the “battle” command to “ribbon”, which must be done if “battle” is not installed on your system as `moonfish-battle`, like `./ribbon --battle=./battle stockfish lc0`
-
-~~~
-# prepare a tournament using the locally-built "battle":
-./ribbon --battle=./battle stockfish lc0 ./moonfish > makefile
-
-# set up a timeout of thirty seconds for each game:
-./ribbon --time=1000+0 --battle='timeout 30 moonfish-battle' stockfish lc0 ./moonfish > makefile
-
-# same as above, but with locally-built "battle":
-./ribbon --time=1000+0 --battle='timeout 30 ./battle' stockfish lc0 ./moonfish > makefile
-
-# pick up the tournament again on every failure (possibly due to timeout):
-while ! make
-do : ; done
-~~~
-
-using “ugi-uci“ and “uci-ugi”
----
-
-~~~
-make ugi-uci uci-ugi
-~~~
-
-`ugi-uci` may be used to let a UGI GUI communicate with a UCI bot, and conversely, `uci-ugi` may be used to let a UCI GUI communicate with a UGI bot.
-
-Simply pass the command of the bot as arguments to either of these tools, and it’ll translate it to be used by the respective GUI.
-
-Note that if the GUI sends a `uci`/`gui` command to the bot that is the same as its protocol, no translation will happen, and the commands will be passed in verbatim between them.
using “chat”
---
--- a/book.txt
+++ /dev/null
@@ -1,152 +1,0 @@
-# Albert Silver's "Silver Opening Suite"
-# <https://www.talkchess.com/forum3/viewtopic.php?t=32532>
-
-# Bird's Opening
-f4 d5 Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O Be2 c5 O-O Nc6
-
-# Reti Opening
-Nf3 Nf6 g3 g6 Bg2 Bg7 O-O O-O d3 d6 e4
-
-# English, Four Knights
-c4 e5 Nc3 Nf6 Nf3 Nc6
-
-# Symmetrical English, Hedgehog
-c4 c5 Nf3 Nf6 g3 b6 Bg2 Bb7 Nc3 e6 O-O Be7 d4 cxd4 Qxd4 d6 Rd1 a6
-
-# Benko Gambit
-d4 Nf6 c4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6
-
-# Benoni, Modern
-d4 Nf6 c4 c5 d5 e6 Nc3 exd5 cxd5 d6 e4 g6
-
-# Dutch, Leningrad
-d4 f5 g3 Nf6 Bg2 g6 Nf3 Bg7 O-O O-O c4 d6 Nc3 Qe8 d5
-
-# Dutch, Stonewall
-d4 f5 g3 Nf6 Bg2 e6 c4 d5 Nf3 c6 O-O Bd6 b3 Qe7
-
-# Scandinavian
-e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 c6 Bc4
-
-# Alekhine, Nf3
-e4 Nf6 e5 Nd5 d4 d6 Nf3
-
-# Pirc, Classical
-e4 d6 d4 Nf6 Nc3 g6 Nf3 Bg7 Be2 O-O O-O c6
-
-# Pirc, Austrian attack
-e4 d6 d4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O
-
-# Caro-Kann, Advance
-e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 c5
-
-# Caro-Kann, Panov
-e4 c6 d4 d5 exd5 cxd5 c4 Nf6 Nc3 e6 Nf3
-
-# Caro-Kann, Classical
-e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 Bxd3 Qxd3
-
-# Sicilian, 2.c3
-e4 c5 c3 d5 exd5 Qxd5 d4 Nf6 Nf3 e6
-
-# Sicilian, Closed
-e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O
-
-# Sicilian, Sveshnikov
-e4 c5 Nf3 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e5 Ndb5 d6 Bg5 a6 Na3 b5 Bxf6 gxf6 Nd5 f5
-
-# Sicilian, Maroczy Bind
-e4 c5 Nf3 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2
-
-# Sicilian, Paulsen
-e4 c5 Nf3 e6 d4 cxd4 Nxd4 Nc6 Nc3 a6
-
-# Sicilian, Richter-Rauzer
-e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 Nc6 Bg5 e6 Qd2 a6 O-O-O h6
-
-# Sicilian, Dragon
-e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 g6 Be3 Bg7 f3 O-O Qd2 Nc6 Bc4 Bd7 O-O-O Ne5 Bb3 Rc8
-
-# Sicilian, Scheveningen
-e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 a6 Be2 e6 O-O Be7 f4 O-O
-
-# Sicilian, Najdorf
-e4 c5 Nf3 d6 d4 cxd4 Nxd4 Nf6 Nc3 a6
-
-# French, Advance
-e4 e6 d4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4
-
-# French, Tarrasch
-e4 e6 d4 d5 Nd2 Nf6 e5 Nfd7 c3 c5 Bd3 Nc6
-
-# French, Winawer
-e4 e6 d4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Ne7
-
-# Philidor's Defense
-e4 e5 Nf3 d6 d4 exd4 Nxd4 Nf6 Nc3 Be7
-
-# Petroff Defense
-e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3
-
-# Scotch
-e4 e5 Nf3 Nc6 d4 exd4 Nxd4
-
-# Italian
-e4 e5 Nf3 Nc6 Bc4 Bc5 d3 Nf6 c3 d6 b4 Bb6 a4 a6
-
-# Ruy Lopez, Exchange var
-e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 d4 exd4 Qxd4 Qxd4 Nxd4
-
-# Spanish, Closed - Archangels
-e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bc5
-
-# Spanish, Open
-e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6
-
-# Spanish, Closed - Zaitsev
-e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 Bb7 d4 Re8 Nbd2
-
-# Colle system
-Nf3 Nf6 d4 d5 e3 e6 c3 c5 Bd3
-
-# Queen's Gambit, Slav
-d4 d5 c4 c6 Nf3 Nf6 Nc3 dxc4 a4 Bf5
-
-# Tarrasch Defense
-d4 d5 c4 e6 Nc3 c5 cxd5 exd5 Nf3 Nc6 g3 Nf6 Bg2 Be7 O-O O-O Bg5
-
-# Queen's Gambit, Semi-Slav
-d4 d5 c4 c6 Nf3 Nf6 Nc3 e6 e3 Nbd7 Bd3
-
-# Queen's Gambit declined, Tartakower
-d4 d5 c4 e6 Nc3 Nf6 Bg5 Be7 e3 O-O Nf3 h6 Bh4 b6
-
-# Gruenfeld, Fianchetto
-d4 Nf6 c4 g6 g3 Bg7 Bg2 O-O Nf3 d5 cxd5 Nxd5 O-O
-
-# Gruenfeld, Classical
-d4 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2
-
-# Catalan, Closed
-d4 Nf6 c4 e6 Nf3 d5 g3 Be7 Bg2 O-O
-
-# Bogo-Indian
-d4 Nf6 c4 e6 Nf3 Bb4+ Bd2 Qe7 g3
-
-# Queen's Indian
-d4 Nf6 c4 e6 Nf3 b6 g3
-
-# Nimzo-Indian, 4.Qc2
-d4 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O a3 Bxc3+ Qxc3
-
-# Nimzo-Indian, Rubinstein
-d4 Nf6 c4 e6 Nc3 Bb4 e3 O-O Bd3 d5 Nf3 c5 O-O
-
-# King's Indian, Fianchetto
-d4 Nf6 c4 g6 Nc3 Bg7 g3 O-O Bg2 d6 Nf3 Nbd7 O-O e5 e4
-
-# King's Indian, Saemisch
-d4 Nf6 c4 g6 Nc3 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 c6
-
-# King's Indian, Classical
-d4 Nf6 c4 g6 Nc3 Bg7 e4 d6 Nf3 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 Nd7 Be3 f5 f3 f4 Bf2 g5
--- a/compare.sh
+++ /dev/null
@@ -1,61 +1,0 @@
-#!/usr/bin/env bash
-
-# moonfish is licensed under the AGPL (v3 or later)
-# copyright 2024 zamfofex
-
-set -ex
-set -o shwordsplit || :
-
-# note: this script has been tested to work with Bash and Zsh
-# (to use Zsh, invoke it explicitly: 'zsh compare.sh')
-
-# note: use this script only from the root/project directory
-
-make=gmake
-which "$make" &> /dev/null || make=make
-
-rm -f moonfish
-mkdir -p compare
-[[ -f compare/openings.fen ]] || wget -O- https://moonfish.neocities.org/pohl.fen.xz | xz -d > compare/openings.fen
-
-dirty=
-[[ "x$(git status --porcelain)" = x ]] || dirty=-dirty
-
-rev1="$(git rev-parse --short HEAD)"
-"$make" moonfish
-mv -f moonfish compare/moonfish-"$rev1$dirty"
-
-git stash
-git switch "${1:-main}"-
-rev2="$(git rev-parse --short HEAD)"
-"$make" moonfish
-mv -f moonfish compare/moonfish-"$rev2"
-
-[[ "$rev1" = "$rev2" ]] || git switch -
-[[ "x$dirty" = x ]] || git stash pop
-
-cd compare
-
-cli=c-chess-cli
-cli_args="-pgn games.pgn"
-format=
-protocol=
-
-if ! which "$cli" &> /dev/null
-then
- cli=cutechess-cli
- cli_args='-pgnout games.pgn'
- format=format=epd
- protocol=proto=uci
-fi
-
-"$cli" \
- -engine {name=,cmd=./}moonfish-"$rev1$dirty" \- -engine {name=,cmd=./}moonfish-"$rev2" \- -each $protocol tc=inf/4+0.125 \
- -openings $format file=openings.fen order=random \
- -games 2 -rounds 64 \
- -sprt elo0=0 elo1=12 alpha=0.05 beta=0.05 \
- -concurrency 1 \
- $cli_args
--- a/makefile
+++ b/makefile
@@ -12,11 +12,10 @@
wasm_cc := $(cc) -D_POSIX_C_SOURCE=199309L
tools_src := moonfish.h tools/tools.h tools/utils.c chess.c
-ugi_src := $(tools_src) tools/ugi.h tools/ugi.c tools/ugi-uci.c
.PHONY: all clean install uninstall check
-all: moonfish play lichess analyse battle ribbon chat uci-ugi ugi-uci book
+all: moonfish play lichess analyse chat
moonfish moonfish.exe: moonfish.h chess.c search.c main.c
$(moonfish_cc) -o $@ $(filter %.c,$^)
@@ -33,12 +32,6 @@
chat: $(tools_src) tools/chat.c tools/https.c
$(tools_cc) -o $@ $(filter %.c,$^) -ltls -lssl -lcrypto
-ugi-uci: $(ugi_src)
- $(tools_cc) -o $@ $(filter %.c,$^)
-
-uci-ugi: $(ugi_src)
- $(tools_cc) -o $@ $(filter %.c,$^)
-
learn: $(tools_src) search.c tools/learn.c
$(tools_cc) -Dmoonfish_learn -o $@ $(filter %.c,$^)
@@ -53,11 +46,7 @@
install -D -m 755 play $(BINDIR)/moonfish-play
install -D -m 755 lichess $(BINDIR)/moonfish-lichess
install -D -m 755 analyse $(BINDIR)/moonfish-analyse
- install -D -m 755 battle $(BINDIR)/moonfish-battle
- install -D -m 755 ribbon $(BINDIR)/moonfish-ribbon
install -D -m 755 chat $(BINDIR)/moonfish-chat
- install -D -m 755 ugi-uci $(BINDIR)/ugi-uci
- install -D -m 755 uci-ugi $(BINDIR)/uci-ugi
uninstall:
- $(RM) $(BINDIR)/moonfish $(BINDIR)/moonfish-* $(BINDIR)/ugi-uci $(BINDIR)/uci-ugi
+ $(RM) $(BINDIR)/moonfish $(BINDIR)/moonfish-*
--- a/tools/battle.c
+++ /dev/null
@@ -1,491 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "../moonfish.h"
-#include "tools.h"
-
-struct moonfish_bot
-{- char *name;
- FILE *in, *out;
- long int time, increment;
- int fixed_time;
- int ugi;
-};
-
-struct moonfish_battle
-{- struct moonfish_chess chess;
- struct moonfish_bot white, black;
- char *fen;
- int ugi;
- char **moves;
- int move_count;
-};
-
-static void moonfish_usage0(char *argv0)
-{- fprintf(stderr, "usage: %s <options>... '[' <options>... <cmd> <args>... ']' '[' <options>... <cmd> <args>... ']'\n", argv0);
- fprintf(stderr, "options:\n");
- fprintf(stderr, " --fen=<FEN> the starting position of the game\n");
- fprintf(stderr, "bot options:\n");
- fprintf(stderr, " --protocol=<protocol> either 'uci' or 'ugi' (default: 'uci')\n");
- fprintf(stderr, " --time=<time-control> the time and increment for the bot in milliseconds\n");
- fprintf(stderr, " --name=<name> name to be reported in the logs and in the output PGN\n");
- exit(1);
-}
-
-static char *moonfish_option(char *name, char ***argv)
-{- size_t length;
-
- if (**argv == NULL) return NULL;
-
- if (!strcmp(**argv, name))
- {- (*argv)++;
- return *(*argv)++;
- }
-
- length = strlen(name);
- if (!strncmp(**argv, name, length) && (**argv)[length] == '=')
- return *(*argv)++ + length + 1;
-
- return NULL;
-}
-
-static void moonfish_battle_options(struct moonfish_battle *battle, char ***argv)
-{- char *arg;
-
- for (;;)
- {- arg = moonfish_option("--fen", argv);- if (arg != NULL)
- {- battle->fen = arg;
- continue;
- }
-
- break;
- }
-}
-
-static void moonfish_bot_options(char *argv0, struct moonfish_bot *bot, char ***argv)
-{- char *arg;
-
- for (;;)
- {- arg = moonfish_option("--time", argv);- if (arg != NULL)
- {- bot->fixed_time = 0;
- if (arg[0] == 'x')
- {- bot->fixed_time = 1;
- arg++;
- }
-
- if (sscanf(arg, "%ld%ld", &bot->time, &bot->increment) != 2)
- moonfish_usage0(argv0);
-
- continue;
- }
-
- arg = moonfish_option("--protocol", argv);- if (arg != NULL)
- {- if (!strcmp(arg, "uci"))
- bot->ugi = 0;
- else if (!strcmp(arg, "ugi"))
- bot->ugi = 1;
- else
- moonfish_usage0(argv0);
-
- continue;
- }
-
- arg = moonfish_option("--name", argv);- if (arg != NULL)
- {- bot->name = arg;
- continue;
- }
-
- break;
- }
-}
-
-static void moonfish_bot_arguments(char *argv0, struct moonfish_bot *bot, char ***argv)
-{- size_t i, j;
- char **options, **command, *value;
- char *line, *arg;
- char *buffer;
-
- if (**argv == NULL) moonfish_usage0(argv0);
-
- for (i = 0 ; (**argv)[i] != '\0' ; i++)
- if ((**argv)[i] != '[') moonfish_usage0(argv0);
-
- if (i < 1) moonfish_usage0(argv0);
-
- bot->name = NULL;
-
- (*argv)++;
- moonfish_bot_options(argv0, bot, argv);
-
- if (**argv != NULL)
- {- if (!strcmp(**argv, "--"))
- (*argv)++;
- else if (***argv == '-')
- moonfish_usage0(argv0);
- }
-
- options = NULL;
-
- j = 0;
- for (;;)
- {- options = realloc(options, (j + 2) * sizeof *options);
- if (options == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- if (**argv == NULL) moonfish_usage0(argv0);
- options[j++] = *(*argv)++;
-
- if (strlen(**argv) != i) continue;
- if (strspn(**argv, "]") != i) continue;
-
- if (**argv == NULL) moonfish_usage0(argv0);
- (*argv)++;
- break;
- }
-
- if (j < 1) moonfish_usage0(argv0);
-
- options[j] = NULL;
-
- command = options;
-
- while (strchr(*command, '=') != NULL)
- command++;
- if (*command != NULL && !strcmp(*command, "--"))
- command++;
-
- moonfish_spawn(command, &bot->in, &bot->out, NULL);
-
- if (bot->ugi) fprintf(bot->in, "ugi\n");
- else fprintf(bot->in, "uci\n");
-
- for (;;)
- {- line = moonfish_next(bot->out);
- if (line == NULL) exit(1);
-
- arg = strtok_r(line, "\r\n\t ", &buffer);
- if (arg == NULL) continue;
-
- if (!strcmp(arg, bot->ugi ? "ugiok" : "uciok")) break;
-
- if (bot->name != NULL) continue;
-
- if (strcmp(arg, "id")) continue;
-
- arg = strtok_r(NULL, "\r\n\t ", &buffer);
- if (arg == NULL) continue;
- if (strcmp(arg, "name")) continue;
-
- arg = strtok_r(NULL, "\r\n", &buffer);
- if (arg == NULL) continue;
-
- bot->name = strdup(arg);
- if (bot->name == NULL)
- {- perror(argv0);
- exit(1);
- }
- }
-
- if (bot->name == NULL) bot->name = command[0];
-
- j = 0;
- for (;;)
- {- value = strchr(options[j], '=');
- if (value == NULL) break;
- fprintf(bot->in, "setoption name %.*s value %s\n", (int) (value - options[j]), options[j], value + 1);
- j++;
- }
-
- free(options);
-
- fprintf(bot->in, "isready\n");
- moonfish_wait(bot->out, "readyok");
-
- if (bot->ugi) fprintf(bot->in, "uginewgame\n");
- else fprintf(bot->in, "ucinewgame\n");
-}
-
-static void moonfish_bot_play(char *argv0, struct moonfish_battle *battle, struct moonfish_bot *bot)
-{- static char name[16];
-
- char *white, *black;
- int i;
- char *arg;
- char *buffer;
- struct moonfish_move move;
- struct timespec t0, t1;
-
- if (!bot->fixed_time && clock_gettime(CLOCK_MONOTONIC, &t0))
- {- perror(argv0);
- exit(1);
- }
-
- fprintf(bot->in, "isready\n");
- moonfish_wait(bot->out, "readyok");
-
- if (battle->fen)
- fprintf(bot->in, "position fen %s", battle->fen);
- else
- fprintf(bot->in, "position startpos");
-
- if (battle->move_count > 0)
- {- fprintf(bot->in, " moves");
- for (i = 0 ; i < battle->move_count ; i++)
- fprintf(bot->in, " %s", battle->moves[i]);
- }
-
- fprintf(bot->in, "\n");
-
- if (bot->ugi)
- white = "p1",
- black = "p2";
- else
- white = "w",
- black = "b";
-
- fprintf(bot->in, "go");
- fprintf(bot->in, " %stime %ld", white, battle->white.time);
- if (battle->white.increment > 0) fprintf(bot->in, " %sinc %ld", white, battle->white.increment);
- fprintf(bot->in, " %stime %ld", black, battle->black.time);
- if (battle->black.increment > 0) fprintf(bot->in, " %sinc %ld", black, battle->black.increment);
- fprintf(bot->in, "\n");
-
- arg = moonfish_wait(bot->out, "bestmove");
- arg = strtok_r(arg, "\r\n\t ", &buffer);
- if (arg == NULL)
- {- fprintf(stderr, "%s: invalid 'bestmove'\n", argv0);
- exit(1);
- }
- arg = strdup(arg);
- if (arg == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- battle->moves = realloc(battle->moves, (battle->move_count + 1) * sizeof *battle->moves);
- if (battle->moves == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- battle->moves[battle->move_count++] = arg;
- if (!battle->ugi)
- {- if (moonfish_from_uci(&battle->chess, &move, arg))
- {- fprintf(stderr, "%s: invalid move '%s' from the bot\n", argv0, arg);
- exit(1);
- }
-
- moonfish_to_san(&battle->chess, &move, name);
- printf("%s ", name);-
- battle->chess = move.chess;
- }
- else
- {- printf("%s ", arg);- }
-
- if (!bot->fixed_time)
- {- if (clock_gettime(CLOCK_MONOTONIC, &t1))
- {- perror(argv0);
- exit(1);
- }
-
- bot->time += bot->increment;
- bot->time -= (t1.tv_sec - t0.tv_sec) * 1000;
- bot->time -= (t1.tv_nsec - t0.tv_nsec) / 1000000;
- }
-}
-
-static int moonfish_battle_play(char *argv0, struct moonfish_battle *battle)
-{- int white;
- char *arg;
- char *buffer;
-
- if (battle->ugi)
- {- fprintf(battle->white.in, "isready\n");
- moonfish_wait(battle->white.out, "readyok");
-
- fprintf(battle->white.in, "query result\n");
- arg = moonfish_wait(battle->white.out, "response");
- arg = strtok_r(arg, "\r\n\t ", &buffer);
- if (arg == NULL)
- {- fprintf(stderr, "%s: invalid 'response'\n", argv0);
- exit(1);
- }
-
- if (!strcmp(arg, "p1win"))
- {- printf("1-0\n");- return 0;
- }
- if (!strcmp(arg, "p2win"))
- {- printf("0-1\n");- return 0;
- }
- if (!strcmp(arg, "draw"))
- {- printf("1/2-1/2\n");- return 0;
- }
-
- fprintf(battle->white.in, "isready\n");
- moonfish_wait(battle->white.out, "readyok");
-
- fprintf(battle->white.in, "query p1turn\n");
- arg = moonfish_wait(battle->white.out, "response");
- arg = strtok_r(arg, "\r\n\t ", &buffer);
- if (arg == NULL)
- {- fprintf(stderr, "%s: invalid 'response'\n", argv0);
- exit(1);
- }
-
- if (!strcmp(arg, "true"))
- white = 1;
- else
- white = 0;
- }
- else
- {- white = battle->chess.white;
- if (moonfish_finished(&battle->chess))
- {- if (moonfish_check(&battle->chess))
- {- if (white) printf("0-1\n");- else printf("1-0\n");- }
- else
- {- printf("1/2-1/2\n");- }
-
- return 0;
- }
- }
-
- if (white)
- {- moonfish_bot_play(argv0, battle, &battle->white);
- if (battle->white.time < -125)
- {- printf("0-1 {timeout}\n");- return 0;
- }
- if (battle->white.time < 10) battle->white.time = 10;
- }
- else
- {- moonfish_bot_play(argv0, battle, &battle->black);
- if (battle->black.time < -125)
- {- printf("1-0 {timeout}\n");- return 0;
- }
- if (battle->black.time < 10) battle->black.time = 10;
- }
-
- return 1;
-}
-
-int main(int argc, char **argv)
-{- static struct moonfish_battle battle;
-
- char *argv0;
-
- (void) argc;
-
- moonfish_spawner(argv[0]);
-
- battle.fen = NULL;
-
- battle.white.time = 15 * 60000;
- battle.white.increment = 10000;
- battle.white.fixed_time = 0;
- battle.white.ugi = 0;
-
- battle.black.time = 15 * 60000;
- battle.black.increment = 10000;
- battle.black.fixed_time = 0;
- battle.black.ugi = 0;
-
- argv0 = *argv++;
- moonfish_battle_options(&battle, &argv);
-
- moonfish_bot_arguments(argv0, &battle.white, &argv);
- moonfish_bot_arguments(argv0, &battle.black, &argv);
-
- if (*argv != NULL) moonfish_usage0(argv0);
-
- battle.ugi = 0;
- if (battle.white.ugi && battle.black.ugi)
- battle.ugi = 1;
-
- if (!battle.ugi)
- {- moonfish_chess(&battle.chess);
- if (battle.fen && moonfish_from_fen(&battle.chess, battle.fen)) moonfish_usage0(argv0);
- }
-
- battle.moves = NULL;
- battle.move_count = 0;
-
- fprintf(stderr, "starting %s vs %s\n", battle.white.name, battle.black.name);
-
- printf("[White \"%s\"]\n", battle.white.name);- printf("[Black \"%s\"]\n", battle.black.name);- if (battle.fen != NULL) printf("[FEN \"%s\"]\n", battle.fen);- while (moonfish_battle_play(argv0, &battle)) { }- printf("\n");-
- fprintf(stderr, "finished %s vs %s\n", battle.white.name, battle.black.name);
- return 0;
-}
--- a/tools/book.c
+++ /dev/null
@@ -1,275 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "../moonfish.h"
-#include "tools.h"
-
-static pthread_mutex_t moonfish_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void *moonfish_book_start(void *data)
-{- FILE *out;
- char line[2048];
- out = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, out) == NULL) exit(0);
- pthread_mutex_lock(&moonfish_mutex);
- fputs(line, stdout);
- fflush(stdout);
- pthread_mutex_unlock(&moonfish_mutex);
- }
-}
-
-static int moonfish_compare_string(const void *a, const void *b)
-{- return strcmp(a, b);
-}
-
-int main(int argc, char **argv)
-{- static char line0[2048];
- static char line[2048];
- static char names[64][6];
- static char *format = "<cmd> <args>...";
- static struct moonfish_arg args[] =
- {- {"F", "file", "<book>", NULL, "opening book"},- {NULL, NULL, NULL, NULL, NULL},- };
- static char book[256][64][6];
- static char choices[256][6];
- static char unique_choices[256][6];
-
- char **command;
- int command_count;
- FILE *file;
- int i, j, k;
- struct moonfish_chess chess;
- struct moonfish_move move;
- char *arg;
- FILE *in, *out;
- int error;
- pthread_t thread;
-
- moonfish_spawner(argv[0]);
-
- command = moonfish_args(args, format, argc, argv);
- if (args[0].value == NULL) moonfish_usage(args, format, argv[0]);
-
- command_count = argc - (command - argv);
- if (command_count < 1) moonfish_usage(args, format, argv[0]);
-
- srand(time(NULL));
-
- i = 0;
-
- file = fopen(args[0].value, "r");
- if (file == NULL)
- {- perror(argv[0]);
- return 1;
- }
-
- for (;;)
- {- errno = 0;
- if (fgets(line, sizeof line, file) == NULL)
- {- if (errno)
- {- perror(argv[0]);
- return 1;
- }
-
- break;
- }
-
- arg = strtok(line, "\r\n\t ");
- if (arg == NULL || arg[0] == '#')
- continue;
-
- if (i >= (int) (sizeof book / sizeof *book - 1))
- {- fprintf(stderr, "%s: Too many openings in book, ignoring some.\n", argv[0]);
- break;
- }
-
- moonfish_chess(&chess);
-
- j = 0;
-
- for (;;)
- {- if (j >= (int) (sizeof *book / sizeof **book - 1))
- {- fprintf(stderr, "%s: Too many moves in opening, ignoring some.\n", argv[0]);
- break;
- }
-
- if (moonfish_from_san(&chess, &move, arg))
- {- fprintf(stderr, "%s: Invalid move in opening: %s\n", argv[0], arg);
- return 1;
- }
-
- moonfish_to_uci(&chess, &move, book[i][j++]);
- chess = move.chess;
-
- arg = strtok(NULL, "\r\n\t ");
- if (arg == NULL || arg[0] == '#')
- break;
- }
-
- book[i++][j][0] = 0;
- }
-
- book[i][0][0] = 0;
-
- if (i == 0) fprintf(stderr, "%s: Empty book.\n", argv[0]);
-
- moonfish_spawn(command, &in, &out, NULL);
-
- error = pthread_create(&thread, NULL, moonfish_book_start, out);
- if (error != 0)
- {- fprintf(stderr, "%s: %s\n", argv[0], strerror(error));
- return 1;
- }
-
- names[0][0] = 0;
-
- for (;;)
- {- errno = 0;
- if (fgets(line0, sizeof line0, stdin) == NULL)
- {- if (errno)
- {- perror(argv[0]);
- return 1;
- }
-
- break;
- }
-
- strcpy(line, line0);
-
- arg = strtok(line, "\r\n\t ");
- if (arg == NULL) continue;
-
- if (!strcmp(arg, "quit"))
- {- pthread_mutex_lock(&moonfish_mutex);
- fputs("quit\n", in);- fflush(stdout);
- pthread_mutex_unlock(&moonfish_mutex);
- break;
- }
- else if (!strcmp(arg, "position"))
- {- names[0][0] = '-';
- names[0][1] = 0;
-
- arg = strtok(NULL, "\r\n\t ");
- if (arg != NULL && !strcmp(arg, "startpos"))
- {- arg = strtok(NULL, "\r\n\t ");
- if (arg == NULL)
- {- names[0][0] = 0;
- }
- else if (!strcmp(arg, "moves"))
- {- i = 0;
- while ((arg = strtok(NULL, "\r\n\t ")) != NULL)
- {- if (i >= (int) (sizeof names / sizeof *names - 1)) break;
- if (strlen(arg) > 5) break;
- strcpy(names[i++], arg);
- }
-
- names[i][0] = 0;
- }
- }
- }
- else if (!strcmp(arg, "go"))
- {- arg = strtok(NULL, "\r\n\t ");
- if (arg == NULL || strcmp(arg, "infinite"))
- {- i = 0;
- k = 0;
- for (;;)
- {- if (book[i][0][0] == 0) break;
-
- j = 0;
- for (;;)
- {- if (names[j][0] == 0)
- {- if (book[i][j][0] != 0)
- strcpy(choices[k++], book[i][j]);
- break;
- }
-
- if (strcmp(names[j], book[i][j]))
- break;
-
- j++;
- }
-
- i++;
- }
-
- if (k == 0)
- {- pthread_mutex_lock(&moonfish_mutex);
- fputs(line0, in);
- fflush(stdout);
- pthread_mutex_unlock(&moonfish_mutex);
- continue;
- }
-
- qsort(choices, k, sizeof *choices, &moonfish_compare_string);
-
- i = 1;
- j = 1;
-
- strcpy(unique_choices[0], choices[0]);
- for (;;)
- {- if (j >= k) break;
- if (strcmp(choices[j], choices[j - 1]))
- strcpy(unique_choices[i++], choices[j]);
- j++;
- }
-
- pthread_mutex_lock(&moonfish_mutex);
- printf("bestmove %s\n", unique_choices[rand() % i]);- fflush(stdout);
- pthread_mutex_unlock(&moonfish_mutex);
-
- continue;
- }
- }
-
- pthread_mutex_lock(&moonfish_mutex);
- fputs(line0, in);
- fflush(stdout);
- pthread_mutex_unlock(&moonfish_mutex);
- }
-
- fclose(in);
- pthread_join(thread, NULL);
- return 0;
-}
--- a/tools/ribbon.c
+++ /dev/null
@@ -1,178 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "tools.h"
-
-static int moonfish_brackets(char *command)
-{- int count, max_count;
-
- max_count = 0;
- count = 0;
-
- for (;;)
- {- if (*command == ']')
- {- count++;
- }
- else
- {- if (count > max_count) max_count = count;
- count = 0;
- }
-
- if (*command++ == '\0') break;
- }
-
- return max_count + 1;
-}
-
-int main(int argc, char **argv)
-{- static char line[2048];
- static char *format = "<cmds>...";
- static struct moonfish_arg args[] =
- {- {"F", "openings", "<file-name>", NULL, "an opening book for the tournament (one FEN per line)"},- {"X", "battle", "<command>", "moonfish-battle", "the command to make the two bots play each other"},- {"T", "time", "<time-control>", NULL, "default time control for each bot"},- {NULL, NULL, NULL, NULL, NULL},- };
-
- FILE *openings;
- int bot_count;
- int brackets;
- int i, j, k;
- int opening_count;
- char *battle, *time;
- char *arg, *buffer;
- char **commands;
- int command_count;
-
- commands = moonfish_args(args, format, argc, argv);
- command_count = argc - (commands - argv);
- if (command_count < 1) moonfish_usage(args, format, argv[0]);
-
- openings = NULL;
- battle = args[1].value;
- time = args[2].value;
- if (args[0].value != NULL)
- {- openings = fopen(args[0].value, "r");
- if (openings == NULL)
- {- perror(argv[0]);
- return 1;
- }
- }
-
- printf("# makefile generated by '%s'\n\n", argv[0]);- printf(".PHONY: all\n\n");- printf("n = basename '$@' .pgn | cut -d- -f\n");-
- /* todo: support BSD Make somehow... */
- /* maybe even POSIX Make */
- printf("n1 = $($(shell $n1))\n");- printf("n2 = $($(shell $n2))\n");- printf("n3 = $($(shell $n3))\n\n");-
- bot_count = 0;
-
- for (;;)
- {- if (commands[bot_count] == NULL) break;
-
- brackets = moonfish_brackets(commands[bot_count]);
-
- printf("bot%d = ", bot_count + 1);- for (i = 0 ; i < brackets ; i++) printf("[");- printf(" ");-
- if (time != NULL) printf("--time=%s ", time);-
- /* todo: skip leading whitespace */
- if (commands[bot_count][0] == '-')
- printf("-- ");-
- /* todo: escape for makefile... */
- printf("%s", commands[bot_count]);-
- printf(" ");- for (i = 0 ; i < brackets ; i++) printf("]");- printf("\n");-
- bot_count++;
- }
-
- if (bot_count < 2) fprintf(stderr, "warning: too few bots established for tournament\n");
-
- printf("\n");-
- if (openings == NULL)
- {- printf("all:");- for (i = 0 ; i < bot_count ; i++)
- for (j = 0 ; j < bot_count ; j++)
- {- if (i == j) continue;
- printf(" \\\n\tbot%d-bot%d.pgn", i + 1, j + 1);- }
- printf("\n\n");-
- printf(".DEFAULT:\n");- printf("\t@%s $(n1) $(n2) > $@.on\n", battle);- printf("\t@mv $@.on $@\n");-
- return 0;
- }
-
- opening_count = 0;
-
- for (;;)
- {- errno = 0;
- if (fgets(line, sizeof line, openings) == NULL)
- {- if (errno == 0) break;
- perror(argv[0]);
- return 1;
- }
-
- arg = line + strspn(line, "\r\n\t ");
- if (arg[0] == '#') continue;
-
- arg = strtok_r(arg, "\r\n#", &buffer);
- if (arg == NULL) continue;
-
- printf("opening%d = ", opening_count + 1);- printf("%s\n", arg);-
- opening_count++;
- }
-
- if (opening_count == 0) fprintf(stderr, "warning: empty opening book\n");
-
- printf("\n");-
- printf("all:");- for (i = 0 ; i < bot_count ; i++)
- for (j = 0 ; j < bot_count ; j++)
- {- if (i == j) continue;
- for (k = 0 ; k < opening_count ; k++)
- printf(" \\\n\topening%d-bot%d-bot%d.pgn", k + 1, i + 1, j + 1);- }
- printf("\n\n");-
- printf(".DEFAULT:\n");- printf("\t@%s --fen='$(n1)' $(n2) $(n3) > $@.on\n", battle);- printf("\t@mv $@.on $@\n");-
- return 0;
-}
--- a/tools/uci-ugi.c
+++ /dev/null
@@ -1,109 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "ugi.h"
-
-/* UCI GUI, UGI bot */
-
-char *moonfish_argv0;
-
-int main(int argc, char **argv)
-{- if (argc < 2)
- {- if (argc > 0) fprintf(stderr, "usage: %s <command> <args>...\n", argv[0]);
- return 1;
- }
-
- moonfish_argv0 = argv[0];
- moonfish_convert_ugi(argv[0], argv + 1, "ugi", "uci");
- return 0;
-}
-
-/* read from GUI, write to bot */
-void *moonfish_convert_in(void *data)
-{- FILE *in;
- char line[2048], *arg;
- char *save;
-
- in = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, stdin) == NULL) return NULL;
- save = NULL;
-
- arg = strtok_r(line, "\r\n\t ", &save);
-
- if (arg == NULL) continue;
-
- if (!strcmp(arg, "go"))
- {- fprintf(in, "go");
- for (;;)
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL) break;
- fprintf(in, " ");
- if (!strcmp(arg, "wtime")) fprintf(in, "p1time");
- else if (!strcmp(arg, "btime")) fprintf(in, "p2time");
- else if (!strcmp(arg, "winc")) fprintf(in, "p1inc");
- else if (!strcmp(arg, "binc")) fprintf(in, "p2inc");
- else fputs(arg, in);
- }
- fprintf(in, "\n");
- }
-
- fputs(arg, in);
- for (;;)
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL) break;
- fprintf(in, " %s", arg);
- }
- fprintf(in, "\n");
- }
-}
-
-
-/* read from bot, write to GUI */
-void *moonfish_convert_out(void *data)
-{- FILE *out;
- char line[2048], *arg;
- char *save;
-
- out = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, out) == NULL) exit(0);
- save = NULL;
-
- arg = strtok_r(line, "\r\n\t ", &save);
-
- if (arg == NULL) continue;
-
- if (!strcmp(arg, "ugiok"))
- {- printf("uciok\n");- fflush(stdout);
- continue;
- }
-
- fputs(arg, stdout);
- for (;;)
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL) break;
- printf(" %s", arg);- }
- printf("\n");- fflush(stdout);
- }
-}
--- a/tools/ugi-uci.c
+++ /dev/null
@@ -1,218 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "../moonfish.h"
-#include "ugi.h"
-
-/* UGI GUI, UCI bot */
-
-static char *moonfish_argv0;
-static struct moonfish_chess moonfish_ugi_chess;
-
-int main(int argc, char **argv)
-{- if (argc < 2)
- {- if (argc > 0) fprintf(stderr, "usage: %s <command> <args>...\n", argv[0]);
- return 1;
- }
-
- moonfish_chess(&moonfish_ugi_chess);
- moonfish_argv0 = argv[0];
- moonfish_convert_ugi(argv[0], argv + 1, "ugi", "uci");
- return 0;
-}
-
-/* read from GUI, write to bot */
-void *moonfish_convert_in(void *data)
-{- FILE *in;
- char line[2048], line2[2048], *arg;
- char *save;
- struct moonfish_move move;
-
- in = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, stdin) == NULL) return NULL;
- save = NULL;
- strcpy(line2, line);
-
- arg = strtok_r(line, "\r\n\t ", &save);
-
- if (arg == NULL) continue;
-
- if (!strcmp(arg, "query"))
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL)
- {- fprintf(stderr, "%s: malformed 'query' command\n", moonfish_argv0);
- exit(1);
- }
-
- if (!strcmp(arg, "gameover"))
- {- if (moonfish_finished(&moonfish_ugi_chess))
- printf("response true\n");- else
- printf("response false\n");- continue;
- }
-
- if (!strcmp(arg, "p1turn"))
- {- if (moonfish_ugi_chess.white)
- printf("response true\n");- else
- printf("response false\n");- continue;
- }
-
- if (!strcmp(arg, "result"))
- {- if (!moonfish_finished(&moonfish_ugi_chess))
- printf("response none\n");- else if (!moonfish_checkmate(&moonfish_ugi_chess))
- printf("response draw\n");- else if (moonfish_ugi_chess.white)
- printf("response p2win\n");- else
- printf("response p1win\n");- continue;
- }
-
- fprintf(stderr, "%s: unknown 'query %s' command\n", moonfish_argv0, arg);
- exit(1);
- }
-
- if (!strcmp(arg, "go"))
- {- fprintf(in, "go");
- for (;;)
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL) break;
- fprintf(in, " ");
- if (!strcmp(arg, "p1time")) fprintf(in, "wtime");
- else if (!strcmp(arg, "p2time")) fprintf(in, "btime");
- else if (!strcmp(arg, "p1inc")) fprintf(in, "winc");
- else if (!strcmp(arg, "p2inc")) fprintf(in, "binc");
- else fputs(arg, in);
- }
- fprintf(in, "\n");
- continue;
- }
-
- if (!strcmp(arg, "position"))
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL)
- {- fprintf(stderr, "%s: malformed 'position' command\n", moonfish_argv0);
- exit(1);
- }
-
- if (!strcmp(arg, "startpos"))
- {- moonfish_chess(&moonfish_ugi_chess);
- }
- else if (!strcmp(arg, "fen"))
- {- arg = strtok_r(NULL, "\r\n", &save);
- if (arg == NULL)
- {- fprintf(stderr, "%s: malformed 'position fen' command\n", moonfish_argv0);
- exit(1);
- }
- moonfish_from_fen(&moonfish_ugi_chess, arg);
-
- arg = strstr(arg, "moves");
- if (arg != NULL)
- {- do arg--;
- while (*arg == '\t' || *arg == ' ');
- save = NULL;
- strcpy(line, arg);
- strtok_r(line, "\r\n", &save);
- }
- else
- {- save = NULL;
- strtok_r("", "\r\n", &save);- }
- }
- else
- {- fprintf(stderr, "%s: unknown 'position %s' command\n", moonfish_argv0, arg);
- exit(1);
- }
-
- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg != NULL)
- {- if (strcmp(arg, "moves"))
- {- fprintf(stderr, "%s: unknown '%s' in 'position' command\n", moonfish_argv0, arg);
- exit(1);
- }
-
- for (;;)
- {- arg = strtok_r(NULL, " ", &save);
- if (arg == NULL) break;
- if (moonfish_from_uci(&moonfish_ugi_chess, &move, arg))
- {- fprintf(stderr, "%s: invalid move '%s' from bot\n", moonfish_argv0, arg);
- exit(1);
- }
- moonfish_ugi_chess = move.chess;
- }
- }
- }
-
- fputs(line2, in);
- }
-}
-
-/* read from bot, write to GUI */
-void *moonfish_convert_out(void *data)
-{- FILE *out;
- char line[2048], *arg;
- char *save;
-
- out = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, out) == NULL) exit(0);
- save = NULL;
-
- arg = strtok_r(line, "\r\n\t ", &save);
-
- if (arg == NULL) continue;
-
- if (!strcmp(arg, "uciok"))
- {- printf("ugiok\n");- fflush(stdout);
- continue;
- }
-
- fputs(arg, stdout);
- for (;;)
- {- arg = strtok_r(NULL, "\r\n\t ", &save);
- if (arg == NULL) break;
- printf(" %s", arg);- }
- printf("\n");- fflush(stdout);
- }
-}
--- a/tools/ugi.c
+++ /dev/null
@@ -1,88 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#include <string.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#include "tools.h"
-#include "ugi.h"
-
-static void *moonfish_pipe_in(void *data)
-{- FILE *in;
- char line[2048];
- in = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, stdin) == NULL) return NULL;
- fputs(line, in);
- }
-}
-
-static void *moonfish_pipe_out(void *data)
-{- FILE *out;
- char line[2048];
- out = data;
-
- for (;;)
- {- if (fgets(line, sizeof line, out) == NULL) exit(0);
- fputs(line, stdout);
- fflush(stdout);
- }
-}
-
-void moonfish_convert_ugi(char *argv0, char **argv, char *convert_arg, char *pipe_arg)
-{- FILE *in, *out;
- char line[2048], *arg;
- int error;
- pthread_t thread1, thread2;
- void *(*start1)(void *data);
- void *(*start2)(void *data);
-
- moonfish_spawner(argv0);
- moonfish_spawn(argv, &in, &out, NULL);
-
- for (;;)
- {- if (fgets(line, sizeof line, stdin) == NULL) return;
- arg = strtok(line, "\r\n\t ");
- if (arg == NULL) continue;
-
- if (!strcmp(arg, convert_arg))
- {- fprintf(in, "%s\n", pipe_arg);
- start1 = &moonfish_convert_in;
- start2 = &moonfish_convert_out;
- break;
- }
-
- if (!strcmp(arg, pipe_arg))
- {- fprintf(in, "%s\n", pipe_arg);
- start1 = &moonfish_pipe_in;
- start2 = &moonfish_pipe_out;
- break;
- }
-
- fprintf(stderr, "%s: unknown protocol '%s'\n", argv0, arg);
- exit(1);
- }
-
- error = 0;
- if (error == 0) error = pthread_create(&thread1, NULL, start1, in);
- if (error == 0) error = pthread_create(&thread2, NULL, start2, out);
- if (error == 0) error = pthread_join(thread1, NULL);
- if (error == 0) fclose(in);
- if (error == 0) error = pthread_join(thread2, NULL);
-
- if (error != 0)
- {- fprintf(stderr, "%s: %s\n", argv0, strerror(error));
- exit(1);
- }
-}
--- a/tools/ugi.h
+++ /dev/null
@@ -1,11 +1,0 @@
-/* moonfish is licensed under the AGPL (v3 or later) */
-/* copyright 2024 zamfofex */
-
-#ifndef MOONFISH_UGI
-#define MOONFISH_UGI
-
-void *moonfish_convert_in(void *data);
-void *moonfish_convert_out(void *data);
-void moonfish_convert_ugi(char *argv0, char **argv, char *convert_arg, char *pipe_arg);
-
-#endif
--
⑨