ref: 1a7e19ead4da96e8994df291a084fcf1f12dd568
parent: 1c280503ec443f76b4ce15308e6b2a4800d7a08c
author: zamfofex <zamfofex@twdb.moe>
date: Tue Dec 12 22:13:35 EST 2023
simplify and improve move generation
--- a/chess.c
+++ b/chess.c
@@ -77,7 +77,8 @@
static char moonfish_delta(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from, unsigned char *to, signed char delta)
{*to += delta;
- if (chess->board[*to] <= moonfish_our_king) return 0;
+ if (chess->board[*to] == moonfish_outside) return 0;
+ if (chess->board[*to] / 16 == chess->board[from] / 16) return 0;
moonfish_create_move(chess, moves, from, *to);
if (chess->board[*to] != moonfish_empty) return 0;
return 1;
@@ -132,10 +133,15 @@
static char moonfish_attacked(struct moonfish_chess *chess, unsigned char from, unsigned char to)
{int check;
+ unsigned char piece;
+
+ if (chess->white) piece = moonfish_white_king;
+ else piece = moonfish_black_king;
+
chess->board[from] = moonfish_empty;
- chess->board[to] = moonfish_our_king;
+ chess->board[to] = piece;
check = moonfish_check(chess);
- chess->board[from] = moonfish_our_king;
+ chess->board[from] = piece;
chess->board[to] = moonfish_empty;
return check;
}
@@ -144,8 +150,9 @@
{unsigned char to;
- for (to = 22 ; to != from ; to++)
- if (chess->board[to] != moonfish_empty)
+ to = chess->white ? 22 : 92;
+ while (to != from)
+ if (chess->board[to++] != moonfish_empty)
return;
if (moonfish_check(chess)) return;
@@ -159,8 +166,9 @@
{unsigned char to;
- for (to = 27 ; to != from ; to--)
- if (chess->board[to] != moonfish_empty)
+ to = chess->white ? 27 : 97;
+ while (to != from)
+ if (chess->board[to--] != moonfish_empty)
return;
if (moonfish_check(chess)) return;
@@ -181,16 +189,16 @@
moonfish_jump(chess, moves, from, 1);
moonfish_jump(chess, moves, from, -1);
- if (!chess->white && from == 24)
+ if (chess->white)
{- if (chess->castle.black_oo) moonfish_castle_low(chess, moves, from);
- if (chess->castle.black_ooo) moonfish_castle_high(chess, moves, from);
- }
- if (chess->white && from == 25)
- {if (chess->castle.white_oo) moonfish_castle_high(chess, moves, from);
if (chess->castle.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);
+ }
}
static void moonfish_move_pawn(struct moonfish_chess *chess, struct moonfish_move **moves, unsigned char from)
@@ -197,36 +205,49 @@
{struct moonfish_move *move;
unsigned char promotion;
+ int dy;
- promotion = moonfish_our_pawn;
- if (from > 80) promotion = moonfish_our_queen;
+ if (chess->white)
+ {+ dy = 10;
+ promotion = moonfish_white_pawn;
+ if (from > 80) promotion = moonfish_white_queen;
+ }
+ else
+ {+ dy = -10;
+ promotion = moonfish_black_pawn;
+ if (from < 30) promotion = moonfish_black_queen;
+ }
- if (chess->board[from + 10] == moonfish_empty)
+ if (chess->board[from + dy] == moonfish_empty)
{- move = moonfish_create_move(chess, moves, from, from + 10);
+ move = moonfish_create_move(chess, moves, from, from + dy);
move->promotion = promotion;
- if (from < 40)
+ if (chess->white ? from < 40 : from > 70)
{- if (chess->board[from + 20] == moonfish_empty)
+ if (chess->board[from + dy * 2] == moonfish_empty)
{- move = moonfish_create_move(chess, moves, from, from + 20);
+ move = moonfish_create_move(chess, moves, from, from + dy * 2);
move->promotion = promotion;
}
}
}
- if (chess->board[from + 9] >= moonfish_their_pawn)
- if (chess->board[from + 9] != moonfish_empty)
+ if (chess->board[from + dy + 1] / 16 != chess->board[from] / 16)
+ if (chess->board[from + dy + 1] != moonfish_empty)
+ if (chess->board[from + dy + 1] != moonfish_outside)
{- move = moonfish_create_move(chess, moves, from, from + 9);
+ move = moonfish_create_move(chess, moves, from, from + dy + 1);
move->promotion = promotion;
}
- if (chess->board[from + 11] >= moonfish_their_pawn)
- if (chess->board[from + 11] != moonfish_empty)
+ if (chess->board[from + dy - 1] / 16 != chess->board[from] / 16)
+ if (chess->board[from + dy - 1] != moonfish_empty)
+ if (chess->board[from + dy - 1] != moonfish_outside)
{- move = moonfish_create_move(chess, moves, from, from + 11);
+ move = moonfish_create_move(chess, moves, from, from + dy - 1);
move->promotion = promotion;
}
}
@@ -234,70 +255,21 @@
void moonfish_moves(struct moonfish_chess *chess, struct moonfish_move *moves, unsigned char from)
{unsigned char piece;
+
piece = chess->board[from];
- if (piece == moonfish_our_pawn) moonfish_move_pawn(chess, &moves, from);
- if (piece == moonfish_our_knight) moonfish_move_knight(chess, &moves, from);
- if (piece == moonfish_our_bishop) moonfish_move_bishop(chess, &moves, from);
- if (piece == moonfish_our_rook) moonfish_move_rook(chess, &moves, from);
- if (piece == moonfish_our_queen) moonfish_move_queen(chess, &moves, from);
- if (piece == moonfish_our_king) moonfish_move_king(chess, &moves, from);
- moves->piece = moonfish_outside;
-}
-
-static void moonfish_swap(struct moonfish_chess *chess, int i, int j)
-{- unsigned char piece;
- piece = chess->board[i];
- chess->board[i] = chess->board[j];
- chess->board[j] = piece;
-}
-
-static void moonfish_flip_horizontally(struct moonfish_chess *chess)
-{- int x, y;
- for (y = 0 ; y < 8 ; y++)
- for (x = 0 ; x < 4 ; x++)
+ if (chess->white ? piece / 16 == 1 : piece / 16 == 2)
{- moonfish_swap(chess,
- (x + 1) + (y + 2) * 10,
- (8 - x) + (y + 2) * 10
- );
+ 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) moonfish_move_king(chess, &moves, from);
}
+ moves->piece = moonfish_outside;
}
-static void moonfish_flip_vertically(struct moonfish_chess *chess)
-{- int x, y;
-
- for (y = 0 ; y < 4 ; y++)
- for (x = 0 ; x < 8 ; x++)
- {- moonfish_swap(chess,
- (x + 1) + (y + 2) * 10,
- (x + 1) + (9 - y) * 10
- );
- }
-}
-
-static void moonfish_rotate(struct moonfish_chess *chess)
-{- int x, y;
-
- moonfish_flip_horizontally(chess);
- moonfish_flip_vertically(chess);
-
- chess->white ^= 1;
- chess->score *= -1;
-
- for (y = 0 ; y < 8 ; y++)
- for (x = 0 ; x < 8 ; x++)
- {- if (chess->board[(x + 1) + (y + 2) * 10] != moonfish_empty)
- chess->board[(x + 1) + (y + 2) * 10] ^= 0x30;
- }
-}
-
static int moonfish_table(int from, unsigned char piece)
{int x, y;
@@ -312,8 +284,6 @@
type = (piece & 0xF) - 1;
color = (piece >> 4) - 1;
- if (color == 0) y = 7 - y;
-
if (x < 4) x = 4 - x;
else x %= 4;
@@ -326,6 +296,8 @@
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->piece);
@@ -334,27 +306,31 @@
chess->board[move->from] = moonfish_empty;
chess->board[move->to] = move->promotion;
- if (move->piece == moonfish_our_pawn)
+ if (move->piece % 16 == moonfish_pawn)
if ((move->to - move->from) % 10)
if (move->captured == moonfish_empty)
{- chess->score -= moonfish_table(move->to - 10, moonfish_their_pawn);
- chess->board[move->to - 10] = moonfish_empty;
+ if (chess->white) dy = 10, piece = moonfish_black_pawn;
+ else dy = -10, piece = moonfish_white_pawn;
+
+ chess->score -= moonfish_table(move->to - dy, piece);
+ chess->board[move->to - dy] = moonfish_empty;
}
- if (move->piece == moonfish_our_king)
+ if (move->piece % 16 == moonfish_king)
{x0 = 0;
- if (move->from == 24 && move->to == 22) x0 = 1, x1 = 3;
- if (move->from == 24 && move->to == 26) x0 = 8, x1 = 5;
- if (move->from == 25 && move->to == 27) x0 = 8, x1 = 6;
- if (move->from == 25 && move->to == 23) x0 = 1, x1 = 4;
+ 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->score -= moonfish_table(x0 + 20, moonfish_our_rook);
- chess->score += moonfish_table(x1 + 20, moonfish_our_rook);
- chess->board[x0 + 20] = moonfish_empty;
- chess->board[x1 + 20] = moonfish_our_rook;
+ 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)
@@ -369,35 +345,29 @@
}
}
- if (move->piece == moonfish_our_rook)
+ if (move->piece == moonfish_white_rook)
{- if (move->from == 21)
- {- if (chess->white) chess->castle.white_ooo = 0;
- else chess->castle.black_oo = 0;
- }
- if (move->from == 28)
- {- if (chess->white) chess->castle.white_oo = 0;
- else chess->castle.black_ooo = 0;
- }
+ 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_their_rook)
+ if (move->captured == moonfish_white_rook)
{- if (move->to == 91)
- {- if (chess->white) chess->castle.black_ooo = 0;
- else chess->castle.white_oo = 0;
- }
- if (move->to == 98)
- {- if (chess->white) chess->castle.black_oo = 0;
- else chess->castle.white_ooo = 0;
- }
+ 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;
+ }
- moonfish_rotate(chess);
+ chess->white ^= 1;
}
void moonfish_unplay(struct moonfish_chess *chess, struct moonfish_move *move)
@@ -404,7 +374,7 @@
{int x0, x1;
- moonfish_rotate(chess);
+ chess->white ^= 1;
chess->board[move->from] = move->piece;
chess->board[move->to] = move->captured;
@@ -411,14 +381,18 @@
chess->castle = move->castle;
chess->score = move->score;
- if (move->piece == moonfish_our_king)
+ if (move->piece % 16 == moonfish_king)
{x0 = 0;
- if (move->from == 24 && move->to == 22) x0 = 1, x1 = 3;
- if (move->from == 24 && move->to == 26) x0 = 8, x1 = 5;
- if (move->from == 25 && move->to == 27) x0 = 8, x1 = 6;
- if (move->from == 25 && move->to == 23) x0 = 1, x1 = 4;
- if (x0) chess->board[x1 + 20] = moonfish_empty, chess->board[x0 + 20] = moonfish_our_rook;
+ 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;
+ }
}
}
@@ -436,27 +410,16 @@
void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name)
{int x, y;
+ unsigned char color;
x = name[0] - 'a';
y = name[1] - '1';
- if (!chess->white)
- {- x = 7 - x;
- y = 7 - y;
- }
-
move->from = (x + 1) + (y + 2) * 10;
x = name[2] - 'a';
y = name[3] - '1';
- if (!chess->white)
- {- x = 7 - x;
- y = 7 - y;
- }
-
move->to = (x + 1) + (y + 2) * 10;
move->piece = chess->board[move->from];
@@ -465,13 +428,14 @@
move->castle = chess->castle;
move->score = chess->score;
- if (name[4] == 'q') move->promotion = moonfish_our_queen;
- if (name[4] == 'r') move->promotion = moonfish_our_rook;
- if (name[4] == 'b') move->promotion = moonfish_our_bishop;
- if (name[4] == 'n') move->promotion = moonfish_our_knight;
+ 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;
}
-void moonfish_to_uci(char *name, struct moonfish_move *move, int white)
+void moonfish_to_uci(char *name, struct moonfish_move *move)
{int x, y;
@@ -478,12 +442,6 @@
x = move->from % 10 - 1;
y = move->from / 10 - 2;
- if (!white)
- {- x = 7 - x;
- y = 7 - y;
- }
-
name[0] = x + 'a';
name[1] = y + '1';
@@ -490,12 +448,6 @@
x = move->to % 10 - 1;
y = move->to / 10 - 2;
- if (!white)
- {- x = 7 - x;
- y = 7 - y;
- }
-
name[2] = x + 'a';
name[3] = y + '1';
@@ -571,7 +523,7 @@
x++;
}
- if (*fen++ == 'b') moonfish_rotate(chess);
+ if (*fen++ == 'b') chess->white ^= 1;
if (*fen++ != ' ') return;
for (;;)
@@ -597,7 +549,7 @@
{moonfish_moves(chess, moves, (x + 1) + (y + 2) * 10);
for (move = moves ; move->piece != moonfish_outside ; move++)
- if (move->captured == moonfish_their_king)
+ if (move->captured % 16 == moonfish_king)
return 0;
}
@@ -616,9 +568,9 @@
chess->castle.black_oo = 0;
chess->castle.black_ooo = 0;
- moonfish_rotate(chess);
+ chess->white ^= 1;
valid = moonfish_validate(chess);
- moonfish_rotate(chess);
+ chess->white ^= 1;
chess->castle = castle;
--- a/main.c
+++ b/main.c
@@ -94,7 +94,7 @@
}
moonfish_best_move(ctx, &move, wtime, btime);
- moonfish_to_uci(name, &move, ctx->chess.white);
+ moonfish_to_uci(name, &move);
printf("bestmove %s\n", name);}
else if (!strcmp(arg, "quit"))
--- a/moonfish.h
+++ b/moonfish.h
@@ -6,20 +6,27 @@
enum
{- moonfish_our_pawn = 0x11,
- moonfish_our_knight = 0x12,
- moonfish_our_bishop = 0x13,
- moonfish_our_rook = 0x14,
- moonfish_our_queen = 0x15,
- moonfish_our_king = 0x16,
+ moonfish_white_pawn = 0x11,
+ moonfish_white_knight = 0x12,
+ moonfish_white_bishop = 0x13,
+ moonfish_white_rook = 0x14,
+ moonfish_white_queen = 0x15,
+ moonfish_white_king = 0x16,
- moonfish_their_pawn = 0x21,
- moonfish_their_knight = 0x22,
- moonfish_their_bishop = 0x23,
- moonfish_their_rook = 0x24,
- moonfish_their_queen = 0x25,
- moonfish_their_king = 0x26,
+ moonfish_black_pawn = 0x21,
+ moonfish_black_knight = 0x22,
+ moonfish_black_bishop = 0x23,
+ moonfish_black_rook = 0x24,
+ moonfish_black_queen = 0x25,
+ moonfish_black_king = 0x26,
+ moonfish_pawn = 1,
+ moonfish_knight = 2,
+ moonfish_bishop = 3,
+ moonfish_rook = 4,
+ moonfish_queen = 5,
+ moonfish_king = 6,
+
moonfish_outside = 0,
moonfish_empty = 0xFF,
@@ -68,7 +75,7 @@
int moonfish_best_move(struct moonfish *ctx, struct moonfish_move *move, long int our_time, long int their_time);
void moonfish_from_uci(struct moonfish_chess *chess, struct moonfish_move *move, char *name);
-void moonfish_to_uci(char *name, struct moonfish_move *move, int white);
+void moonfish_to_uci(char *name, struct moonfish_move *move);
int moonfish_validate(struct moonfish_chess *chess);
int moonfish_check(struct moonfish_chess *chess);
--- a/search.c
+++ b/search.c
@@ -24,7 +24,11 @@
if (depth <= 0)
{- if (depth <= -4) return chess->score;
+ if (depth <= -4)
+ {+ if (chess->white) return chess->score;
+ else return -chess->score;
+ }
if (chess->score >= beta) return beta;
if (chess->score > alpha) alpha = chess->score;
@@ -38,7 +42,7 @@
for (move = moves ; move->piece != moonfish_outside ; move++)
{if (depth <= 0 && move->captured == moonfish_empty) continue;
- if (move->captured == moonfish_their_king) return moonfish_omega * (depth + 10);
+ if (move->captured % 16 == moonfish_king) return moonfish_omega * (depth + 10);
moonfish_play(chess, move);
score = -moonfish_search(chess, -beta, -alpha, depth - 1);
--- a/tools/analyse.c
+++ b/tools/analyse.c
@@ -49,8 +49,7 @@
else
printf("\x1B[48;5;69m");- if (fancy->plies[fancy->i].chess.white) y = 7 - y;
- else x = 7 - x;
+ y = 7 - y;
piece = fancy->plies[fancy->i].chess.board[(x + 1) + (y + 2) * 10];
@@ -60,8 +59,6 @@
return;
}
- if (!fancy->plies[fancy->i].chess.white) piece ^= 0x30;
-
if (piece >> 4 == 1)
printf("\x1B[38;5;253m");else
@@ -303,16 +300,8 @@
to_x = move->to % 10 - 1;
to_y = move->to / 10 - 2;
- if (!chess->white)
+ if (move->piece % 16 == moonfish_pawn)
{- from_x = 7 - from_x;
- from_y = 7 - from_y;
- to_x = 7 - to_x;
- to_y = 7 - to_y;
- }
-
- if (move->piece == moonfish_our_pawn)
- {if (from_x != to_x)
{*name++ = from_x + 'a';
@@ -322,10 +311,10 @@
*name++ = to_x + 'a';
*name++ = to_y + '1';
- if (move->promotion != moonfish_our_pawn)
+ if (move->promotion % 16 != moonfish_pawn)
{*name++ = '=';
- *name++ = names[(move->promotion & 0xF) - 2];
+ *name++ = names[move->promotion % 16 - 2];
}
*name = 0;
@@ -587,22 +576,14 @@
struct moonfish_move *move;
int valid;
- if (chess->white)
- {- y0 = 9 - y0;
- y1 = 9 - y1;
- }
- else
- {- x0 = 9 - x0;
- x1 = 9 - x1;
- }
+ y0 = 10 - y0;
+ y1 = 10 - y1;
- moonfish_moves(chess, moves, x0 + (y0 + 1) * 10);
+ moonfish_moves(chess, moves, x0 + y0 * 10);
for (move = moves ; move->piece != moonfish_outside ; move++)
{- if (move->to == x1 + (y1 + 1) * 10)
+ if (move->to == x1 + y1 * 10)
{moonfish_play(chess, move);
valid = moonfish_validate(chess);
@@ -927,7 +908,7 @@
fancy->plies[fancy->i].depth = 0;
fancy->plies[fancy->i].score *= -1;
- moonfish_to_uci(fancy->plies[fancy->i].name, &move, fancy->plies[fancy->i].chess.white);
+ moonfish_to_uci(fancy->plies[fancy->i].name, &move);
moonfish_to_san(&fancy->plies[fancy->i].chess, fancy->plies[fancy->i].san, &move);
moonfish_play(&fancy->plies[fancy->i].chess, &move);
--- a/tools/play.c
+++ b/tools/play.c
@@ -38,7 +38,7 @@
else
printf("\x1B[48;5;69m");- if (fancy->white == fancy->chess.white) y = 7 - y;
+ if (fancy->white) y = 7 - y;
else x = 7 - x;
piece = fancy->chess.board[(x + 1) + (y + 2) * 10];
@@ -49,8 +49,6 @@
return;
}
- if (!fancy->chess.white) piece ^= 0x30;
-
if (piece >> 4 == 1)
printf("\x1B[38;5;253m");else
@@ -191,14 +189,20 @@
struct moonfish_move *move;
int valid;
- y0 = 9 - y0;
- y1 = 9 - y1;
+ if (!chess->white)
+ {+ x0 = 9 - x0; y0 = 9 - y0;
+ x1 = 9 - x1; y1 = 9 - y1;
+ }
- moonfish_moves(chess, moves, x0 + (y0 + 1) * 10);
+ y0 = 10 - y0;
+ y1 = 10 - y1;
+ moonfish_moves(chess, moves, x0 + y0 * 10);
+
for (move = moves ; move->piece != moonfish_outside ; move++)
{- if (move->to == x1 + (y1 + 1) * 10)
+ if (move->to == x1 + y1 * 10)
{moonfish_play(chess, move);
valid = moonfish_validate(chess);
@@ -559,7 +563,7 @@
if (moonfish_move_from(&fancy->chess, &move, fancy->x, fancy->y, x1, y1) == 0)
{*name++ = ' ';
- moonfish_to_uci(name, &move, fancy->chess.white);
+ moonfish_to_uci(name, &move);
name += strlen(name);
pthread_mutex_lock(fancy->mutex);
--
⑨