shithub: moonfish

Download patch

ref: f6e2043016e1ee471c725e891dfff8284c2fc14d
parent: 77880a7a3ce8c15d4ec62b97d53112ec41d0e7c9
author: zamfofex <zamfofex@twdb.moe>
date: Thu Nov 21 03:39:19 EST 2024

bring back certain scripts

--- a/.build.yml
+++ b/.build.yml
@@ -20,12 +20,13 @@
   - strip: |
       cd moonfish
       strip --strip-all moonfish lichess analyse chat
+      scripts/minify.sh
   
   - deploy: |
       set +x
       
       if test "x$GIT_REF" = x || ! test -f neocities-token.txt
-      then exit 0
+      then exit
       fi
       
       if test "$GIT_REF" = refs/heads/main
@@ -36,6 +37,7 @@
       cd moonfish
       curl -fsSL --oauth2-bearer "$(cat ~/neocities-token.txt)" \
         -F "$root"/moonfish=@moonfish \
+        -F "$root"/moonfish.sh=@moonfish.sh \
         -F "$root"/lichess=@lichess \
         -F "$root"/analyse=@analyse \
         -F "$root"/chat=@chat \
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
 !/chess.c
 !/search.c
 !/main.c
+!/mini.c
 !/tools
 !/tools/tools.h
 !/tools/utils.c
@@ -22,3 +23,8 @@
 !/tools/https.c
 !/tools/perft.c
 !/tools/pgn.c
+!/scripts
+!/scripts/minify.sh
+!/scripts/rename.sh
+!/scripts/compare.sh
+!/scripts/offload.sh
--- a/chess.c
+++ b/chess.c
@@ -1,8 +1,6 @@
 /* moonfish is licensed under the AGPL (v3 or later) */
 /* copyright 2023, 2024 zamfofex */
 
-#include <string.h>
-
 #include "moonfish.h"
 
 static void moonfish_force_promotion(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to, unsigned char promotion)
@@ -46,6 +44,8 @@
 	}
 }
 
+int moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from);
+
 int moonfish_validate(struct moonfish_chess *chess)
 {
 	int x, y;
@@ -461,6 +461,33 @@
 	return moonfish_finished(chess);
 }
 
+int moonfish_equal(struct moonfish_chess *a, struct moonfish_chess *b)
+{
+	int x, y, i;
+	
+	if (a->white != b->white) return 0;
+	if (a->passing != b->passing) return 0;
+	if (a->oo[0] != b->oo[0]) return 0;
+	if (a->oo[1] != b->oo[1]) return 0;
+	if (a->ooo[0] != b->ooo[0]) return 0;
+	if (a->ooo[1] != b->ooo[1]) return 0;
+	
+	for (y = 0 ; y < 8 ; y++) {
+		for (x = 0 ; x < 8 ; x++) {
+			i = (x + 1) + (y + 2) * 10;
+			if (a->board[i] != b->board[i]) {
+				return 0;
+			}
+		}
+	}
+	
+	return 1;
+}
+
+#ifndef moonfish_mini
+
+#include <string.h>
+
 static int moonfish_match_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char type, unsigned char promotion, int x0, int y0, int x1, int y1, int check, int captured)
 {
 	int found;
@@ -830,25 +857,4 @@
 	*name = 0;
 }
 
-int moonfish_equal(struct moonfish_chess *a, struct moonfish_chess *b)
-{
-	int x, y, i;
-	
-	if (a->white != b->white) return 0;
-	if (a->passing != b->passing) return 0;
-	if (a->oo[0] != b->oo[0]) return 0;
-	if (a->oo[1] != b->oo[1]) return 0;
-	if (a->ooo[0] != b->ooo[0]) return 0;
-	if (a->ooo[1] != b->ooo[1]) return 0;
-	
-	for (y = 0 ; y < 8 ; y++) {
-		for (x = 0 ; x < 8 ; x++) {
-			i = (x + 1) + (y + 2) * 10;
-			if (a->board[i] != b->board[i]) {
-				return 0;
-			}
-		}
-	}
-	
-	return 1;
-}
+#endif
--- /dev/null
+++ b/mini.c
@@ -1,0 +1,78 @@
+/* moonfish is licensed under the AGPL (v3 or later) */
+/* copyright 2023, 2024 zamfofex */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "moonfish.h"
+
+int main(void)
+{
+	static char line[2048];
+	static struct moonfish_chess chess, chess0;
+	static struct moonfish_move move;
+	static struct moonfish_options options;
+	static struct moonfish_result result;
+	
+	struct moonfish_node *node;
+	char name[6];
+	int wtime, btime;
+	char *arg;
+	
+	node = moonfish_new();
+	moonfish_root(node, &chess);
+	
+	for (;;) {
+		
+		fflush(stdout);
+		
+		fgets(line, sizeof line, stdin);
+		arg = strchr(line, '\n');
+		if (arg) *arg = 0;
+		
+		if (!strncmp(line, "go ", 3)) {
+			
+			sscanf(line, "go wtime %d btime %d", &wtime, &btime);
+			
+			options.max_time = -1;
+			options.our_time = chess.white ? wtime : btime;
+			moonfish_best_move(node, &result, &options);
+			moonfish_to_uci(&chess, &result.move, name);
+			printf("bestmove %s\n", name);
+		}
+		
+		if (!strncmp(line, "position ", 9)) {
+			
+			moonfish_chess(&chess);
+			
+			arg = strstr(line, " moves ");
+			if (!arg) continue;
+			
+			arg = strtok(arg, " ");
+			
+			for (;;) {
+				
+				arg = strtok(NULL, "\r\n\t ");
+				if (arg == NULL) break;
+				if (moonfish_from_uci(&chess, &move, arg)) {
+					fprintf(stderr, "malformed move '%s'\n", arg);
+					exit(1);
+				}
+				
+				moonfish_root(node, &chess0);
+				if (moonfish_equal(&chess0, &chess)) moonfish_reroot(node, &move.chess);
+				
+				chess = move.chess;
+			}
+			
+			moonfish_root(node, &chess0);
+			if (!moonfish_equal(&chess0, &chess)) moonfish_reroot(node, &chess);
+		}
+		
+		if (!strcmp(line, "uci")) printf("uciok\n");
+		if (!strcmp(line, "isready")) printf("readyok\n");
+		if (!strcmp(line, "quit")) return 0;
+	}
+}
+
--- /dev/null
+++ b/scripts/compare.sh
@@ -1,0 +1,66 @@
+#!/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 scripts/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 reset --hard "${1:-main}"
+
+rev2="$(git rev-parse --short HEAD)"
+"$make" moonfish
+mv -f moonfish compare/moonfish-"$rev2"
+
+[[ "$rev1" = "$rev2" ]] || git reset --hard "$rev1"
+[[ "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=fastchess
+	cli_args='-pgnout games.pgn'
+	format=format=epd
+fi
+
+if ! which "$cli" &> /dev/null
+then
+	cli=cutechess-cli
+	protocol=proto=uci
+fi
+
+"$cli" \
+	-engine {name=,cmd=./}moonfish-"$rev1$dirty" \
+	-engine {name=,cmd=./}moonfish-"$rev2" \
+	-each $protocol tc=inf/10+0.1 \
+	-openings $format file=openings.fen order=random \
+	-games 2 -rounds 1024 \
+	-sprt elo0=0 elo1=12 alpha=0.05 beta=0.05 \
+	-concurrency "$(getconf _NPROCESSORS_ONLN)" \
+	$cli_args
--- /dev/null
+++ b/scripts/minify.sh
@@ -1,0 +1,61 @@
+#!/bin/sh -e
+
+# moonfish is licensed under the AGPL (v3 or later)
+# copyright 2023, 2024 zamfofex
+
+cc="${HOST_CC:-gcc}"
+
+header='#!/bin/sh
+t=`mktemp`
+tail -n+5 "$0"|unxz -Fraw|'""${CC:-cc}""' -ansi -O3 -o $t -xc - -lm
+(sleep 3;rm $t)&exec $t'
+
+# for each C source file
+cat moonfish.h chess.c search.c mini.c |
+
+# remove the '#' from system '#include'
+sed -E 's/^#(include <)/\1/g' |
+
+# preprocess the file, add '#' back to 'include'
+# note: this materialises the whole file
+"$cc" -E -P -Dinclude='#include' -Dmoonfish_mini -D'exit(...)=' -D'perror(...)=' -D'fprintf(...)=' - |
+
+# replace tabs with spaces
+tr '\t' ' ' |
+
+# remove leading white space from '#include' lines
+sed -E 's/^ +#/#/g' |
+
+# tokenise the file (roughly)
+grep -Eoh "'[^']*'"'|"[^"]*"|#.*|[a-zA-Z0-9_]+|[^a-zA-Z0-9_"'"'"' ]+' |
+
+# remove spaces in '#include' lines
+sed '/^#/s/ //g' |
+
+# put '#include' lines at the start
+# (note: this materialises the file)
+awk '/^#/ { print $0 ; next } { x = x $0 "\n" } END { print x }' |
+
+# rename identifiers to be shorter
+scripts/rename.sh |
+
+# put spaces between identifiers
+awk '/^[^a-zA-Z0-9]/ { n = 0 ; print $0 ; next } { if (++n > 1) print " " ; } 1' |
+
+# remove line breaks (except in '#include' lines)
+awk '/^#/ { print $0 ; next } { printf "%s", $0 }' |
+
+# remove duplicate '#include' lines
+awk '!x[$0]++' |
+
+# store it into a file
+tee moonfish.c |
+
+# compress it
+xz -e9qFraw |
+
+# finally, create a shell script for it
+{ echo "$header" ; tee ; } > moonfish.sh
+
+# and make it executable
+chmod +x moonfish.sh
--- /dev/null
+++ b/scripts/offload.sh
@@ -1,0 +1,22 @@
+#!/usr/bin/env bash
+
+# moonfish is licensed under the AGPL (v3 or later)
+# copyright 2024 zamfofex
+
+set -ex
+set -o shwordsplit || :
+
+undo=no
+git add .
+git commit -m xxx && undo=yes
+git push --force --all tests
+
+commit="$(git rev-parse HEAD)"
+
+[[ "$undo" = yes ]] && git reset HEAD~
+
+url="$(git remote get-url tests)"
+ssh="${url%%:*}"
+dir="${url#*:}"
+
+ssh "$ssh" -- "cd '$dir/..' && git reset --hard '$commit' && scripts/compare.sh '${1:-main}'"
--- /dev/null
+++ b/scripts/rename.sh
@@ -1,0 +1,52 @@
+#!/usr/bin/env bash
+
+# moonfish is licensed under the AGPL (v3 or later)
+# copyright 2023, 2024 zamfofex
+
+set -e
+
+alphabet=({a..z} {a..z}{a..z} {a..z}{a..z}{a..z})
+alphabet2=("${alphabet[@]}")
+declare -A names
+
+functions="main fopen fread printf fprintf sscanf fgets fflush stdin stdout stderr strcmp strncmp strcpy strtok strstr strchr malloc realloc free exit errno clock_gettime timespec tv_sec tv_nsec pthread_create pthread_join pthread_t typedef memmove fabs sqrt log pow qsort"
+keywords="do while for if else switch case break continue return extern static struct enum unsigned signed long short int char double float void const sizeof $functions"
+
+while read -r name
+do
+	if ! [[ "$name" =~ ^[a-z] ]]
+	then
+		echo "$name"
+		continue
+	fi
+	
+	if [[ " $keywords " =~ " $name " ]]
+	then
+		echo "$name"
+		continue
+	fi
+	
+	short="${names["$name"]}"
+	if [[ "$short" = "" ]]
+	then
+		if [[ "$name" =~ ^moonfish ]]
+		then
+			short="F${alphabet[0]}"
+			alphabet=("${alphabet[@]:1}")
+		else
+			while :
+			do
+				short="${alphabet2[0]}"
+				alphabet2=("${alphabet2[@]:1}")
+				if ! [[ " $keywords " =~ " $short " ]]
+				then break
+				fi
+			done
+		fi
+		
+		echo "renaming '$name' to '$short'" >&2
+		names["$name"]="$short"
+	fi
+	
+	echo "$short"
+done
--