shithub: moonfish

Download patch

ref: 61ccd998497e3561bbb657786603833034a26b3c
parent: 7cef241c0a17871d4f4eb529e27037660a6ba94f
author: zamfofex <zamfofex@twdb.moe>
date: Tue May 7 12:29:43 EDT 2024

simplify move generation

--- a/chess.c
+++ b/chess.c
@@ -60,47 +60,62 @@
 	-14, -21, 16, -2,
 };
 
-void moonfish_force_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to)
+static int moonfish_table(int from, unsigned char piece)
 {
-	move->from = from;
-	move->to = to;
-	move->piece = chess->board[from];
-	move->promotion = chess->board[from];
-	move->captured = chess->board[to];
-	move->castle = chess->castle;
-	move->score = chess->score;
-	move->passing = chess->passing;
+	int x, y;
+	unsigned char type, color;
+	int score;
+	
+	if (piece == moonfish_empty) return 0;
+	
+	x = from % 10 - 1;
+	y = from / 10 - 2;
+	
+	type = (piece % 16) - 1;
+	color = (piece / 16) - 1;
+	
+	if (color == 0) y = 7 - y;
+	
+	if (x < 4) x = 3 - x;
+	else x %= 4;
+	
+	score = moonfish_piece_square_scores[x + y * 4 + type * 32];
+	if (color != 0) score *= -1;
+	
+	return score;
 }
 
-static void moonfish_pawn_moves(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to)
+static void moonfish_force_promotion(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to, unsigned char promotion)
 {
-	unsigned char color;
+	(*moves)->from = from;
+	(*moves)->to = to;
+	(*moves)->chess = *chess;
+	(*moves)->chess.board[to] = promotion;
+	(*moves)->chess.board[from] = moonfish_empty;
+	(*moves)->chess.score -= moonfish_table(from, chess->board[from]);
+	(*moves)->chess.score += moonfish_table(to, promotion);
+	(*moves)->chess.score -= moonfish_table(to, chess->board[to]);
+	(*moves)->chess.passing = 0;
+	(*moves)->chess.white ^= 1;
 	
-	moonfish_force_move(chess, (*moves)++, from, to);
-	if (chess->board[from] % 16 != moonfish_pawn) return;
+	if (from == 21 || to == 21) (*moves)->chess.white_ooo = 0;
+	if (from == 28 || to == 28) (*moves)->chess.white_oo = 0;
+	if (from == 91 || to == 91) (*moves)->chess.black_ooo = 0;
+	if (from == 98 || to == 98) (*moves)->chess.black_oo = 0;
 	
-	color = chess->board[from] & 0xF0;
-	if (color == 0x10 && from < 80) return;
-	if (color == 0x20 && from > 40) return;
-	
-	(*moves)--;
-	(*moves)[1] = **moves;
-	(*moves)[2] = **moves;
-	(*moves)[3] = **moves;
-	
-	(*moves)++->promotion = moonfish_queen | color;
-	(*moves)++->promotion = moonfish_rook | color;
-	(*moves)++->promotion = moonfish_bishop | color;
-	(*moves)++->promotion = moonfish_knight | color;
+	(*moves)++;
 }
 
+static void moonfish_force_move(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to)
+{
+	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)
 {
-	unsigned char to;
-	to = from + delta;
-	if (chess->board[to] == moonfish_outside) return;
-	if (chess->board[to] / 16 == chess->board[from] / 16) return;
-	moonfish_force_move(chess, (*moves)++, from, to);
+	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)
@@ -113,7 +128,7 @@
 		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);
+		moonfish_force_move(chess, moves, from, to);
 		if (chess->board[to] != moonfish_empty) break;
 	}
 }
@@ -172,7 +187,7 @@
 {
 	unsigned char to;
 	
-	to = chess->white ? 22 : 92;
+	to = from - 3;
 	while (to != from)
 		if (chess->board[to++] != moonfish_empty)
 			return;
@@ -181,7 +196,10 @@
 	if (moonfish_attacked(chess, from, from - 1)) return;
 	if (moonfish_attacked(chess, from, from - 2)) return;
 	
-	moonfish_jump(chess, moves, from, -2);
+	moonfish_force_move(chess, moves, from - 4, from - 1);
+	(*moves)--;
+	(*moves)->chess.white = chess->white;
+	moonfish_force_move(&(*moves)->chess, moves, from, from - 2);
 }
 
 static void moonfish_castle_high(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
@@ -188,7 +206,7 @@
 {
 	unsigned char to;
 	
-	to = chess->white ? 27 : 97;
+	to = from + 2;
 	while (to != from)
 		if (chess->board[to--] != moonfish_empty)
 			return;
@@ -197,7 +215,10 @@
 	if (moonfish_attacked(chess, from, from + 1)) return;
 	if (moonfish_attacked(chess, from, from + 2)) return;
 	
-	moonfish_jump(chess, moves, from, 2);
+	moonfish_force_move(chess, moves, from + 3, from + 1);
+	(*moves)--;
+	(*moves)->chess.white = chess->white;
+	moonfish_force_move(&(*moves)->chess, moves, from, from + 2);
 }
 
 static void moonfish_move_king(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
@@ -213,21 +234,44 @@
 	
 	if (chess->white)
 	{
-		if (chess->castle.white_oo) moonfish_castle_high(chess, moves, from);
-		if (chess->castle.white_ooo) moonfish_castle_low(chess, moves, from);
+		if (chess->white_oo) moonfish_castle_high(chess, moves, from);
+		if (chess->white_ooo) moonfish_castle_low(chess, moves, from);
 	}
 	else
 	{
-		if (chess->castle.black_oo) moonfish_castle_high(chess, moves, from);
-		if (chess->castle.black_ooo) moonfish_castle_low(chess, moves, from);
+		if (chess->black_oo) moonfish_castle_high(chess, moves, from);
+		if (chess->black_ooo) moonfish_castle_low(chess, moves, from);
 	}
 }
 
+static void moonfish_pawn_moves(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to)
+{
+	unsigned char color;
+	
+	color = chess->board[from] & 0xF0;
+	if ((color == 0x10 && from < 80) || (color == 0x20 && from > 40))
+	{
+		moonfish_force_move(chess, moves, from, to);
+		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);
+}
+
 static void moonfish_pawn_capture(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char to)
 {
+	int dy;
+	
 	if (to == chess->passing)
 	{
-		moonfish_force_move(chess, (*moves)++, from, to);
+		dy = chess->white ? 10 : -10;
+		
+		moonfish_force_move(chess, moves, from, to);
+		(*moves)[-1].chess.score -= moonfish_table(to - dy, chess->board[to - dy]);
+		(*moves)[-1].chess.board[to - dy] = moonfish_empty;
 		return;
 	}
 	
@@ -246,10 +290,13 @@
 	if (chess->board[from + dy] == moonfish_empty)
 	{
 		moonfish_pawn_moves(chess, moves, from, from + dy);
-				
+		
 		if (chess->white ? from < 40 : from > 80)
 		if (chess->board[from + dy * 2] == moonfish_empty)
-			moonfish_pawn_moves(chess, moves, from, from + dy * 2);
+		{
+			moonfish_force_move(chess, moves, from, from + dy * 2);
+			(*moves)[-1].chess.passing = from + dy;
+		}
 	}
 	
 	moonfish_pawn_capture(chess, moves, from, from + dy + 1);
@@ -256,10 +303,13 @@
 	moonfish_pawn_capture(chess, moves, from, from + dy - 1);
 }
 
-void moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from)
+int moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from)
 {
+	struct moonfish_move *moves0;
 	unsigned char piece;
+	int i, count;
 	
+	moves0 = moves;
 	piece = chess->board[from];
 	
 	if (chess->white ? piece / 16 == 1 : piece / 16 == 2)
@@ -269,161 +319,30 @@
 		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) moonfish_move_king(chess, &moves, from);
-	}
-	
-	moves->piece = moonfish_outside;
-}
-
-static int moonfish_table(int from, unsigned char piece)
-{
-	int x, y;
-	unsigned char type, color;
-	int score;
-	
-	if (piece == moonfish_empty) return 0;
-	
-	x = from % 10 - 1;
-	y = from / 10 - 2;
-	
-	type = (piece % 16) - 1;
-	color = (piece / 16) - 1;
-	
-	if (color == 0) y = 7 - y;
-	
-	if (x < 4) x = 3 - x;
-	else x %= 4;
-	
-	score = moonfish_piece_square_scores[x + y * 4 + type * 32];
-	if (color != 0) score *= -1;
-	
-	return score;
-}
-
-void moonfish_play(struct moonfish_chess *chess, struct moonfish_move *move)
-{
-	int x0, x1;
-	int dy;
-	unsigned char piece;
-	
-	chess->score -= moonfish_table(move->from, move->piece);
-	chess->score += moonfish_table(move->to, move->promotion);
-	chess->score -= moonfish_table(move->to, move->captured);
-	
-	chess->board[move->from] = moonfish_empty;
-	chess->board[move->to] = move->promotion;
-	
-	chess->passing = 0;
-	
-	if (move->piece % 16 == moonfish_pawn)
-	{
-		if ((move->to - move->from) / 10 == 2) chess->passing = move->from + 10;
-		if ((move->from - move->to) / 10 == 2) chess->passing = move->from - 10;
 		
-		if ((move->to - move->from) % 10)
-		if (move->captured == moonfish_empty)
+		if (piece % 16 == moonfish_king)
 		{
-			if (chess->white) dy = 10, piece = moonfish_black_pawn;
-			else dy = -10, piece = moonfish_white_pawn;
+			moonfish_move_king(chess, &moves, from);
 			
-			chess->score -= moonfish_table(move->to - dy, piece);
-			chess->board[move->to - dy] = moonfish_empty;
-		}
-	}
-	
-	if (move->piece % 16 == moonfish_king)
-	{
-		x0 = 0;
-		if (move->from == 25 && move->to == 27) x0 = 28, x1 = 26;
-		if (move->from == 25 && move->to == 23) x0 = 21, x1 = 24;
-		if (move->from == 95 && move->to == 97) x0 = 98, x1 = 96;
-		if (move->from == 95 && move->to == 93) x0 = 91, x1 = 94;
-		if (x0)
-		{
-			piece = chess->white ? moonfish_white_rook : moonfish_black_rook;
-			chess->score -= moonfish_table(x0, piece);
-			chess->score += moonfish_table(x1, piece);
-			chess->board[x0] = moonfish_empty;
-			chess->board[x1] = piece;
-		}
-		
-		if (chess->white)
-		{
-			chess->castle.white_oo = 0;
-			chess->castle.white_ooo = 0;
-		}
-		else
-		{
-			chess->castle.black_oo = 0;
-			chess->castle.black_ooo = 0;
-		}
-	}
-	
-	if (move->piece == moonfish_white_rook)
-	{
-		if (move->from % 10 == 1) chess->castle.white_ooo = 0;
-		if (move->from % 10 == 8) chess->castle.white_oo = 0;
-	}
-	if (move->piece == moonfish_black_rook)
-	{
-		if (move->from % 10 == 1) chess->castle.black_ooo = 0;
-		if (move->from % 10 == 8) chess->castle.black_oo = 0;
-	}
-	
-	if (move->captured == moonfish_white_rook)
-	{
-		if (move->to % 10 == 1) chess->castle.white_ooo = 0;
-		if (move->to % 10 == 8) chess->castle.white_oo = 0;
-	}
-	if (move->captured == moonfish_black_rook)
-	{
-		if (move->to % 10 == 1) chess->castle.black_ooo = 0;
-		if (move->to % 10 == 8) chess->castle.black_oo = 0;
-	}
-	
-	chess->white ^= 1;
-}
-
-void moonfish_unplay(struct moonfish_chess *chess, struct moonfish_move *move)
-{
-	int x0, x1;
-	int dy;
-	unsigned char piece;
-	
-	chess->white ^= 1;
-	
-	chess->board[move->from] = move->piece;
-	chess->board[move->to] = move->captured;
-	chess->castle = move->castle;
-	chess->score = move->score;
-	chess->passing = move->passing;
-	
-	if (move->piece % 16 == moonfish_pawn)
-	{
-		if ((move->to - move->from) % 10)
-		if (move->captured == moonfish_empty)
-		{
-			if (chess->white) dy = 10, piece = moonfish_black_pawn;
-			else dy = -10, piece = moonfish_white_pawn;
+			count = moves - moves0;
 			
-			chess->score += moonfish_table(move->to - dy, piece);
-			chess->board[move->to - dy] = piece;
+			for (i = 0 ; i < count ; i++)
+			{
+				if (chess->white)
+				{
+					moves0[i].chess.white_oo = 0;
+					moves0[i].chess.white_ooo = 0;
+				}
+				else
+				{
+					moves0[i].chess.black_oo = 0;
+					moves0[i].chess.black_ooo = 0;
+				}
+			}
 		}
 	}
 	
-	if (move->piece % 16 == moonfish_king)
-	{
-		x0 = 0;
-		if (move->from == 25 && move->to == 27) x0 = 28, x1 = 26;
-		if (move->from == 25 && move->to == 23) x0 = 21, x1 = 24;
-		if (move->from == 95 && move->to == 97) x0 = 98, x1 = 96;
-		if (move->from == 95 && move->to == 93) x0 = 91, x1 = 94;
-		if (x0)
-		{
-			chess->board[x1] = moonfish_empty;
-			chess->board[x0] = chess->white ? moonfish_white_rook : moonfish_black_rook;
-		}
-	}
+	return moves - moves0;
 }
 
 void moonfish_chess(struct moonfish_chess *chess)
@@ -432,10 +351,10 @@
 	int x, y;
 	
 	chess->white = 1;
-	chess->castle.white_oo = 1;
-	chess->castle.white_ooo = 1;
-	chess->castle.black_oo = 1;
-	chess->castle.black_ooo = 1;
+	chess->white_oo = 1;
+	chess->white_ooo = 1;
+	chess->black_oo = 1;
+	chess->black_ooo = 1;
 	chess->score = 0;
 	chess->passing = 0;
 	
@@ -455,16 +374,11 @@
 	}
 }
 
-static void moonfish_from_xy(struct moonfish_chess *chess, struct moonfish_move *move, int x0, int y0, int x1, int y1)
-{
-	moonfish_force_move(chess, move, (x0 + 1) + (y0 + 2) * 10, (x1 + 1) + (y1 + 2) * 10);
-}
-
 void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name)
 {
 	int x0, y0;
 	int x1, y1;
-	unsigned char color;
+	unsigned char piece;
 	
 	x0 = name[0] - 'a';
 	y0 = name[1] - '1';
@@ -471,24 +385,25 @@
 	x1 = name[2] - 'a';
 	y1 = name[3] - '1';
 	
-	moonfish_from_xy(chess, move, x0, y0, x1, y1);
-	if (move->piece % 16 == moonfish_king && x0 == 4)
+	piece = chess->board[(x0 + 1) + (y0 + 2) * 10];
+	if (piece % 16 == moonfish_king && x0 == 4)
 	{
 		if (x1 == 0) x1 = 2;
 		if (x1 == 7) x1 = 6;
-		moonfish_from_xy(chess, move, x0, y0, x1, y1);
 	}
 	
-	color = chess->white ? 0x10 : 0x20;
-	if (name[4] == 'q') move->promotion = color | moonfish_queen;
-	if (name[4] == 'r') move->promotion = color | moonfish_rook;
-	if (name[4] == 'b') move->promotion = color | moonfish_bishop;
-	if (name[4] == 'n') move->promotion = color | moonfish_knight;
+	if (name[4] == 'q') piece = moonfish_queen;
+	if (name[4] == 'r') piece = moonfish_rook;
+	if (name[4] == 'b') piece = moonfish_bishop;
+	if (name[4] == 'n') piece = moonfish_knight;
+	
+	moonfish_force_promotion(chess, &move, (x0 + 1) + (y0 + 2) * 10, (x1 + 1) + (y1 + 2) * 10, piece);
 }
 
-void moonfish_to_uci(struct moonfish_move *move, char *name)
+void moonfish_to_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name)
 {
 	int x, y;
+	unsigned char piece;
 	
 	x = move->from % 10 - 1;
 	y = move->from / 10 - 2;
@@ -502,18 +417,18 @@
 	name[2] = x + 'a';
 	name[3] = y + '1';
 	
-	if (move->promotion != move->piece)
+	name[4] = 0;
+	
+	piece = move->chess.board[move->to];
+	
+	if (piece != chess->board[move->from])
 	{
-		if (move->promotion % 16 == moonfish_queen) name[4] = 'q';
-		if (move->promotion % 16 == moonfish_rook) name[4] = 'r';
-		if (move->promotion % 16 == moonfish_bishop) name[4] = 'b';
-		if (move->promotion % 16 == moonfish_knight) name[4] = 'n';
+		if (piece % 16 == moonfish_queen) name[4] = 'q';
+		if (piece % 16 == moonfish_rook) name[4] = 'r';
+		if (piece % 16 == moonfish_bishop) name[4] = 'b';
+		if (piece % 16 == moonfish_knight) name[4] = 'n';
 		name[5] = 0;
 	}
-	else
-	{
-		name[4] = 0;
-	}
 }
 
 int moonfish_validate(struct moonfish_chess *chess)
@@ -520,14 +435,14 @@
 {
 	int x, y;
 	struct moonfish_move moves[32];
-	struct moonfish_move *move;
+	int i, count;
 	
 	for (y = 0 ; y < 8 ; y++)
 	for (x = 0 ; x < 8 ; x++)
 	{
-		moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
-		for (move = moves ; move->piece != moonfish_outside ; move++)
-			if (move->captured % 16 == moonfish_king)
+		count = moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+		for (i = 0 ; i < count ; i++)
+			if (chess->board[moves[i].to] % 16 == moonfish_king)
 				return 0;
 	}
 	
@@ -537,23 +452,30 @@
 int moonfish_check(struct moonfish_chess *chess)
 {
 	int valid;
-	struct moonfish_castle castle;
 	unsigned char passing;
+	int white_oo, white_ooo;
+	int black_oo, black_ooo;
 	
-	castle = chess->castle;
 	passing = chess->passing;
+	white_oo = chess->white_oo;
+	white_ooo = chess->white_ooo;
+	black_oo = chess->black_oo;
+	black_ooo = chess->black_ooo;
 	
-	chess->castle.white_oo = 0;
-	chess->castle.white_ooo = 0;
-	chess->castle.black_oo = 0;
-	chess->castle.black_ooo = 0;
+	chess->white_oo = 0;
+	chess->white_ooo = 0;
+	chess->black_oo = 0;
+	chess->black_ooo = 0;
 	
 	chess->white ^= 1;
 	valid = moonfish_validate(chess);
 	chess->white ^= 1;
 	
-	chess->castle = castle;
 	chess->passing = passing;
+	chess->white_oo = white_oo;
+	chess->white_ooo = white_ooo;
+	chess->black_oo = black_oo;
+	chess->black_ooo = black_ooo;
 	
 	return valid ^ 1;
 }
@@ -565,22 +487,17 @@
 int moonfish_move(struct moonfish_chess *chess, struct moonfish_move *found, unsigned char from, unsigned char to)
 {
 	struct moonfish_move moves[32];
-	struct moonfish_move *move;
-	int valid;
+	int i, count;
 	
-	moonfish_moves(chess, moves, from);
+	count = moonfish_moves(chess, moves, from);
 	
-	for (move = moves ; move->piece != moonfish_outside ; move++)
+	for (i = 0 ; i < count ; i++)
 	{
-		if (move->to == to)
+		if (moves[i].to == to)
 		{
-			moonfish_play(chess, move);
-			valid = moonfish_validate(chess);
-			moonfish_unplay(chess, move);
-			
-			if (valid)
+			if (moonfish_validate(&moves[i].chess))
 			{
-				*found = *move;
+				*found = moves[i];
 				return 0;
 			}
 		}
@@ -603,10 +520,10 @@
 	y = 0;
 	
 	chess->white = 1;
-	chess->castle.white_oo = 0;
-	chess->castle.white_ooo = 0;
-	chess->castle.black_oo = 0;
-	chess->castle.black_ooo = 0;
+	chess->white_oo = 0;
+	chess->white_ooo = 0;
+	chess->black_oo = 0;
+	chess->black_ooo = 0;
 	chess->score = 0;
 	chess->passing = 0;
 	
@@ -661,10 +578,10 @@
 		if (ch == 0) return 0;
 		if (ch == ' ') break;
 		
-		if (ch == 'K') chess->castle.white_oo = 1;
-		if (ch == 'Q') chess->castle.white_ooo = 1;
-		if (ch == 'k') chess->castle.black_oo = 1;
-		if (ch == 'q') chess->castle.black_ooo = 1;
+		if (ch == 'K') chess->white_oo = 1;
+		if (ch == 'Q') chess->white_ooo = 1;
+		if (ch == 'k') chess->black_oo = 1;
+		if (ch == 'q') chess->black_ooo = 1;
 		
 		if (ch >= 'A' && ch <= 'H') return 1;
 		if (ch >= 'a' && ch <= 'h') return 1;
@@ -682,21 +599,17 @@
 
 int moonfish_finished(struct moonfish_chess *chess)
 {
-	struct moonfish_move moves[32], *move;
+	struct moonfish_move moves[32];
 	int x, y;
-	int valid;
+	int i, count;
 	
 	for (y = 0 ; y < 8 ; y++)
 	for (x = 0 ; x < 8 ; x++)
 	{
-		moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
-		for (move = moves ; move->piece != moonfish_outside ; move++)
-		{
-			moonfish_play(chess, move);
-			valid = moonfish_validate(chess);
-			moonfish_unplay(chess, move);
-			if (valid) return 0;
-		}
+		count = moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+		for (i = 0 ; i < count ; i++)
+			if (moonfish_validate(&moves[i].chess))
+				return 0;
 	}
 	
 	return 1;
@@ -714,14 +627,13 @@
 	return moonfish_finished(chess);
 }
 
-static int moonfish_match_move(struct moonfish_chess *chess, struct moonfish_move *result_move, unsigned char type, unsigned char promotion, int x0, int y0, int x1, int y1, int check, int captured)
+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;
 	int x, y;
 	struct moonfish_move moves[32];
-	struct moonfish_move *move;
 	int xi0, yi0, xi1, yi1;
-	int valid;
+	int i, count;
 	
 	xi0 = 0, xi1 = 8;
 	yi0 = 0, yi1 = 8;
@@ -734,24 +646,21 @@
 	for (y = yi0 ; y < yi1 ; y++)
 	for (x = xi0 ; x < xi1 ; x++)
 	{
-		moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
-		for (move = moves ; move->piece != moonfish_outside ; move++)
+		count = moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+		for (i = 0 ; i < count ; i++)
 		{
-			if (move->piece % 16 != type) continue;
-			if (captured && move->captured == moonfish_empty) continue;
-			if (promotion && promotion != move->promotion % 16) continue;
-			if (move->to % 10 != x1) continue;
-			if (move->to / 10 - 1 != y1) continue;
+			if (chess->board[moves[i].from] % 16 != type) continue;
+			if (captured && chess->board[moves[i].to] == moonfish_empty) continue;
+			if (promotion && promotion != moves[i].chess.board[moves[i].to] % 16) continue;
+			if (moves[i].to % 10 != x1) continue;
+			if (moves[i].to / 10 - 1 != y1) continue;
 			
-			moonfish_play(chess, move);
-			valid = moonfish_validate(chess);
-			if (valid && check) if (!moonfish_check(chess)) valid = 0;
-			if (valid && check == 2) if (!moonfish_checkmate(chess)) valid = 0;
-			moonfish_unplay(chess, move);
-			if (!valid) continue;
-			if (found) continue;
+			if (!moonfish_validate(&moves[i].chess)) continue;
+			if (check && !moonfish_check(chess)) continue;
+			if (check == 2 && !moonfish_checkmate(chess)) continue;
+			if (found) return 1;
 			found = 1;
-			*result_move = *move;
+			*move = moves[i];
 		}
 	}
 	
@@ -883,7 +792,6 @@
 	return moonfish_match_move(chess, move, type, promotion, x0, y0, x1, y1, check, capture);
 }
 
-/* todo: improve this */
 void moonfish_to_fen(struct moonfish_chess *chess, char *fen)
 {
 	int x, y;
@@ -948,10 +856,10 @@
 	else *fen++ = 'b';
 	*fen++ = ' ';
 	
-	if (chess->castle.white_oo) *fen++ = 'K';
-	if (chess->castle.white_ooo) *fen++ = 'Q';
-	if (chess->castle.black_oo) *fen++ = 'k';
-	if (chess->castle.black_ooo) *fen++ = 'q';
+	if (chess->white_oo) *fen++ = 'K';
+	if (chess->white_ooo) *fen++ = 'Q';
+	if (chess->black_oo) *fen++ = 'k';
+	if (chess->black_ooo) *fen++ = 'q';
 	if (fen[-1] == ' ') *fen++ = '-';
 	
 	*fen++ = ' ';
@@ -971,10 +879,10 @@
 	
 	int x, y;
 	struct moonfish_move moves[32];
-	struct moonfish_move *other_move;
 	char file_ambiguity, rank_ambiguity, ambiguity;
 	int to_x, to_y;
 	int from_x, from_y;
+	int i, count;
 	
 	from_x = move->from % 10 - 1;
 	from_y = move->from / 10 - 2;
@@ -982,7 +890,7 @@
 	to_x = move->to % 10 - 1;
 	to_y = move->to / 10 - 2;
 	
-	if (move->piece % 16 == moonfish_pawn)
+	if (chess->board[move->from] % 16 == moonfish_pawn)
 	{
 		if (from_x != to_x)
 		{
@@ -993,10 +901,10 @@
 		*name++ = to_x + 'a';
 		*name++ = to_y + '1';
 		
-		if (move->promotion % 16 != moonfish_pawn)
+		if (move->chess.board[move->to] % 16 != moonfish_pawn)
 		{
 			*name++ = '=';
-			*name++ = names[move->promotion % 16 - 2];
+			*name++ = names[move->chess.board[move->to] % 16 - 2];
 		}
 		
 		*name = 0;
@@ -1012,20 +920,20 @@
 	for (x = 0 ; x < 8 ; x++)
 	{
 		if ((x + 1) + (y + 2) * 10 == move->from) continue;
-		moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+		count = moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
 		
-		for (other_move = moves ; other_move->piece != moonfish_outside ; other_move++)
+		for (i = 0 ; i < count ; i++)
 		{
-			if (other_move->to != move->to) continue;
-			if (other_move->piece != move->piece) continue;
+			if (moves[i].to != move->to) continue;
+			if (chess->board[moves[i].from] != chess->board[move->from]) continue;
 			
 			ambiguity = 1;
-			if (other_move->from % 10 - 1 == from_x) file_ambiguity = 1;
-			if (other_move->from / 10 - 2 == from_y) rank_ambiguity = 1;
+			if (moves[i].from % 10 - 1 == from_x) file_ambiguity = 1;
+			if (moves[i].from / 10 - 2 == from_y) rank_ambiguity = 1;
 		}
 	}
 	
-	*name++ = names[(move->piece & 0xF) - 2];
+	*name++ = names[(chess->board[move->from] & 0xF) - 2];
 	
 	if (ambiguity)
 	{
@@ -1041,7 +949,7 @@
 		}
 	}
 	
-	if (move->captured != moonfish_empty)
+	if (chess->board[move->to] != moonfish_empty)
 		*name++ = 'x';
 		
 	*name++ = to_x + 'a';
--- a/main.c
+++ b/main.c
@@ -160,7 +160,7 @@
 				printf("score mate %d\n", moonfish_countdown(score));
 			else
 				printf("score cp %d\n", score);
-			moonfish_to_uci(&move, name);
+			moonfish_to_uci(&chess, &move, name);
 			printf("bestmove %s\n", name);
 		}
 		else if (!strcmp(arg, "quit"))
@@ -212,7 +212,7 @@
 				while ((arg = strtok(NULL, "\r\n\t ")) != NULL)
 				{
 					moonfish_from_uci(&chess, &move, arg);
-					moonfish_play(&chess, &move);
+					chess = move.chess;
 				}
 			}
 			
--- a/moonfish.h
+++ b/moonfish.h
@@ -89,13 +89,6 @@
 	moonfish_omega = 5000000
 };
 
-/* bitfield booleans representing castling rights */
-struct moonfish_castle
-{
-	unsigned int white_oo:1, white_ooo:1;
-	unsigned int black_oo:1, black_ooo:1;
-};
-
 /* represents a chess position */
 struct moonfish_chess
 {
@@ -102,48 +95,31 @@
 	/* 10 x 12 array board representation */
 	unsigned char board[120];
 	
-	/* whether it's white's turn (a boolean) */
-	/* 1 means white's turn */
-	/* 0 means black's turn */
-	unsigned char white;
+	/* bitfield booleans representing castling rights */
+	unsigned int white_oo:1, white_ooo:1;
+	unsigned int black_oo:1, black_ooo:1;
 	
+	/* PST score for the position */
+	int score;
+	
 	/* square index of a pawn that may be captured via e.p. */
 	/* or zero if there is no such pawn */
 	unsigned char passing;
 	
-	/* castling rights */
-	struct moonfish_castle castle;
-	
-	/* PST score for the position */
-	int score;
+	/* whether it's white's turn (a boolean) */
+	/* 1 means white's turn */
+	/* 0 means black's turn */
+	unsigned char white;
 };
 
-/* represents a possible move in a specific position */
-/* note: a move will only be sensibly useful in the position that it is meant for! */
-/* using a move on a position that it is not meant for might cause weird things */
+/* represents a move that can be made on a given position */
 struct moonfish_move
 {
-	/* indices of the squares the piece is moving from and to */
-	unsigned char from, to;
+	/* the position after the move is played */
+	struct moonfish_chess chess;
 	
-	/* integer representing the piece that is moving */
-	unsigned char piece;
-	
-	/* represents the piece that a pawn promotes to (if the move is a promotion) */
-	/* if the move is not a promotion, then "promotion == piece" */
-	unsigned char promotion;
-	
-	/* integer representing the captured piece (or "moonfish_empty" if the move isn't a capture) */
-	unsigned char captured;
-	
-	/* square index of the pawn that may have been captured via e.p. *before* this move was played (or zero if there was no such pawn) */
-	unsigned char passing;
-	
-	/* castling rights *before* the move was played */
-	struct moonfish_castle castle;
-	
-	/* PST score of the position *before* the move was played */
-	int score;
+	/* square indices of where the piece moved from and to */
+	unsigned char from, to;
 };
 
 /* opaque analysis struct */
@@ -160,21 +136,10 @@
 /* note: an array of moves of size 32 is always enough (since its impossible to have a piece have more moves available than that in chess) */
 /* note: this might generate a move that leaves the king in check (which is invalid!) */
 /* note: it will not generate any other kind of invalid move */
-/* to filter out invalid moves, you may use "moonfish_validate" below on the position *after* playing the given move */
-void moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from);
+/* to filter out invalid moves, you may use "moonfish_validate" below on the position *after* the generated move was played */
+/* this will return the number of moves generated */
+int moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from);
 
-/* assumes that a move (with the given "from" and "to" indices) is valid in the given position and creates it */
-/* the generated move is stored in the given move pointer */
-/* this will ignore underpromotions (always promotes to queen when the pawn reaches the last rank) */
-void moonfish_force_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to);
-
-/* play or unplay ("makes" or "unmakes") a given move by mutating the given position */
-/* note: a move must be played on the position it is meant for! */
-/* note: a move must be unplayed on the position that resulted from playing it! */
-/* that means move playing/unplaying must be balanced (surrounded by playing/unplaying the same move) */
-void moonfish_play(struct moonfish_chess *chess, struct moonfish_move *move);
-void moonfish_unplay(struct moonfish_chess *chess, struct moonfish_move *move);
-
 /* tries to find the best move in the given position in at most the given time */
 /* the move is stored in the "move" pointer, and the score for the position is returned */
 /* the move found is the best for the player whose turn it is on the given position */
@@ -210,7 +175,7 @@
 /* converts a move to UCI notation */
 /* the name is stored in the given "char" pointer (including the trailing NUL), so make sure you pass in a pointer that can fit it */
 /* a "char" array of size 6 is always enough to fit a given move name */
-void moonfish_to_uci(struct moonfish_move *move, char *name);
+void moonfish_to_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
 
 /* returns whether an iinvalid move was just played (i.e. whether the opponent king is attacked on the given position) */
 /* return 0: the opponent king is attacked, an invalid move was just played */
@@ -243,8 +208,11 @@
 int moonfish_from_san(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
 void moonfish_to_san(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
 
-/* similar to "moonfish_force_move", but this will perform validation, and only return 0 for a valid move */
-/* on failure (i.e. invalid move), it will return 1, and the move is not usable */
+/* checks whether there is a valid move with the given from/to square indices */
+/* then, if so, generates the move and stores it in the given move pointer */
+/* if the move is valid, this will return 0, and the pointer will point to a move that can be used */
+/* on failure (i.e. invalid move), this will return 1, and the move the pointer points to will not be usable */
+/* note: this will ignore underpromotions (always promotes to queen when a pawn reaches the last rank) */
 int moonfish_move(struct moonfish_chess *chess, struct moonfish_move *move, unsigned char from, unsigned char to);
 
 /* returns whether the game ended due to either checkmate or stalemate */
--- a/search.c
+++ b/search.c
@@ -50,7 +50,6 @@
 	struct moonfish_analysis *analysis;
 	pthread_t thread;
 	struct moonfish_move move;
-	struct moonfish_chess chess;
 	int score;
 };
 
@@ -116,7 +115,7 @@
 	analysis->time = -1;
 }
 
-static int moonfish_search(struct moonfish_info *info, int alpha, int beta, int depth, long int t0, long int time)
+static int moonfish_search(struct moonfish_info *info, struct moonfish_chess *chess, int alpha, int beta, int depth, long int t0, long int time)
 {
 	int score;
 	int i;
@@ -127,8 +126,8 @@
 	
 	if (depth < 0)
 	{
-		score = info->chess.score;
-		if (!info->chess.white) score *= -1;
+		score = chess->score;
+		if (!chess->white) score *= -1;
 		
 		if (depth < -3) return score;
 		if (score >= beta) return beta;
@@ -143,30 +142,23 @@
 	
 	for (y = 0 ; y < 8 ; y++)
 	for (x = 0 ; x < 8 ; x++)
-	{
-		moonfish_moves(&info->chess, moves + count, (x + 1) + (y + 2) * 10);
-		
-		while (moves[count].piece != moonfish_outside)
-		{
-			if (moves[count].captured % 16 == moonfish_king)
-				return moonfish_omega * (moonfish_depth - depth);
-			count++;
-		}
-	}
+		count += moonfish_moves(chess, moves + count, (x + 1) + (y + 2) * 10);
 	
-	for (i = 0 ; moves[i].piece != moonfish_outside ; i++)
+	for (i = 0 ; i < count ; i++)
+		if (chess->board[moves[i].to] % 16 == moonfish_king)
+			return moonfish_omega * (moonfish_depth - depth);
+	
+	for (i = 0 ; i < count ; i++)
 	{
 		if (depth < 0)
-		if (moves[i].captured == moonfish_empty)
-		if (moves[i].promotion == moves[i].piece)
+		if (chess->board[moves[i].to] == moonfish_empty)
+		if (moves[i].chess.board[moves[i].to] == chess->board[moves[i].from])
 			continue;
 		
 		t1 = moonfish_clock(info->analysis);
 		c = time * i / count - t1 + t0;
 		
-		moonfish_play(&info->chess, moves + i);
-		score = -moonfish_search(info, -beta, -alpha, depth - 1, t1, time / count + c);
-		moonfish_unplay(&info->chess, moves + i);
+		score = -moonfish_search(info, &moves[i].chess, -beta, -alpha, depth - 1, t1, time / count + c);
 		
 		if (score >= beta) return beta;
 		if (score > alpha) alpha = score;
@@ -195,36 +187,33 @@
 	t0 = moonfish_clock(info->analysis);
 	time = info->analysis->time;
 	
-	info->score = -moonfish_search(info, -100 * moonfish_omega, 100 * moonfish_omega, depth, t0, time);
+	info->score = -moonfish_search(info, &info->move.chess, -100 * moonfish_omega, 100 * moonfish_omega, depth, t0, time);
 	return moonfish_value;
 }
 
 static void moonfish_iteration(struct moonfish_analysis *analysis, struct moonfish_move *best_move)
 {
-	int i, j;
 	int result;
 	int x, y;
-	struct moonfish_move *move, moves[32];
+	struct moonfish_move moves[32];
+	int i, j, count;
 #ifdef moonfish_no_threads
-	int count;
+	int total;
 	
 	if (analysis->time >= 0)
 	{
-		count = 0;
+		total = 0;
 		
 		for (y = 0 ; y < 8 ; y++)
 		for (x = 0 ; x < 8 ; x++)
 		{
-			moonfish_moves(&analysis->chess, moves, (x + 1) + (y + 2) * 10);
+			count = moonfish_moves(&analysis->chess, moves, (x + 1) + (y + 2) * 10);
 			for (move = moves ; move->piece != moonfish_outside ; move++)
-			{
-				moonfish_play(&analysis->chess, move);
-				if (moonfish_validate(&analysis->chess)) count++;
-				moonfish_unplay(&analysis->chess, move);
-			}
+				if (!moonfish_validate(&analysis->chess)) count--;
+			total += count;
 		}
 		
-		analysis->time /= count;
+		analysis->time /= total;
 	}
 #endif
 	
@@ -233,15 +222,13 @@
 	for (y = 0 ; y < 8 ; y++)
 	for (x = 0 ; x < 8 ; x++)
 	{
-		moonfish_moves(&analysis->chess, moves, (x + 1) + (y + 2) * 10);
-		for (move = moves ; move->piece != moonfish_outside ; move++)
+		count = moonfish_moves(&analysis->chess, moves, (x + 1) + (y + 2) * 10);
+		for (i = 0 ; i < count ; i++)
 		{
-			analysis->info[j].chess = analysis->chess;
-			moonfish_play(&analysis->info[j].chess, move);
-			if (!moonfish_validate(&analysis->info[j].chess)) continue;
+			if (!moonfish_validate(&moves[i].chess)) continue;
 			
 			analysis->info[j].analysis = analysis;
-			analysis->info[j].move = *move;
+			analysis->info[j].move = moves[i];
 			
 			result = pthread_create(&analysis->info[j].thread, NULL, &moonfish_start_search, analysis->info + j);
 			if (result)
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -375,7 +375,7 @@
 					moonfish_to_san(&ply.chess, &move, san);
 					length = strlen(san);
 					if (i + length > sizeof fancy->pv - 2) break;
-					moonfish_play(&ply.chess, &move);
+					ply.chess = move.chess;
 					fancy->pv[i++] = ' ';
 					strcpy(fancy->pv + i, san);
 					i += length;
@@ -832,10 +832,10 @@
 				fancy->plies[fancy->i].depth = 0;
 				fancy->plies[fancy->i].score *= -1;
 				
-				moonfish_to_uci(&move, fancy->plies[fancy->i].name);
+				moonfish_to_uci(&fancy->plies[fancy->i].chess, &move, fancy->plies[fancy->i].name);
 				moonfish_to_san(&fancy->plies[fancy->i].chess, &move, fancy->plies[fancy->i].san);
 				
-				moonfish_play(&fancy->plies[fancy->i].chess, &move);
+				fancy->plies[fancy->i].chess = move.chess;
 				fancy->x = 0;
 				moonfish_fancy(fancy);
 				
--- a/tools/battle.c
+++ b/tools/battle.c
@@ -309,7 +309,7 @@
 	if (!battle->ugi)
 	{
 		moonfish_from_uci(&battle->chess, &move, arg);
-		moonfish_play(&battle->chess, &move);
+		battle->chess = move.chess;
 	}
 	
 	if (!bot->fixed_time)
--- a/tools/book.c
+++ b/tools/book.c
@@ -119,8 +119,8 @@
 				return 1;
 			}
 			
-			moonfish_play(&chess, &move);
-			moonfish_to_uci(&move, book[i][j++]);
+			moonfish_to_uci(&chess, &move, book[i][j++]);
+			chess = move.chess;
 			
 			arg = strtok(NULL, "\r\n\t ");
 			if (arg == NULL || arg[0] == '#')
--- a/tools/chat.c
+++ b/tools/chat.c
@@ -246,7 +246,9 @@
 		if (moonfish_from_san(&chess, &move, message))
 			continue;
 		
-		moonfish_play(&chess, &move);
+		moonfish_to_uci(&chess, &move, name);
+		chess = move.chess;
+		
 		if (moonfish_finished(&chess))
 		{
 			moonfish_to_fen(&chess, fen);
@@ -269,8 +271,6 @@
 			continue;
 		}
 		
-		moonfish_to_uci(&move, name);
-		
 		names = realloc(names, strlen(names) + strlen(name) + 2);
 		if (names == NULL)
 		{
@@ -304,7 +304,7 @@
 		
 		moonfish_from_uci(&chess, &move, name0);
 		moonfish_to_san(&chess, &move, name);
-		moonfish_play(&chess, &move);
+		chess = move.chess;
 		moonfish_to_fen(&chess, fen);
 		
 		for (i = 0 ; fen[i] != 0 ; i++)
--- a/tools/lichess.c
+++ b/tools/lichess.c
@@ -188,7 +188,7 @@
 				for (;;)
 				{
 					moonfish_from_uci(&chess, &move, name);
-					moonfish_to_uci(&move, name0);
+					moonfish_to_uci(&chess, &move, name0);
 					fprintf(in, "%s", name0);
 					name = strtok(NULL, " ");
 					if (name == NULL) break;
@@ -223,7 +223,7 @@
 		if (variant)
 		{
 			moonfish_from_uci(&chess, &move, name);
-			if (move.piece % 16 == moonfish_king)
+			if (chess.board[move.from] % 16 == moonfish_king)
 			{
 				if (!strcmp(name, "e1c1")) name = "e1a1";
 				else if (!strcmp(name, "e1g1")) name = "e1h1";
@@ -387,19 +387,19 @@
 			invalid = moonfish_from_fen(&chess, fen->valuestring);
 			
 			if (!invalid)
-			if (chess.castle.white_oo || chess.castle.white_ooo)
+			if (chess.white_oo || chess.white_ooo)
 			if (chess.board[25] != moonfish_white_king)
 				invalid = 1;
 			
 			if (!invalid)
-			if (chess.castle.black_oo || chess.castle.black_ooo)
+			if (chess.black_oo || chess.black_ooo)
 			if (chess.board[95] != moonfish_black_king)
 				invalid = 1;
 			
-			if (!invalid && chess.castle.white_ooo && chess.board[21] != moonfish_white_rook) invalid = 1;
-			if (!invalid && chess.castle.white_oo && chess.board[28] != moonfish_white_rook) invalid = 1;
-			if (!invalid && chess.castle.black_ooo && chess.board[91] != moonfish_black_rook) invalid = 1;
-			if (!invalid && chess.castle.black_oo && chess.board[98] != moonfish_black_rook) invalid = 1;
+			if (!invalid && chess.white_ooo && chess.board[21] != moonfish_white_rook) invalid = 1;
+			if (!invalid && chess.white_oo && chess.board[28] != moonfish_white_rook) invalid = 1;
+			if (!invalid && chess.black_ooo && chess.board[91] != moonfish_black_rook) invalid = 1;
+			if (!invalid && chess.black_oo && chess.board[98] != moonfish_black_rook) invalid = 1;
 			
 			if (invalid)
 			{
--- a/tools/perft.c
+++ b/tools/perft.c
@@ -12,27 +12,23 @@
 {
 	struct moonfish_move moves[32];
 	int x, y;
-	long int count;
-	struct moonfish_move *move;
+	long int perft;
+	int i, count;
 	
 	if (depth == 0) return 1;
 	
-	count = 0;
+	perft = 0;
 	
 	for (y = 0 ; y < 8 ; y++)
 	for (x = 0 ; x < 8 ; x++)
 	{
-		moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
-		for (move = moves ; move->piece != moonfish_outside ; move++)
-		{
-			moonfish_play(chess, move);
-			if (moonfish_validate(chess))
-				count += moonfish_perft(chess, depth - 1);
-			moonfish_unplay(chess, move);
-		}
+		count = moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
+		for (i = 0 ; i < count ; i++)
+			if (moonfish_validate(&moves[i].chess))
+				perft += moonfish_perft(&moves[i].chess, depth - 1);
 	}
 	
-	return count;
+	return perft;
 }
 
 int main(int argc, char **argv)
--- a/tools/play.c
+++ b/tools/play.c
@@ -282,7 +282,7 @@
 	
 	pthread_mutex_lock(fancy->mutex);
 	moonfish_from_uci(&fancy->chess, &move, arg);
-	moonfish_play(&fancy->chess, &move);
+	fancy->chess = move.chess;
 }
 
 int main(int argc, char **argv)
@@ -544,13 +544,13 @@
 			if (moonfish_move_from(&fancy->chess, &move, fancy->x, fancy->y, x1, y1) == 0)
 			{
 				*name++ = ' ';
-				moonfish_to_uci(&move, name);
+				moonfish_to_uci(&fancy->chess, &move, name);
 				name += strlen(name);
 				
 				pthread_mutex_lock(fancy->mutex);
 				
 				fancy->x = 0;
-				moonfish_play(&fancy->chess, &move);
+				fancy->chess = move.chess;
 				moonfish_reset_time(fancy);
 				moonfish_fancy(fancy);
 				if (moonfish_finished(&fancy->chess)) break;
--- a/tools/ugi-uci.c
+++ b/tools/ugi-uci.c
@@ -167,7 +167,7 @@
 					arg = strtok_r(NULL, " ", &save);
 					if (arg == NULL) break;
 					moonfish_from_uci(&moonfish_ugi_chess, &move, arg);
-					moonfish_play(&moonfish_ugi_chess, &move);
+					moonfish_ugi_chess = move.chess;
 				}
 			}
 		}
@@ -175,7 +175,6 @@
 		fputs(line2, in);
 	}
 }
-
 
 /* read from bot, write to GUI */
 void *moonfish_convert_out(void *data)
--