shithub: moonfish

Download patch

ref: 041ed9c6c6e31075450eec8955fe820e8a115500
parent: d468ffc53681ee75056f8a99657c3cf11491db75
author: zamfofex <zamfofex@twdb.moe>
date: Fri May 10 08:42:09 EDT 2024

improve minification

--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
 !/chess.c
 !/search.c
 !/main.c
+!/mini.c
 !/book.txt
 !/tools
 !/tools/tools.h
--- a/chess.c
+++ b/chess.c
@@ -111,62 +111,26 @@
 	moonfish_force_promotion(chess, moves, from, to, chess->board[from]);
 }
 
-static void moonfish_jump(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, signed char delta)
+static void moonfish_deltas(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, int *deltas, int n)
 {
-	if (chess->board[from + delta] == moonfish_outside) return;
-	if (chess->board[from] / 16 == chess->board[from + delta] / 16) return;
-	moonfish_force_move(chess, moves, from, from + delta);
-}
-
-static void moonfish_slide(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, signed char delta)
-{
+	int i;
 	unsigned char to;
 	
-	to = from;
-	for (;;)
+	while (*deltas)
 	{
-		to += delta;
-		if (chess->board[to] == moonfish_outside) break;
-		if (chess->board[to] / 16 == chess->board[from] / 16) break;
-		moonfish_force_move(chess, moves, from, to);
-		if (chess->board[to] != moonfish_empty) break;
+		to = from;
+		for (i = 0 ; i < n ; i++)
+		{
+			to += *deltas;
+			if (chess->board[to] == moonfish_outside) break;
+			if (chess->board[to] / 16 == chess->board[from] / 16) break;
+			moonfish_force_move(chess, moves, from, to);
+			if (chess->board[to] != moonfish_empty) break;
+		}
+		deltas++;
 	}
 }
 
-static void moonfish_move_knight(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
-{
-	moonfish_jump(chess, moves, from, 21);
-	moonfish_jump(chess, moves, from, 19);
-	moonfish_jump(chess, moves, from, -19);
-	moonfish_jump(chess, moves, from, -21);
-	moonfish_jump(chess, moves, from, 12);
-	moonfish_jump(chess, moves, from, 8);
-	moonfish_jump(chess, moves, from, -8);
-	moonfish_jump(chess, moves, from, -12);
-}
-
-static void moonfish_move_bishop(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
-{
-	moonfish_slide(chess, moves, from, 11);
-	moonfish_slide(chess, moves, from, 9);
-	moonfish_slide(chess, moves, from, -9);
-	moonfish_slide(chess, moves, from, -11);
-}
-
-static void moonfish_move_rook(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
-{
-	moonfish_slide(chess, moves, from, 10);
-	moonfish_slide(chess, moves, from, -10);
-	moonfish_slide(chess, moves, from, 1);
-	moonfish_slide(chess, moves, from, -1);
-}
-
-static void moonfish_move_queen(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
-{
-	moonfish_move_rook(chess, moves, from);
-	moonfish_move_bishop(chess, moves, from);
-}
-
 static char moonfish_attacked(struct moonfish_chess *chess, unsigned char from, unsigned char to)
 {
 	int check;
@@ -223,15 +187,6 @@
 
 static void moonfish_move_king(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
 {
-	moonfish_jump(chess, moves, from, 11);
-	moonfish_jump(chess, moves, from, 9);
-	moonfish_jump(chess, moves, from, -9);
-	moonfish_jump(chess, moves, from, -11);
-	moonfish_jump(chess, moves, from, 10);
-	moonfish_jump(chess, moves, from, -10);
-	moonfish_jump(chess, moves, from, 1);
-	moonfish_jump(chess, moves, from, -1);
-	
 	if (chess->white)
 	{
 		if (chess->white_oo) moonfish_castle_high(chess, moves, from);
@@ -255,10 +210,10 @@
 		return;
 	}
 	
-	moonfish_force_promotion(chess, moves, from, to, moonfish_queen | color);
-	moonfish_force_promotion(chess, moves, from, to, moonfish_rook | color);
-	moonfish_force_promotion(chess, moves, from, to, moonfish_bishop | color);
-	moonfish_force_promotion(chess, moves, from, to, moonfish_knight | color);
+	moonfish_force_promotion(chess, moves, from, to, color | moonfish_queen);
+	moonfish_force_promotion(chess, moves, from, to, color | moonfish_rook);
+	moonfish_force_promotion(chess, moves, from, to, color | moonfish_bishop);
+	moonfish_force_promotion(chess, moves, from, to, color | moonfish_knight);
 }
 
 static void moonfish_pawn_capture(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to)
@@ -305,6 +260,17 @@
 
 int moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from)
 {
+	static int steps[] = {0, 1, 8, 8, 8, 1};
+	static int deltas[][9] =
+	{
+		{0},
+		{21, 19, -19, -21, 12, 8, -8, -12, 0},
+		{11, 9, -9, -11, 0},
+		{10, -10, 1, -1, 0},
+		{10, -10, 1, -1, 11, 9, -9, -11, 0},
+		{10, -10, 1, -1, 11, 9, -9, -11, 0},
+	};
+	
 	struct moonfish_move *moves0;
 	unsigned char piece;
 	int i, count;
@@ -314,11 +280,9 @@
 	
 	if (chess->white ? piece / 16 == 1 : piece / 16 == 2)
 	{
+		moonfish_deltas(chess, &moves, from, deltas[piece % 16 - 1], steps[piece % 16 - 1]);
+		
 		if (piece % 16 == moonfish_pawn) moonfish_move_pawn(chess, &moves, from);
-		if (piece % 16 == moonfish_knight) moonfish_move_knight(chess, &moves, from);
-		if (piece % 16 == moonfish_bishop) moonfish_move_bishop(chess, &moves, from);
-		if (piece % 16 == moonfish_rook) moonfish_move_rook(chess, &moves, from);
-		if (piece % 16 == moonfish_queen) moonfish_move_queen(chess, &moves, from);
 		
 		if (piece % 16 == moonfish_king)
 		{
--- a/main.c
+++ b/main.c
@@ -16,15 +16,12 @@
 	char *arg;
 	struct moonfish_move move;
 	char name[6];
-	long int wtime, btime, *xtime;
-	int score;
+	long int our_time, their_time, *xtime;
+	long int score;
 	int depth;
 	struct moonfish_chess chess;
 	char *end;
-#ifndef moonfish_mini
-	long int long_depth;
 	long int time;
-#endif
 	
 	if (argc > 1)
 	{
@@ -54,12 +51,10 @@
 		
 		if (!strcmp(arg, "go"))
 		{
-			wtime = -1;
-			btime = -1;
+			our_time = -1;
+			their_time = -1;
 			depth = -1;
-#ifndef moonfish_mini
 			time = -1;
-#endif
 			
 			for (;;)
 			{
@@ -68,8 +63,16 @@
 				
 				if (!strcmp(arg, "wtime") || !strcmp(arg, "btime"))
 				{
-					if (!strcmp(arg, "wtime")) xtime = &wtime;
-					else xtime = &btime;
+					if (chess.white)
+					{
+						if (!strcmp(arg, "wtime")) xtime = &our_time;
+						else xtime = &their_time;
+					}
+					else
+					{
+						if (!strcmp(arg, "wtime")) xtime = &their_time;
+						else xtime = &our_time;
+					}
 					
 					arg = strtok(NULL, "\r\n\t ");
 					if (arg == NULL)
@@ -86,7 +89,6 @@
 						return 1;
 					}
 				}
-#ifndef moonfish_mini
 				else if (!strcmp(arg, "depth"))
 				{
 					arg = strtok(NULL, "\r\n\t ");
@@ -98,19 +100,17 @@
 					}
 					
 					errno = 0;
-					long_depth = strtol(arg, &end, 10);
+					depth = strtol(arg, &end, 10);
 					if (errno != 0)
 					{
 						perror(argv[0]);
 						return 1;
 					}
-					if (*end != 0 || long_depth < 0 || long_depth > 100)
+					if (*end != 0 || depth < 0 || depth > 100)
 					{
 						fprintf(stderr, "%s: malformed depth in 'go' command\n", argv[0]);
 						return 1;
 					}
-					
-					depth = long_depth;
 				}
 				else if (!strcmp(arg, "movetime"))
 				{
@@ -135,31 +135,26 @@
 						return 1;
 					}
 				}
-#endif
 			}
 			
-			if (wtime < 0) wtime = 0;
-			if (btime < 0) btime = 0;
+			if (our_time < 0) our_time = 0;
+			if (their_time < 0) their_time = 0;
 			
-#ifndef moonfish_mini
 			if (depth >= 0)
 				score = moonfish_best_move_depth(analysis, &move, depth);
 			else if (time >= 0)
 				score = moonfish_best_move_time(analysis, &move, time);
 			else
-#endif
-			if (chess.white)
-				score = moonfish_best_move_clock(analysis, &move, wtime, btime);
-			else
-				score = moonfish_best_move_clock(analysis, &move, btime, wtime);
+				score = moonfish_best_move_clock(analysis, &move, our_time, their_time);
 			
 			if (depth < 0) depth = 4;
-			
 			printf("info depth %d ", depth);
+			
 			if (score >= moonfish_omega || score <= -moonfish_omega)
 				printf("score mate %d\n", moonfish_countdown(score));
 			else
-				printf("score cp %d\n", score);
+				printf("score cp %ld\n", score);
+			
 			moonfish_to_uci(&chess, &move, name);
 			printf("bestmove %s\n", name);
 		}
@@ -180,7 +175,6 @@
 			{
 				moonfish_chess(&chess);
 			}
-#ifndef moonfish_mini
 			else if (!strcmp(arg, "fen"))
 			{
 				arg = strtok(NULL, "\r\n");
@@ -199,7 +193,6 @@
 					strtok("", "\r\n\t ");
 				}
 			}
-#endif
 			else
 			{
 				fprintf(stderr, "malformed 'position' command\n");
@@ -232,7 +225,6 @@
 		{
 			printf("readyok\n");
 		}
-#ifndef moonfish_mini
 		else if (!strcmp(arg, "debug") || !strcmp(arg, "setoption") || !strcmp(arg, "ucinewgame") || !strcmp(arg, "stop"))
 		{
 		}
@@ -240,14 +232,11 @@
 		{
 			fprintf(stderr, "%s: unknown command '%s'\n", argv[0], arg);
 		}
-#endif
 		
 		fflush(stdout);
 	}
 	
-#ifndef moonfish_mini
 	free(analysis);
-#endif
 	
 	return 0;
 }
--- /dev/null
+++ b/mini.c
@@ -1,0 +1,81 @@
+/* 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];
+	
+	struct moonfish_analysis *analysis;
+	struct moonfish_move move;
+	char name[6];
+	int our_time, their_time, time;
+	int score;
+	struct moonfish_chess chess;
+	char *arg;
+	
+	analysis = moonfish_analysis(NULL);
+	
+	for (;;)
+	{
+		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", &our_time, &their_time);
+			
+			if (!chess.white)
+			{
+				time = our_time;
+				our_time = their_time;
+				their_time = time;
+			}
+			
+			score = moonfish_best_move_clock(analysis, &move, our_time, their_time);
+			
+			printf("info depth 4 ");
+			
+			if (score >= moonfish_omega || score <= -moonfish_omega)
+				printf("score mate %d\n", moonfish_countdown(score));
+			else
+				printf("score cp %d\n", score);
+			
+			moonfish_to_uci(&chess, &move, name);
+			printf("bestmove %s\n", name);
+		}
+		else if (!strncmp(line, "position ", 9))
+		{
+			moonfish_chess(&chess);
+			
+			arg = strstr(line, " moves ");
+			if (!arg) continue;
+			
+			arg = strtok(arg, " ");
+			
+			while ((arg = strtok(NULL, "\r\n\t ")) != NULL)
+			{
+				moonfish_from_uci(&chess, &move, arg);
+				chess = move.chess;
+			}
+			
+			moonfish_new(analysis, &chess);
+		}
+		else if (!strcmp(line, "uci"))
+			printf("uciok\n");
+		else if (!strcmp(line, "isready"))
+			printf("readyok\n");
+		else if (!strcmp(line, "quit"))
+			break;
+		
+		fflush(stdout);
+	}
+	
+	return 0;
+}
--- a/minify.sh
+++ b/minify.sh
@@ -6,14 +6,17 @@
 set -e
 
 # for every C source file
-cat moonfish.h chess.c search.c main.c |
+cat moonfish.h chess.c search.c mini.c |
 
 # remove the '#' from system '#include'
 sed 's/^#\(include <\)/\1/g' |
 
-# preprocess the file, add '#' back to 'include', remove debug statements
+# remove top-level 'static'
+sed 's/^static\b//g' |
+
+# preprocess the file, add '#' back to 'include'
 # note: this materialises the whole file
-gcc -E -Dinclude='#include' -D'perror(...)=' -D'fprintf(...)=' -Dmoonfish_mini - |
+gcc -E -Dinclude='#include' -Dmoonfish_mini - |
 
 # remove lines starting with '# '
 sed '/^# /d' |
@@ -23,7 +26,7 @@
 
 # place all '#include' lines on top
 # note: this materialises the whole file
-( txt="$(tee)" && { grep '^#' <<< "$txt" ; } && { grep -v '^#' <<< "$txt" ; } ) |
+( txt="$(tee)" && { grep '^#' <<< "$txt" || : ; grep -v '^#' <<< "$txt" ; } ) |
 
 # put line breaks around string literals
 sed 's/\("\(\\.\|[^"]\)*"\)/\n\1\n/g' |
--- a/rename.sh
+++ b/rename.sh
@@ -9,8 +9,8 @@
 alphabet2=("${alphabet[@]}")
 declare -A names
 
-functions="main printf fprintf strtol fgets fflush stdin stdout stderr strcmp strcpy strtok strstr malloc realloc free exit errno clock_gettime timespec tv_sec tv_nsec pthread_create pthread_join pthread_t typedef moonfish_type_t"
-keywords="do while for if else break continue return static struct enum unsigned signed long short int char void sizeof $functions"
+functions="main 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 moonfish_type_t"
+keywords="do while for if else switch case break continue return static struct enum unsigned signed long short int char void sizeof $functions"
 
 while read -r name
 do
--- a/search.c
+++ b/search.c
@@ -78,11 +78,15 @@
 {
 	struct timespec ts;
 	
+#ifdef moonfish_mini
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+#else
 	if (clock_gettime(CLOCK_MONOTONIC, &ts))
 	{
 		perror(analysis->argv0);
 		exit(1);
 	}
+#endif
 	
 	return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
 }
@@ -95,11 +99,13 @@
 	struct moonfish_chess chess;
 	
 	analysis = malloc(sizeof *analysis);
+#ifndef moonfish_mini
 	if (analysis == NULL)
 	{
 		perror(argv0);
 		exit(1);
 	}
+#endif
 	
 	analysis->argv0 = argv0;
 	
@@ -234,11 +240,13 @@
 			analysis->info[j].move = moves[i];
 			
 			result = pthread_create(&analysis->info[j].thread, NULL, &moonfish_start_search, analysis->info + j);
+#ifndef moonfish_mini
 			if (result)
 			{
 				fprintf(stderr, "%s: %s\n", analysis->argv0, strerror(result));
 				exit(1);
 			}
+#endif
 			
 			j++;
 		}
@@ -249,11 +257,13 @@
 	for (i = 0 ; i < j ; i++)
 	{
 		result = pthread_join(analysis->info[i].thread, NULL);
+#ifndef moonfish_mini
 		if (result)
 		{
 			fprintf(stderr, "%s: %s\n", analysis->argv0, strerror(result));
 			exit(1);
 		}
+#endif
 		
 		if (analysis->info[i].score > analysis->score)
 		{
--