ref: 3a4dd039662549083dfb672a6a78910af84ccce7
parent: 26d5e64b0162c1d46b301a7afb2fd30eee630395
author: zamfofex <zamfofex@twdb.moe>
date: Sat Jun 22 22:46:41 EDT 2024
improve ‘battle’ and ‘ribbon’ slightly
--- a/README.md
+++ b/README.md
@@ -152,7 +152,7 @@
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 moves will be in UCI/UGI format, rather than SAN.
+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.
@@ -162,11 +162,11 @@
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 15 minutes with ten seconds of increment.
+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 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.
- - -
--- a/tools/battle.c
+++ b/tools/battle.c
@@ -237,14 +237,15 @@
else fprintf(bot->in, "ucinewgame\n");
}
-static char *moonfish_bot_play(char *argv0, struct moonfish_battle *battle, struct moonfish_bot *bot)
+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))
@@ -314,8 +315,15 @@
exit(1);
}
+ moonfish_to_san(&battle->chess, &move, name);
+ printf("%s ", name);+
battle->chess = move.chess;
}
+ else
+ {+ printf("%s ", arg);+ }
if (!bot->fixed_time)
{@@ -329,8 +337,6 @@
bot->time -= (t1.tv_sec - t0.tv_sec) * 1000;
bot->time -= (t1.tv_nsec - t0.tv_nsec) / 1000000;
}
-
- return arg;
}
static int moonfish_battle_play(char *argv0, struct moonfish_battle *battle)
@@ -407,7 +413,7 @@
if (white)
{- arg = moonfish_bot_play(argv0, battle, &battle->white);
+ moonfish_bot_play(argv0, battle, &battle->white);
if (battle->white.time < -125)
{ printf("0-1 {timeout}\n");@@ -417,7 +423,7 @@
}
else
{- arg = moonfish_bot_play(argv0, battle, &battle->black);
+ moonfish_bot_play(argv0, battle, &battle->black);
if (battle->black.time < -125)
{ printf("1-0 {timeout}\n");@@ -425,8 +431,6 @@
}
if (battle->black.time < 10) battle->black.time = 10;
}
-
- printf("%s ", arg);return 1;
}
--- a/tools/ribbon.c
+++ b/tools/ribbon.c
@@ -6,72 +6,8 @@
#include <string.h>
#include <errno.h>
-static void moonfish_usage0(char *argv0)
-{- fprintf(stderr, "usage: %s <options>... <cmds>...\n", argv0);
- fprintf(stderr, "options:\n");
- fprintf(stderr, " --openings=<file-name> an opening book for the tournament (one FEN per line)\n");
- fprintf(stderr, " --battle=<command> the command to make the two bots play each other\n");
- fprintf(stderr, " --time=<time-control> default time control for each bot\n");
- exit(1);
-}
+#include "tools.h"
-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_options(char *argv0, FILE **openings, char **battle, char **time, char ***argv)
-{- char *arg;
-
- for (;;)
- {- arg = moonfish_option("--openings", argv);- if (arg != NULL)
- {- *openings = fopen(arg, "r");
- if (*openings == NULL)
- {- perror(argv0);
- exit(1);
- }
-
- continue;
- }
-
- arg = moonfish_option("--battle", argv);- if (arg != NULL)
- {- *battle = arg;
- continue;
- }
-
- arg = moonfish_option("--time", argv);- if (arg != NULL)
- {- *time = arg;
- continue;
- }
-
- break;
- }
-}
-
static int moonfish_brackets(char *command)
{int count, max_count;
@@ -100,8 +36,15 @@
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},+ };
- char *argv0;
FILE *openings;
int bot_count;
int brackets;
@@ -109,26 +52,27 @@
int opening_count;
char *battle, *time;
char *arg, *buffer;
+ char **commands;
+ int command_count;
- if (argc < 1) return 1;
+ commands = moonfish_args(args, format, argc, argv);
+ command_count = argc - (commands - argv);
+ if (command_count < 1) moonfish_usage(args, format, argv[0]);
- argv0 = *argv++;
-
openings = NULL;
- battle = "moonfish-battle";
- time = NULL;
-
- moonfish_options(argv0, &openings, &battle, &time, &argv);
-
- if (argv[0] != NULL)
+ battle = args[1].value;
+ time = args[2].value;
+ if (args[0].value != NULL)
{- if (!strcmp(argv[0], "--"))
- argv++;
- else if (**argv == '-')
- moonfish_usage0(argv0);
+ openings = fopen(args[0].value, "r");
+ if (openings == NULL)
+ {+ perror(argv[0]);
+ return 1;
+ }
}
- printf("# makefile generated by '%s'\n\n", argv0);+ printf("# makefile generated by '%s'\n\n", argv[0]); printf(".PHONY: all\n\n"); printf("n = basename '$@' .pgn | cut -d- -f\n");@@ -142,26 +86,31 @@
for (;;)
{- if (argv[bot_count] == NULL) break;
+ if (commands[bot_count] == NULL) break;
- brackets = moonfish_brackets(argv[bot_count]);
+ brackets = moonfish_brackets(commands[bot_count]);
printf("bot%d = ", bot_count + 1);- for (i = 0 ; i < brackets ; i++) printf("[");+ for (i = 0 ; i < brackets ; i++) printf("["); printf(" "); if (time != NULL) printf("--time=%s ", time);- printf("%s", argv[bot_count]);+ /* 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("]");+ for (i = 0 ; i < brackets ; i++) printf("]"); printf("\n");bot_count++;
}
- if (bot_count == 0) fprintf(stderr, "warning: no bots established for tournament\n");
+ if (bot_count < 2) fprintf(stderr, "warning: too few bots established for tournament\n");
printf("\n");@@ -191,7 +140,7 @@
if (fgets(line, sizeof line, openings) == NULL)
{if (errno == 0) break;
- perror(argv0);
+ perror(argv[0]);
return 1;
}
--
⑨