From 6f7a04cc89fdf9db68019be258f6e9bb23dd46c8 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Thu, 6 Jul 2023 12:22:26 +0200 Subject: [PATCH] Add move_do (dup position), remove &board in move struct --- src/brchess.c | 59 ++++++++++++++++++--------- src/move.c | 106 ++++++++++++++++++++++++++++++------------------- src/move.h | 6 +-- src/position.c | 27 ++++++++----- 4 files changed, 125 insertions(+), 73 deletions(-) diff --git a/src/brchess.c b/src/brchess.c index 64b1b0b..1fec805 100644 --- a/src/brchess.c +++ b/src/brchess.c @@ -55,7 +55,7 @@ int do_init(pos_t *, char*); int do_pos(pos_t *, char*); int do_genmoves(pos_t *, char*); int do_prmoves(pos_t *, char*); -int do_prmovepos(pos_t *pos, char *arg); +//int do_prmovepos(pos_t *pos, char *arg); int do_prpieces(pos_t *pos, char *arg); int do_memstats(pos_t *, char*); int do_eval(pos_t *, char*); @@ -72,7 +72,7 @@ COMMAND commands[] = { { "quit", do_quit, "Quit" }, { "genmove", do_genmoves, "Generate move list for " }, { "prmoves", do_prmoves, "Print position move list" }, - { "prmovepos", do_prmovepos, "Print Nth move resulting position" }, +// { "prmovepos", do_prmovepos, "Print Nth move resulting position" }, { "prpieces", do_prpieces, "Print Pieces (from pieces lists)" }, { "memstats", do_memstats, "Generate next move list" }, { "eval", do_eval, "Eval current position" }, @@ -304,23 +304,25 @@ int do_prmoves(pos_t *pos, __unused char *arg) return 1; } -int do_prmovepos(pos_t *pos, char *arg) -{ - struct list_head *p_cur, *tmp; - int movenum = atoi(arg), cur = 0; /* starts with 0 */ - move_t *move; - - log_f(1, "%s\n", arg); - list_for_each_safe(p_cur, tmp, &pos->moves[pos->turn]) { - move = list_entry(p_cur, move_t, list); - if (cur++ == movenum) { - pos_print(move->newpos); - break; - } - } - - return 1; -} +/* + * int do_prmovepos(pos_t *pos, char *arg) + * { + * struct list_head *p_cur, *tmp; + * int movenum = atoi(arg), cur = 0; /\* starts with 0 *\/ + * move_t *move; + * + * log_f(1, "%s\n", arg); + * list_for_each_safe(p_cur, tmp, &pos->moves[pos->turn]) { + * move = list_entry(p_cur, move_t, list); + * if (cur++ == movenum) { + * pos_print(move->newpos); + * break; + * } + * } + * + * return 1; + * } + */ int do_prpieces(pos_t *pos, __unused char *arg) { @@ -339,6 +341,25 @@ int do_memstats(__unused pos_t *pos,__unused char *arg) int do_move(__unused pos_t *pos, __unused char *arg) { + int i = 1, nmove = atoi(arg); + move_t *move; + pos_t *newpos; + + if (list_empty(&pos->moves[pos->turn])) { + log_f(1, "No moves list.\n"); + return 0; + } + list_for_each_entry(move, &pos->moves[pos->turn], list) { + if (i == nmove) + goto doit; + i++; + } + log_f(1, "Invalid <%d> move, should be <1-%d>.\n", nmove, i); + return 0; +doit: + newpos = move_do(pos, move); + pos_print(newpos); + return 1; } diff --git a/src/move.c b/src/move.c index ffe8da7..975506d 100644 --- a/src/move.c +++ b/src/move.c @@ -172,7 +172,7 @@ static move_t *move_add(pos_t *pos, piece_t piece, square_t from, move->to = to; move->taken = board[to].piece; move->flags = M_NORMAL; - move->newpos = pos_dup(pos); + //move->newpos = pos_dup(pos); //newpos = move->newpos; //SET_COLOR(newpos->turn, OPPONENT(move->piece)); //newpos->turn = OPPONENT(newpos->turn); @@ -216,9 +216,9 @@ void move_del(struct list_head *ptr) # endif /* TODO: remove move->pos if non null */ - if (move->newpos) { - pos_clear(move->newpos); - } + //if (move->newpos) { + // pos_clear(move->newpos); + // } list_del(ptr); pool_add(moves_pool, move); return; @@ -250,7 +250,7 @@ static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from, move_t *move; piece_t promote; unsigned char color = COLOR(piece); - pos_t *newpos; + //pos_t *newpos; //if (color != pos->turn) // return NULL; @@ -260,17 +260,17 @@ static move_t *move_pawn_add(pos_t *pos, piece_t piece, square_t from, move->flags |= M_PROMOTION; move->promotion = promote | color; /* fix piece on board and piece list */ - newpos = move->newpos; - newpos->board[to].piece = promote|color; - newpos->board[to].s_piece->piece = piece|color; - newpos->board[to].s_piece->value = piece_details[PIECE(piece)].value; + //newpos = move->newpos; + //newpos->board[to].piece = promote|color; + //newpos->board[to].s_piece->piece = piece|color; + //newpos->board[to].s_piece->value = piece_details[PIECE(piece)].value; //piece_del(&newpos->board[from].s_piece); } } } else { move = move_add(pos, piece, from, to); - newpos = move->newpos; + //newpos = move->newpos; } return move; @@ -362,9 +362,9 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit) move->taken = taken; /* remove taken pawn from board */ - piece_del(&move->newpos->board[t_square].s_piece->list); - move->newpos->board[t_square].piece = 0; - move->newpos->board[t_square].s_piece = NULL; + //piece_del(&move->newpos->board[t_square].s_piece->list); + //move->newpos->board[t_square].piece = 0; + //move->newpos->board[t_square].s_piece = NULL; pos->mobility[color]++; count++; @@ -413,7 +413,7 @@ int pseudo_moves_castle(pos_t *pos, bool color, bool doit) struct can_castle *can_castle; bitboard_t controlled; bitboard_t occupied = pos->occupied[WHITE] | pos->occupied[BLACK]; - pos_t *newpos; + //pos_t *newpos; # ifdef DEBUG_MOVE log_f(2, "pos:%p turn:%s color:%s\n", @@ -454,14 +454,14 @@ int pseudo_moves_castle(pos_t *pos, bool color, bool doit) move = move_add(pos, board[SQ88(4, rank1)].piece, SQ88(4, rank1), SQ88(6, rank1)); if (move) { - newpos = move->newpos; + //newpos = move->newpos; move->flags |= M_CASTLE_K; /* move King rook to column F */ - newpos->board[SQ88(5, rank1)] = newpos->board[SQ88(7, rank1)]; - SETF88(newpos->board[SQ88(5, rank1)].s_piece->square, 5); - newpos->board[SQ88(7, rank1)].piece = 0; - newpos->board[SQ88(7, rank1)].s_piece = NULL; + //newpos->board[SQ88(5, rank1)] = newpos->board[SQ88(7, rank1)]; + //SETF88(newpos->board[SQ88(5, rank1)].s_piece->square, 5); + //newpos->board[SQ88(7, rank1)].piece = 0; + //newpos->board[SQ88(7, rank1)].s_piece = NULL; } } @@ -487,13 +487,13 @@ next: move = move_add(pos, board[SQ88(4, rank1)].piece, SQ88(4, rank1), SQ88(2, rank1)); if (move) { - newpos = move->newpos; + //newpos = move->newpos; move->flags |= M_CASTLE_Q; /* move King rook to column F */ - newpos->board[SQ88(3, rank1)] = newpos->board[SQ88(0, rank1)]; - SETF88(newpos->board[SQ88(3, rank1)].s_piece->square, 3); - newpos->board[SQ88(0, rank1)].piece = 0; - newpos->board[SQ88(0, rank1)].s_piece = NULL; + //newpos->board[SQ88(3, rank1)] = newpos->board[SQ88(0, rank1)]; + //SETF88(newpos->board[SQ88(3, rank1)].s_piece->square, 3); + //newpos->board[SQ88(0, rank1)].piece = 0; + //newpos->board[SQ88(0, rank1)].s_piece = NULL; } } } @@ -622,42 +622,66 @@ int moves_gen(pos_t *pos, bool color, bool doit) return count; } -/* note: for now, a new pos is generated */ -struct pos *move_do(pos_t *pos, move_t *move) +/** + * move_do() - execute move in a duplicated position. + * @pos: &pos_t struct on which move will be applied + * @move: &move_t struct to apply + * + */ +pos_t *move_do(pos_t *pos, move_t *move) { # ifdef DEBUG_MOVE log_f(3, "++++++++++"); move_print(move, 0); + log(3, "\n"); # endif - pos_t *newpos = pos_dup(pos); + + pos_t *new = pos_dup(pos); piece_t piece = move->piece; int color = COLOR(piece); square_t from = move->from, to = move->to; - /* todo: en passant + /* todo: en passant, castle */ - SET_COLOR(pos->turn, OPPONENT(color)); /* pos color */ + SET_COLOR(new->turn, OPPONENT(color)); /* pos color */ if (move->taken || PIECE(piece) == PAWN) /* 50 moves */ - newpos->clock_50 = 0; + new->clock_50 = 0; else - newpos->clock_50++; - if (move->taken) { /* */ - piece_del(&newpos->board[to].s_piece->list); - newpos->occupied[OPPONENT(color)] ^= SQ88_2_BB(to); + new->clock_50++; + + if (move->taken) { /* capture */ + if (!(move->flags & M_EN_PASSANT)) { + piece_del(&new->board[to].s_piece->list); + new->board[to].piece = 0; + new->occupied[OPPONENT(color)] ^= SQ88_2_BB(to); + new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(to); + } else { + unsigned char ep_file = F88(pos->en_passant); + square_t ep_grab = color == WHITE ? SQ88(ep_file, 4): SQ88(ep_file, 3); + log_f(1, "en-passant=%d,%d\n", ep_file, color == WHITE ? 4 : 3); + piece_del(&new->board[ep_grab].s_piece->list); + new->board[ep_grab].piece = 0; + new->occupied[OPPONENT(color)] ^= SQ88_2_BB(ep_grab); + new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(ep_grab); + } + } - newpos->board[to] = newpos->board[from]; + + new->board[to] = new->board[from]; /* fix dest square */ - newpos->board[to].s_piece->square = to; + new->board[to].s_piece->square = to; /* replace old occupied bitboard by new one */ - newpos->occupied[color] ^= SQ88_2_BB(from); - newpos->occupied[color] |= SQ88_2_BB(to); + new->occupied[color] ^= SQ88_2_BB(from); + new->occupied[color] |= SQ88_2_BB(to); + new->bb[color][PIECETOBB(piece)] ^= SQ88_2_BB(from); + new->bb[color][PIECETOBB(piece)] |= SQ88_2_BB(to); /* always make "from" square empty */ - newpos->board[from].piece = 0; - newpos->board[from].s_piece = NULL; + new->board[from].piece = 0; + new->board[from].s_piece = NULL; - return 0; + return new; } void move_undo(pos_t *pos, __unused move_t *move) diff --git a/src/move.h b/src/move.h index 8cfe9f7..cbd973b 100644 --- a/src/move.h +++ b/src/move.h @@ -40,11 +40,11 @@ typedef unsigned char move_flags_t; typedef struct move_s { piece_t piece; square_t from, to; - piece_t taken; /* removed piece */ + piece_t taken; /* captured piece */ piece_t promotion; /* promoted piece */ move_flags_t flags; struct list_head list; /* next move */ - struct pos_s *newpos; /* resulting position */ + //struct pos_s *newpos; /* resulting position */ } move_t; pool_t *moves_pool_init(); @@ -60,7 +60,7 @@ 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 moves_gen(pos_t *pos, bool color, bool doit); -struct pos *move_do(pos_t *pos, move_t *move); +pos_t *move_do(pos_t *pos, move_t *move); void move_undo(pos_t *pos, move_t *move); #endif /* MODE_H */ diff --git a/src/position.c b/src/position.c index a40845c..60c7b68 100644 --- a/src/position.c +++ b/src/position.c @@ -185,10 +185,20 @@ pos_t *pos_get() return pos; } -/* TODO: merge with pos_get - NULL for init, non null for duplicate */ +/** + * pos_dup() - duplicate a position. + * @pos: &position to duplicate. + * + * New position is the same as source one, with duplicated pieces list + * and empty moves list. + * + * @return: The new position. + * + * TODO: merge with pos_get - NULL for init, non null for duplicate + */ pos_t *pos_dup(pos_t *pos) { - struct list_head *p_cur, *tmp, *piece_list; + struct list_head *p_cur, *piece_list; piece_list_t *oldpiece; board_t *board; pos_t *new = pool_get(pos_pool); @@ -196,20 +206,17 @@ pos_t *pos_dup(pos_t *pos) if (new) { board = new->board; *new = *pos; - INIT_LIST_HEAD(&new->pieces[WHITE]); - INIT_LIST_HEAD(&new->pieces[BLACK]); - INIT_LIST_HEAD(&new->moves[WHITE]); - INIT_LIST_HEAD(&new->moves[BLACK]); - - /* duplicate piece list */ for (int color=0; color<2; ++color) { + INIT_LIST_HEAD(&new->pieces[color]); + INIT_LIST_HEAD(&new->moves[color]); + + /* duplicate piece list */ piece_list = &pos->pieces[color]; /* white/black piece list */ - list_for_each_safe(p_cur, tmp, piece_list) { + list_for_each(p_cur, piece_list) { oldpiece = list_entry(p_cur, piece_list_t, list); board[oldpiece->square].s_piece = piece_add(new, oldpiece->piece, oldpiece->square); - } } }