Improve move gen, delete ling pos, 3 steps moves generation

This commit is contained in:
2023-07-07 02:21:14 +02:00
parent 6f7a04cc89
commit 183e9ef2be
7 changed files with 149 additions and 94 deletions

View File

@@ -62,7 +62,7 @@ void moves_pool_stats()
pool_stats(moves_pool);
}
int move_print(move_t *move, move_flags_t flags)
int move_print(int movenum, move_t *move, move_flags_t flags)
{
if (flags & M_PR_CAPT && !(move->flags & M_CAPTURE)) {
# ifdef DEBUG_MOVE
@@ -76,6 +76,8 @@ int move_print(move_t *move, move_flags_t flags)
# endif
return 0;
}
if (flags & M_PR_NUM)
printf("%d:", movenum);
if (move->flags & M_CASTLE_K) {
printf("O-O");
goto end;
@@ -110,26 +112,30 @@ void moves_print(pos_t *pos, move_flags_t flags)
{
struct list_head *p_cur, *tmp;
move_t *move;
move_flags_t details = flags & M_PR_LONG;
//move_flags_t details = flags & M_PR_LONG;
int movenum;
for (int color=WHITE; color <= BLACK; ++color) {
int verif = 0;
printf("%s pseudo-moves:\n\t", color == WHITE? "White": "Black");
if (! (flags & M_PR_SEPARATE)) {
movenum = 1;
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
move = list_entry(p_cur, move_t, list);
verif += move_print(move, details);
verif += move_print(movenum++, move, flags);
}
} else {
printf("captures: ");
movenum = 1;
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
move = list_entry(p_cur, move_t, list);
verif += move_print(move, details | M_PR_CAPT);
verif += move_print(movenum++, move, flags | M_PR_CAPT);
}
movenum = 1;
printf("\n\tothers : ");
list_for_each_safe(p_cur, tmp, &pos->moves[color]) {
move = list_entry(p_cur, move_t, list);
verif += move_print(move, details | M_PR_NCAPT);
verif += move_print(movenum++, move, flags | M_PR_NCAPT);
}
}
printf("\n\tTotal moves = %d mobility=%u\n", verif, pos->mobility[color]);
@@ -250,28 +256,16 @@ 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;
//if (color != pos->turn)
// return NULL;
if (R88(from) == rank7) { /* promotion */
for (promote = QUEEN; promote > PAWN; promote >>= 1) {
if ((move = move_add(pos, piece, from, to))) {
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;
//piece_del(&newpos->board[from].s_piece);
}
}
} else {
move = move_add(pos, piece, from, to);
//newpos = move->newpos;
}
return move;
}
@@ -360,12 +354,6 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
move = move_pawn_add(pos, piece | color , square, pos->en_passant, rank7);
move->flags |= M_EN_PASSANT | M_CAPTURE;
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;
pos->mobility[color]++;
count++;
}
@@ -403,9 +391,8 @@ int pseudo_moves_pawn(pos_t *pos, piece_list_t *ppiece, bool doit)
return count;
}
int pseudo_moves_castle(pos_t *pos, bool color, bool doit)
int pseudo_moves_castle(pos_t *pos, bool color, bool doit, bool doking)
{
//unsigned char color = pos->turn;
board_t *board = pos->board;
unsigned char rank1, castle_K, castle_Q;
move_t *move = NULL;
@@ -448,22 +435,15 @@ int pseudo_moves_castle(pos_t *pos, bool color, bool doit)
# endif
goto next;
}
pos->mobility[color]++;
count++;
if (doking) {
pos->mobility[color]++;
count++;
}
if (doit) {
move = move_add(pos, board[SQ88(4, rank1)].piece,
SQ88(4, rank1), SQ88(6, rank1));
if (move) {
//newpos = move->newpos;
if (move)
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;
}
}
}
@@ -481,29 +461,33 @@ next:
# endif
goto end;
}
pos->mobility[color]++;
count++;
if (doking) {
pos->mobility[color]++;
count++;
}
if (doit) {
move = move_add(pos, board[SQ88(4, rank1)].piece,
SQ88(4, rank1), SQ88(2, rank1));
if (move) {
//newpos = move->newpos;
if (move)
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;
}
}
}
end:
return count;
}
/* general rule moves for non pawn pieces
/**
* pseudo_moves_gen() - general move generation for non pawn pieces
* @pos: &position
* @ppiece: &piece_list structure pointer
* @doit: add move to moves list
* @doking: count king moves
*
* Calculate all possible moves for @ppiece.
* If @doit is true, add moves to @pos' moves list.
* If @doking is true, account king moves (incl. castle) to mobility.
*/
int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit, bool doking)
{
piece_t piece = PIECE(ppiece->piece);
unsigned char color = COLOR(ppiece->piece);
@@ -569,9 +553,10 @@ int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
}
/* we are sure the move is valid : we create move */
//log_f(2, "piece mobility\n");
pos->mobility[color]++;
count++;
if (piece != KING || doking) {
pos->mobility[color]++;
count++;
}
if (doit) {
//move = move_add(pos, ppiece->piece, square, new);
move_add(pos, ppiece->piece, square, new);
@@ -596,7 +581,18 @@ int pseudo_moves_gen(pos_t *pos, piece_list_t *ppiece, bool doit)
return count;
}
int moves_gen(pos_t *pos, bool color, bool doit)
/**
* moves_gen() - move generation for one color
* @pos: &position
* @color: side
* @doit: add move to moves list
* @doking: count king moves
*
* Calculate all possible moves for @color.
* If @doit is true, add moves to @pos' moves list.
* If @doking is true, account king moves (incl. castle) to mobility.
*/
int moves_gen(pos_t *pos, bool color, bool doit, bool doking)
{
struct list_head *p_cur, *tmp, *piece_list;
piece_list_t *piece;
@@ -609,11 +605,11 @@ int moves_gen(pos_t *pos, bool color, bool doit)
pos->mobility[color] = 0;
pos->controlled[color] = 0;
count += pseudo_moves_castle(pos, color, doit);
count += pseudo_moves_castle(pos, color, doit, doking);
list_for_each_safe(p_cur, tmp, piece_list) {
piece = list_entry(p_cur, piece_list_t, list);
if (PIECE(piece->piece) != PAWN)
count += pseudo_moves_gen(pos, piece, doit);
count += pseudo_moves_gen(pos, piece, doit, doking);
else
count += pseudo_moves_pawn(pos, piece, doit);
@@ -622,6 +618,40 @@ int moves_gen(pos_t *pos, bool color, bool doit)
return count;
}
/**
* moves_gen_king_moves() - adjust king mobility
* @pos: &position
* @color: king color
* @doit: add move to moves list
*
* Compute the number of king moves (incl. castle), after opponent controlled
* are known.
* If @doit is true, add moves to @pos' moves list.
*
* @return: The number of possible king moves.
*/
int moves_gen_king_moves(pos_t *pos, bool color, bool doit)
{
int count = 0;
piece_list_t *king = list_first_entry(&pos->pieces[color], piece_list_t, list);
count = pseudo_moves_castle(pos, king, doit, true);
count += pseudo_moves_gen(pos, king, doit, true);
return count;
}
/**
* moves_gen_all() - calculate all moves
* @pos: &position
*
* Compute pseudo moves for both sides.
*/
void moves_gen_all(pos_t *pos)
{
moves_gen(pos, OPPONENT(pos->turn), false, false);
moves_gen(pos, pos->turn, false, true);
moves_gen_king_moves(pos, OPPONENT(pos->turn), true);
}
/**
* move_do() - execute move in a duplicated position.
* @pos: &pos_t struct on which move will be applied
@@ -632,7 +662,7 @@ pos_t *move_do(pos_t *pos, move_t *move)
{
# ifdef DEBUG_MOVE
log_f(3, "++++++++++");
move_print(move, 0);
move_print(0, move, 0);
log(3, "\n");
# endif
@@ -650,14 +680,14 @@ pos_t *move_do(pos_t *pos, move_t *move)
else
new->clock_50++;
if (move->taken) { /* capture */
if (move->flags & M_CAPTURE) { /* 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);
uchar 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);
@@ -666,6 +696,30 @@ pos_t *move_do(pos_t *pos, move_t *move)
new->bb[OPPONENT(color)][PIECETOBB(piece)] ^= SQ88_2_BB(ep_grab);
}
} else if (move->flags & M_CASTLE_Q) {
uchar row = R88(from);
square_t rook_from = SQ88(0, row);
square_t rook_to = SQ88(3, row);
new->board[rook_to] = new->board[rook_from];
new->board[rook_to].s_piece->square = rook_to;
new->occupied[color] ^= SQ88_2_BB(rook_from);
new->occupied[color] |= SQ88_2_BB(rook_to);
new->bb[color][PIECETOBB(BB_ROOK)] ^= SQ88_2_BB(rook_from);
new->bb[color][PIECETOBB(BB_ROOK)] |= SQ88_2_BB(rook_to);
new->board[rook_from].piece = 0;
new->board[rook_from].s_piece = NULL;
} else if (move->flags & M_CASTLE_K) {
uchar row = R88(from);
square_t rook_from = SQ88(7, row);
square_t rook_to = SQ88(5, row);
new->board[rook_to] = new->board[rook_from];
new->board[rook_to].s_piece->square = rook_to;
new->occupied[color] ^= SQ88_2_BB(rook_from);
new->occupied[color] |= SQ88_2_BB(rook_to);
new->bb[color][PIECETOBB(BB_ROOK)] ^= SQ88_2_BB(rook_from);
new->bb[color][PIECETOBB(BB_ROOK)] |= SQ88_2_BB(rook_to);
new->board[rook_from].piece = 0;
new->board[rook_from].s_piece = NULL;
}
new->board[to] = new->board[from];
@@ -708,8 +762,7 @@ int main(int ac, char**av)
fen2pos(pos, av[1]);
}
//printf("turn = %d opponent = %d\n", pos->turn, OPPONENT(pos->turn));
moves_gen(pos, WHITE, false);
moves_gen(pos, BLACK, false);
moves_gen_all(pos);
pos_print(pos);
pos_pieces_print(pos);
moves_print(pos, M_PR_SEPARATE);