add memstats / clear lists when new fen position

This commit is contained in:
2021-11-14 16:03:36 +01:00
parent 6dac938c76
commit f0e1836f2f
10 changed files with 181 additions and 64 deletions

View File

@@ -1,8 +1,12 @@
'4k3/4p3/8/b7/1BR1p2p/1Q3P2/5N2/4K3 w - - 0 1' 4k3/4p3/8/b7/1BR1p2p/1Q3P2/5N2/4K3 w - - 0 1
'r1bq1rk1/pppp1ppp/2n2n2/4p3/2B1P3/3PPN2/PPP3PP/RN1QK2R b KQ - 1 7' r1bq1rk1/pppp1ppp/2n2n2/4p3/2B1P3/3PPN2/PPP3PP/RN1QK2R b KQ - 1 7
'6k1/6pp/R2p4/p1p5/8/1P1r3P/6P1/6K1 b - - 3 37' 6k1/6pp/R2p4/p1p5/8/1P1r3P/6P1/6K1 b - - 3 37
# both can castle queen only # both can castle queen only
'r3k2r/8/3B4/8/8/3b4/8/R3K2R w KQkq - 0 1' r3k2r/8/3B4/8/8/3b4/8/R3K2R w KQkq - 0 1
'r3k2r/8/3BB3/8/8/3bb3/8/R3K2R w KQkq - 0 1' r3k2r/8/3BB3/8/8/3bb3/8/R3K2R w KQkq - 0 1
'r2bkb1r/8/8/8/8/3bb3/8/R2BKB1R w KQkq - 0 1' r2bkb1r/8/8/8/8/3bb3/8/R2BKB1R w KQkq - 0 1
# illegal positions
4k3/8/8/8/7b/8/8/4K3 b - - 0 1
2r1k3/3P4/8/8/8/8/8/4K3 w - - 0 1

View File

@@ -13,4 +13,5 @@
src/list.h src/pool.h src/board.h src/position.h src/list.h src/pool.h src/board.h src/position.h
./obj/pool.o:: src/pool.c src/list.h src/pool.h src/debug.h ./obj/pool.o:: src/pool.c src/list.h src/pool.h src/debug.h
./obj/position.o:: src/position.c src/chessdefs.h src/bits.h src/debug.h \ ./obj/position.o:: src/position.c src/chessdefs.h src/bits.h src/debug.h \
src/position.h src/board.h src/piece.h src/list.h src/pool.h src/fen.h src/position.h src/board.h src/piece.h src/list.h src/pool.h src/move.h \
src/fen.h

View File

@@ -48,13 +48,15 @@ COMMAND *find_command (char *);
char *stripwhite (char *string); char *stripwhite (char *string);
/* The names of functions that actually do the manipulation. */ /* The names of functions that actually do the manipulation. */
int do_help (pos_t *, char*); int do_help(pos_t *, char*);
int do_fen (pos_t *, char*); int do_fen(pos_t *, char*);
int do_pos (pos_t *, char*); int do_pos(pos_t *, char*);
int do_genmoves(pos_t *, char*); int do_genmoves(pos_t *, char*);
int do_prmoves(pos_t *, char*); int do_prmoves(pos_t *, char*);
int do_eval (pos_t *, char*); int do_memstats(pos_t *, char*);
int do_quit (pos_t *, char*); int do_eval(pos_t *, char*);
int do_quit(pos_t *, char*);
int do_debug(pos_t *, char*);
COMMAND commands[] = { COMMAND commands[] = {
{ "help", do_help, "Display this text" }, { "help", do_help, "Display this text" },
@@ -62,10 +64,12 @@ COMMAND commands[] = {
{ "fen", do_fen, "Set position to FEN" }, { "fen", do_fen, "Set position to FEN" },
{ "pos", do_pos, "Print current position" }, { "pos", do_pos, "Print current position" },
{ "quit", do_quit, "Quit" }, { "quit", do_quit, "Quit" },
{ "genmv", do_genmoves, "Generate next move list" }, { "genmove", do_genmoves, "Generate next move list" },
{ "prmv", do_prmoves, "Generate next move list" }, { "prmoves", do_prmoves, "Generate next move list" },
{ "memstats", do_memstats, "Generate next move list" },
{ "eval", do_eval, "Eval current position" }, { "eval", do_eval, "Eval current position" },
{ NULL, (int (*)()) NULL, NULL } { "debug", do_debug, "Set log level to LEVEL" },
{ NULL, (int(*)()) NULL, NULL }
}; };
static int done=0; static int done=0;
@@ -87,13 +91,13 @@ int bodichess(pos_t *pos)
* Then, if there is anything left, add it to the history list * Then, if there is anything left, add it to the history list
* and execute it. * and execute it.
*/ */
s = stripwhite (buffer); s = stripwhite(buffer);
if (*s) { if (*s) {
add_history (s); add_history(s);
execute_line (pos, s); execute_line(pos, s);
} }
free (buffer); free(buffer);
} }
return 0; return 0;
@@ -170,15 +174,13 @@ char *escape(const char *original)
int quote_detector(char *line, int index) int quote_detector(char *line, int index)
{ {
return ( return index > 0
index > 0 && && line[index - 1] == '\\'
line[index - 1] == '\\' && &&!quote_detector(line, index - 1);
!quote_detector(line, index - 1)
);
} }
/* Execute a command line. */ /* Execute a command line. */
int execute_line (pos_t *pos, char *line) int execute_line(pos_t *pos, char *line)
{ {
register int i; register int i;
COMMAND *command; COMMAND *command;
@@ -186,31 +188,31 @@ int execute_line (pos_t *pos, char *line)
/* Isolate the command word. */ /* Isolate the command word. */
i = 0; i = 0;
while (line[i] && whitespace (line[i])) while (line[i] && whitespace(line[i]))
i++; i++;
word = line + i; word = line + i;
while (line[i] && !whitespace (line[i])) while (line[i] && !whitespace(line[i]))
i++; i++;
if (line[i]) if (line[i])
line[i++] = '\0'; line[i++] = '\0';
command = find_command (word); command = find_command(word);
if (!command) { if (!command) {
fprintf (stderr, "%s: Unknown command.\n", word); fprintf(stderr, "%s: Unknown command.\n", word);
return (-1); return -1;
} }
/* Get argument to command, if any. */ /* Get argument to command, if any. */
while (whitespace (line[i])) while (whitespace(line[i]))
i++; i++;
word = line + i; word = line + i;
/* return command number */ /* return command number */
return ((*(command->func)) (pos, word)); return (*command->func)(pos, word);
} }
/* Look up NAME as the name of a command, and return a pointer to that /* Look up NAME as the name of a command, and return a pointer to that
@@ -220,10 +222,10 @@ COMMAND *find_command(char *name)
register int i; register int i;
for (i = 0; commands[i].name; i++) for (i = 0; commands[i].name; i++)
if (strcmp (name, commands[i].name) == 0) if (strcmp(name, commands[i].name) == 0)
return (&commands[i]); return &commands[i];
return ((COMMAND *)NULL); return (COMMAND *)NULL;
} }
/* Strip whitespace from the start and end of STRING. Return a pointer /* Strip whitespace from the start and end of STRING. Return a pointer
@@ -232,14 +234,14 @@ char *stripwhite(char *string)
{ {
register char *s, *t; register char *s, *t;
for (s = string; whitespace (*s); s++) for (s = string; whitespace(*s); s++)
; ;
if (*s == 0) if (*s == 0)
return (s); return s;
t = s + strlen (s) - 1; t = s + strlen(s) - 1;
while (t > s && whitespace (*t)) while (t > s && whitespace(*t))
t--; t--;
*++t = '\0'; *++t = '\0';
@@ -261,7 +263,7 @@ int do_fen(pos_t *pos, char *arg)
return 1; return 1;
} }
int do_pos (pos_t *pos, int do_pos(pos_t *pos,
__attribute__((unused)) char *arg) __attribute__((unused)) char *arg)
{ {
log_f(1, "%s\n", arg); log_f(1, "%s\n", arg);
@@ -286,12 +288,28 @@ int do_prmoves(pos_t *pos,
return 1; return 1;
} }
int do_memstats(__attribute__((unused)) pos_t *pos,
__attribute__((unused)) char *arg)
{
moves_pool_stats();
piece_pool_stats();
pos_pool_stats();
return 1;
}
int do_quit(__attribute__((unused)) pos_t *pos, int do_quit(__attribute__((unused)) pos_t *pos,
__attribute__((unused)) char *arg) __attribute__((unused)) char *arg)
{ {
return done = 1; return done = 1;
} }
int do_debug(__attribute__((unused)) pos_t *pos,
__attribute__((unused)) char *arg)
{
debug_level_set(atoi(arg));
return 1;
}
/* Print out help for ARG, or for all of the commands if ARG is /* Print out help for ARG, or for all of the commands if ARG is
not present. */ not present. */
int do_help(__attribute__((unused)) pos_t *pos, int do_help(__attribute__((unused)) pos_t *pos,
@@ -301,30 +319,30 @@ int do_help(__attribute__((unused)) pos_t *pos,
int printed = 0; int printed = 0;
for (i = 0; commands[i].name; i++) { for (i = 0; commands[i].name; i++) {
if (!*arg || (strcmp (arg, commands[i].name) == 0)) { if (!*arg || (strcmp(arg, commands[i].name) == 0)) {
printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); printf("%s\t\t%s.\n", commands[i].name, commands[i].doc);
printed++; printed++;
} }
} }
if (!printed) { if (!printed) {
printf ("No commands match `%s'. Possibilties are:\n", arg); printf("No commands match `%s'. Possibilties are:\n", arg);
for (i = 0; commands[i].name; i++) { for (i = 0; commands[i].name; i++) {
/* Print in six columns. */ /* Print in six columns. */
if (printed == 6) { if (printed == 6) {
printed = 0; printed = 0;
printf ("\n"); printf("\n");
} }
printf ("%s\t", commands[i].name); printf("%s\t", commands[i].name);
printed++; printed++;
} }
if (printed) if (printed)
printf ("\n"); printf("\n");
} }
return (0); return 0;
} }
#ifdef BIN_bodichess #ifdef BIN_bodichess

View File

@@ -53,6 +53,7 @@ pos_t *fen2pos(pos_t *pos, char *fen)
board_t *board = pos->board; board_t *board = pos->board;
# define SKIP_BLANK(p) for(;*(p) == ' '; (p)++) # define SKIP_BLANK(p) for(;*(p) == ' '; (p)++)
pos_clear(pos);
/* 1) get piece placement information /* 1) get piece placement information
*/ */
for (rank = 7, file = 0; *p && *p != ' '; ++p) { for (rank = 7, file = 0; *p && *p != ' '; ++p) {

View File

@@ -54,6 +54,12 @@ pool_t *moves_pool_init()
return moves_pool; return moves_pool;
} }
void moves_pool_stats()
{
if (moves_pool)
pool_stats(moves_pool);
}
int move_print(move_t *move, move_flags_t flags) int move_print(move_t *move, move_flags_t flags)
{ {
if (flags & M_PR_CAPT && !(move->flags & M_CAPTURE)) { if (flags & M_PR_CAPT && !(move->flags & M_CAPTURE)) {
@@ -141,8 +147,17 @@ static move_t *move_add(pos_t *pos, piece_t piece, square_t from,
FILE2C(GET_F(to)), FILE2C(GET_F(to)),
RANK2C(GET_R(to))); RANK2C(GET_R(to)));
# endif # endif
/* impossible if opponent king is attacked
*/
if (COLOR(piece) != pos->turn) if (COLOR(piece) != pos->turn)
return NULL; return NULL;
if (board[to].piece & KING) {
# ifdef DEBUG_MOVE
log_i(2, "invalid position: opponent king [%c%c] is in check.\n",
FILE2C(GET_F(to)), RANK2C(GET_R(to)));
# endif
return NULL;
}
if (!(move = pool_get(moves_pool))) if (!(move = pool_get(moves_pool)))
return NULL; return NULL;
@@ -165,6 +180,42 @@ static move_t *move_add(pos_t *pos, piece_t piece, square_t from,
return move; return move;
} }
void move_del(struct list_head *ptr)
{
move_t *move = list_entry(ptr, move_t, list);
# ifdef DEBUG_MOVE
log_i(3, "delete move from %c%c to %c%c\n",
FILE2C(GET_F(move->from)), RANK2C(GET_R(move->from)),
FILE2C(GET_F(move->to)), RANK2C(GET_R(move->to)));
# endif
/* TODO: remove move->pos if non null */
if (move->pos) {
pos_clear(move->pos);
}
list_del(ptr);
pool_add(moves_pool, move);
return;
}
int moves_del(pos_t *pos)
{
struct list_head *p_cur, *tmp, *head;
int count = 0;
head = &pos->moves;
list_for_each_safe(p_cur, tmp, head) {
move_del(p_cur);
count++;
}
# ifdef DEBUG_PIECE
log_f(3, "removed=%d\n", count);
# endif
return count;
}
/* TODO: return nmoves */ /* TODO: return nmoves */
static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from, static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from,
square_t to, unsigned char rank7) square_t to, unsigned char rank7)
@@ -217,7 +268,7 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
} }
# ifdef DEBUG_MOVE # ifdef DEBUG_MOVE
log_f(3, "pos:%p turn:%s piece:%d [%s %s] dir:%d at %#04x[%c%c]\n", log_f(2, "pos:%p turn:%s piece:%d [%s %s] dir:%d at %#04x[%c%c]\n",
pos, pos,
IS_WHITE(pos->turn)? "white": "black", IS_WHITE(pos->turn)? "white": "black",
piece, piece,
@@ -464,6 +515,7 @@ int moves_gen(pos_t *pos, bool color, bool doit)
if (doit) if (doit)
pseudo_moves_castle(pos); pseudo_moves_castle(pos);
list_for_each_safe(p_cur, tmp, piece_list) { list_for_each_safe(p_cur, tmp, piece_list) {
piece = list_entry(p_cur, piece_list_t, list); piece = list_entry(p_cur, piece_list_t, list);
if (PIECE(piece->piece) != PAWN) if (PIECE(piece->piece) != PAWN)
pseudo_moves_gen(pos, piece, doit); pseudo_moves_gen(pos, piece, doit);

View File

@@ -19,10 +19,6 @@
#include "pool.h" #include "pool.h"
#include "piece.h" #include "piece.h"
/* move_add() return value when generating
*/
/* move flags /* move flags
*/ */
typedef unsigned char move_flags_t; typedef unsigned char move_flags_t;
@@ -48,14 +44,18 @@ typedef struct move_s {
piece_t promotion; /* promoted piece */ piece_t promotion; /* promoted piece */
move_flags_t flags; move_flags_t flags;
struct list_head list; /* next move */ struct list_head list; /* next move */
struct pos_t *pos; /* resulting position */ struct pos_s *pos; /* resulting position */
} move_t; } move_t;
pool_t *moves_pool_init(); pool_t *moves_pool_init();
void moves_pool_stats();
int move_print(move_t *move, move_flags_t flags); int move_print(move_t *move, move_flags_t flags);
void moves_print(pos_t *move, move_flags_t flags); void moves_print(pos_t *move, move_flags_t flags);
int pseudo_moves_castle(pos_t *pos); int pseudo_moves_castle(pos_t *pos);
void move_del(struct list_head *ptr);
int moves_del(pos_t *pos);
int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit); int pseudo_moves_gen(pos_t *pos, piece_list_t *piece, bool doit);
int pseudo_moves_pawn(pos_t *pos, piece_list_t *piece, bool doit); int pseudo_moves_pawn(pos_t *pos, piece_list_t *piece, bool doit);
int moves_gen(pos_t *pos, bool color, bool doit); int moves_gen(pos_t *pos, bool color, bool doit);

View File

@@ -54,6 +54,12 @@ pool_t *piece_pool_init()
return pieces_pool; return pieces_pool;
} }
void piece_pool_stats()
{
if (pieces_pool)
pool_stats(pieces_pool);
}
static eval_t pieces_values[] = { static eval_t pieces_values[] = {
[PAWN] = PAWN_VALUE, [PAWN] = PAWN_VALUE,
[KNIGHT] = KNIGHT_VALUE, [KNIGHT] = KNIGHT_VALUE,
@@ -85,6 +91,34 @@ piece_list_t *piece_add(pos_t *pos, piece_t piece, square_t square)
return new; return new;
} }
void piece_del(struct list_head *ptr)
{
piece_list_t *piece = list_entry(ptr, piece_list_t, list);
# ifdef DEBUG_PIECE
log_f(3, "piece=%02x square=%02x\n", piece->piece, piece->square);
# endif
list_del(ptr);
pool_add(pieces_pool, piece);
return;
}
int pieces_del(pos_t *pos, short color)
{
struct list_head *p_cur, *tmp, *head;
int count = 0;
head = &pos->pieces[color];
list_for_each_safe(p_cur, tmp, head) {
piece_del(p_cur);
count++;
}
# ifdef DEBUG_PIECE
log_f(3, "color=%d removed=%d\n", color, count);
# endif
return count;
}
#ifdef BIN_piece #ifdef BIN_piece
#include "fen.h" #include "fen.h"
int main(int ac, char**av) int main(int ac, char**av)

View File

@@ -62,6 +62,9 @@ extern struct piece_details {
void piece_list_print(struct list_head *list); void piece_list_print(struct list_head *list);
pool_t *piece_pool_init(); pool_t *piece_pool_init();
void piece_pool_stats();
piece_list_t *piece_add(pos_t *pos, piece_t piece, square_t square); piece_list_t *piece_add(pos_t *pos, piece_t piece, square_t square);
void piece_del(struct list_head *ptr);
int pieces_del(pos_t *pos, short color);
#endif #endif

View File

@@ -19,6 +19,7 @@
#include "chessdefs.h" #include "chessdefs.h"
#include "position.h" #include "position.h"
#include "move.h"
#include "fen.h" #include "fen.h"
#include "piece.h" #include "piece.h"
@@ -149,9 +150,10 @@ pos_t *pos_clear(pos_t *pos)
pos->controlled[BLACK] = 0; pos->controlled[BLACK] = 0;
pos->mobility[WHITE] = 0; pos->mobility[WHITE] = 0;
pos->mobility[BLACK] = 0; pos->mobility[BLACK] = 0;
INIT_LIST_HEAD(&pos->pieces[WHITE]); /* remove pieces / moves */
INIT_LIST_HEAD(&pos->pieces[BLACK]); pieces_del(pos, WHITE);
INIT_LIST_HEAD(&pos->moves); pieces_del(pos, BLACK);
moves_del(pos);
return pos; return pos;
} }
@@ -167,15 +169,10 @@ pos_t *pos_get()
{ {
pos_t *pos = pool_get(pos_pool); pos_t *pos = pool_get(pos_pool);
if (pos) { if (pos) {
//printf("sizeof(board)=%lu\n", sizeof (board_t)); INIT_LIST_HEAD(&pos->pieces[WHITE]);
//pos->board = malloc(sizeof (board_t)*BOARDSIZE); INIT_LIST_HEAD(&pos->pieces[BLACK]);
//printf("board mem: %p-%p\n", pos->board, pos->board+sizeof (board_t)); INIT_LIST_HEAD(&pos->moves);
//if (pos->board)
pos_clear(pos); pos_clear(pos);
//else {
// free(pos);
// pos = NULL;
//}
} }
return pos; return pos;
} }
@@ -207,3 +204,9 @@ pool_t *pos_pool_init()
pos_pool = pool_init("positions", 128, sizeof(pos_t)); pos_pool = pool_init("positions", 128, sizeof(pos_t));
return pos_pool; return pos_pool;
} }
void pos_pool_stats()
{
if (pos_pool)
pool_stats(pos_pool);
}

View File

@@ -45,6 +45,7 @@ pos_t *pos_clear(pos_t *pos);
pos_t *pos_startpos(pos_t *pos); pos_t *pos_startpos(pos_t *pos);
pos_t *pos_create(); pos_t *pos_create();
pool_t *pos_pool_init(); pool_t *pos_pool_init();
void pos_pool_stats();
pos_t *pos_get(); pos_t *pos_get();
pos_t *pos_dup(pos_t *pos); pos_t *pos_dup(pos_t *pos);