rename pos_all_legal() to pos_legal_dup(), new pos_legal()

This commit is contained in:
2024-04-17 09:13:21 +02:00
parent 8b3202fac0
commit 2505217c70
5 changed files with 118 additions and 72 deletions

View File

@@ -138,24 +138,52 @@ move_t pos_next_legal(const pos_t *pos, movelist_t *movelist, int *start)
} }
/** /**
* pos_all_legal() - get the list of legal moves from pseudo-legal. * pos_legal_dup() - get legal moves from pseudo-legal ones in new list.
* @pos: position * @pos: position
* @movelist: &pseudo-legal movelist_t * @pseudo: &movelist_t pseudo-legal moves list
* @dest: &destination movelist_t * @legal: &movelist_t legal moves
* *
* The pseudo-legal moves must be already calculated before calling this function. * The pseudo-legal moves must be already calculated before calling this function.
* No check is done on @dest limits. * No check is done on @legal limits.
* This function is similar to pos_legal(), but creates a new list for legal moves.
* It should only be used for debug purpose, when we want to keep a copy of
* pseudo-legal moves.
* *
* @Return: @dest * @return: @legal
*/ */
movelist_t *pos_all_legal(const pos_t *pos, movelist_t *movelist, movelist_t *dest) movelist_t *pos_legal_dup(const pos_t *pos, movelist_t *pseudo, movelist_t *legal)
{ {
int tmp = dest->nmoves = 0; int tmp = legal->nmoves = 0;
move_t move; move_t move;
while ((move = pos_next_legal(pos, movelist, &tmp)) != MOVE_NONE) while ((move = pos_next_legal(pos, pseudo, &tmp)) != MOVE_NONE)
dest->move[dest->nmoves++] = move; legal->move[legal->nmoves++] = move;
return dest; return legal;
}
/**
* pos_legal() - get legal moves from pseudo-legal ones in new list.
* @pos: position
* @list: &movelist_t pseudo-legal moves list
*
* The pseudo-legal moves must be already calculated before calling this function.
* @list is replaced by legal moves.
*
* @return: @list
*/
movelist_t *pos_legal(const pos_t *pos, movelist_t *list)
{
move_t *cur = list->move, *last = list->move + list->nmoves;
while (cur < last) {
if (pseudo_is_legal(pos, *cur))
cur++;
else {
*cur = *--last;
}
}
list->nmoves = last - list->move;
return list;
} }
/** /**
@@ -292,7 +320,7 @@ static inline move_t *moves_gen(move_t *moves, square_t from, bitboard_t to_bb)
} }
/** /**
* pos_gen_pseudomoves() - generate position pseudo-legal moves * pos_gen_pseudo() - generate position pseudo-legal moves
* @pos: position * @pos: position
* @movelist: &movelist_t array to store pseudo-moves * @movelist: &movelist_t array to store pseudo-moves
* *
@@ -312,9 +340,9 @@ static inline move_t *moves_gen(move_t *moves, square_t from, bitboard_t to_bb)
* *
* TODO: move code to specific functions (especially castling, pawn push/capture) * TODO: move code to specific functions (especially castling, pawn push/capture)
* *
* @Return: The total number of moves. * @Return: movelist
*/ */
int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist) movelist_t *pos_gen_pseudo(pos_t *pos, movelist_t *movelist)
{ {
color_t us = pos->turn; color_t us = pos->turn;
color_t them = OPPONENT(us); color_t them = OPPONENT(us);
@@ -511,5 +539,7 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
/* TODO: add function per piece, and type, for easier debug /* TODO: add function per piece, and type, for easier debug
*/ */
finish: finish:
return movelist->nmoves = moves - movelist->move; movelist->nmoves = moves - movelist->move;
return movelist;
//return movelist->nmoves = moves - movelist->move;
} }

View File

@@ -23,7 +23,9 @@
bool pseudo_is_legal(const pos_t *pos, const move_t move); bool pseudo_is_legal(const pos_t *pos, const move_t move);
move_t pos_next_legal(const pos_t *pos, movelist_t *movelist, int *start); move_t pos_next_legal(const pos_t *pos, movelist_t *movelist, int *start);
movelist_t *pos_all_legal(const pos_t *pos, movelist_t *movelist, movelist_t *dest); movelist_t *pos_legal_dup(const pos_t *pos, movelist_t *pseudo, movelist_t *legal);
int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist); movelist_t *pos_legal(const pos_t *pos, movelist_t *list);
movelist_t *pos_gen_pseudo(pos_t *pos, movelist_t *movelist);
#endif /* MOVEGEN_H */ #endif /* MOVEGEN_H */

View File

@@ -33,8 +33,8 @@
* This version uses the algorithm: * This version uses the algorithm:
* if last depth * if last depth
* return 1; * return 1;
* gen pseudo-legal moves * gen legal moves
* loop for each legal move * loop for legal move
* do-move * do-move
* perft (depth -1) * perft (depth -1)
* undo-move * undo-move
@@ -43,30 +43,33 @@
*/ */
u64 perft(pos_t *pos, int depth, int ply) u64 perft(pos_t *pos, int depth, int ply)
{ {
int subnodes, movetmp = 0; int subnodes;
u64 nodes = 0; u64 nodes = 0;
movelist_t pseudo; movelist_t movelist;
move_t move; move_t *move, *last;
state_t state; state_t state;
if (depth == 0) movelist.nmoves = 0;
return 1;
pseudo.nmoves = 0;
pos_set_checkers_pinners_blockers(pos); pos_set_checkers_pinners_blockers(pos);
state = pos->state; state = pos->state;
pos_gen_pseudomoves(pos, &pseudo); pos_legal(pos, pos_gen_pseudo(pos, &movelist));
while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) { last = movelist.move + movelist.nmoves;
move_do(pos, move); for (move = movelist.move; move < last; ++move) {
if (depth == 1) {
nodes++;
} else {
move_do(pos, *move);
subnodes = perft(pos, depth - 1, ply + 1); subnodes = perft(pos, depth - 1, ply + 1);
if (ply == 1) { if (ply == 1) {
char movestr[8]; char movestr[8];
printf("%s: %d\n", move_str(movestr, move, 0), subnodes); printf("%s: %d\n", move_str(movestr, *move, 0), subnodes);
} }
nodes += subnodes; nodes += subnodes;
move_undo(pos, move); move_undo(pos, *move);
pos->state = state; pos->state = state;
} }
}
if (ply == 1) if (ply == 1)
printf("Total: %lu\n", nodes); printf("Total: %lu\n", nodes);
@@ -82,6 +85,15 @@ u64 perft(pos_t *pos, int depth, int ply)
* Run perft on a position. This function displays the available moves at @depth * Run perft on a position. This function displays the available moves at @depth
* level for each possible first move, and the total of moves. * level for each possible first move, and the total of moves.
* *
* This version uses the algorithm:
* if last depth
* return 1;
* gen pseudo-legal moves
* loop for each legal move in pseudo-legal list
* do-move
* perft (depth -1)
* undo-move
*
* @return: total moves found at @depth level. * @return: total moves found at @depth level.
*/ */
u64 perft_new_pinners(pos_t *pos, int depth, int ply) u64 perft_new_pinners(pos_t *pos, int depth, int ply)
@@ -92,14 +104,15 @@ u64 perft_new_pinners(pos_t *pos, int depth, int ply)
move_t move; move_t move;
state_t state; state_t state;
if (depth == 0)
return 1;
pseudo.nmoves = 0; pseudo.nmoves = 0;
pos_set_checkers_pinners_blockers(pos); pos_set_checkers_pinners_blockers(pos);
state = pos->state; state = pos->state;
pos_gen_pseudomoves(pos, &pseudo); pos_gen_pseudo(pos, &pseudo);
while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) { while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) {
if (depth == 1) {
nodes++;
} else {
move_do(pos, move); move_do(pos, move);
subnodes = perft_new_pinners(pos, depth - 1, ply + 1); subnodes = perft_new_pinners(pos, depth - 1, ply + 1);
if (ply == 1) { if (ply == 1) {
@@ -110,6 +123,7 @@ u64 perft_new_pinners(pos_t *pos, int depth, int ply)
move_undo(pos, move); move_undo(pos, move);
pos->state = state; pos->state = state;
} }
}
if (ply == 1) if (ply == 1)
printf("Total: %lu\n", nodes); printf("Total: %lu\n", nodes);
@@ -314,7 +328,7 @@ u64 perft_new_pinners(pos_t *pos, int depth, int ply)
* @return: The @pos negamax evaluation. * @return: The @pos negamax evaluation.
*/ */
/*int ab_negamax(pos_t *pos, int alpha, int beta, int depth) /*int ab_negamax(pos_t *pos, int alpha, int beta, int depth)
{ {
move_t *move; move_t *move;
pos_t *newpos; pos_t *newpos;
eval_t best = EVAL_MIN, score; eval_t best = EVAL_MIN, score;
@@ -333,5 +347,5 @@ u64 perft_new_pinners(pos_t *pos, int depth, int ply)
alpha = score; // alpha acts like max in MiniMax alpha = score; // alpha acts like max in MiniMax
} }
return alpha; return alpha;
} }
*/ */

View File

@@ -47,7 +47,7 @@ int main(int __unused ac, __unused char**av)
pos->checkers = pos_checkers(pos, pos->turn); pos->checkers = pos_checkers(pos, pos->turn);
pos_set_pinners_blockers(pos); pos_set_pinners_blockers(pos);
pos_gen_pseudomoves(pos, &pseudo); pos_gen_pseudo(pos, &pseudo);
savepos = pos_dup(pos); savepos = pos_dup(pos);
state_t state = pos->state; state_t state = pos->state;

View File

@@ -216,7 +216,7 @@ int main(int __unused ac, __unused char**av)
FILE *outfd; FILE *outfd;
char *fen; char *fen;
pos_t *pos, *fishpos = pos_new(); pos_t *pos, *fishpos = pos_new();
movelist_t pseudo, legal, fishmoves; movelist_t pseudo, fishmoves;
//bitboard_t wrong = 0x5088000040, tmp, loop; //bitboard_t wrong = 0x5088000040, tmp, loop;
//bit_for_each64(loop, tmp, ) //bit_for_each64(loop, tmp, )
//printf("fishpos 1=%p\n", fishpos); //printf("fishpos 1=%p\n", fishpos);
@@ -239,9 +239,9 @@ int main(int __unused ac, __unused char**av)
send_stockfish_fen(outfd, fishpos, &fishmoves, fen); send_stockfish_fen(outfd, fishpos, &fishmoves, fen);
pos_set_checkers_pinners_blockers(pos); pos_set_checkers_pinners_blockers(pos);
pos_gen_pseudomoves(pos, &pseudo); pos_gen_pseudo(pos, &pseudo);
//moves_print(&pseudo, 0); //moves_print(&pseudo, 0);
pos_all_legal(pos, &pseudo, &legal); pos_legal(pos, &pseudo);
//moves_print(&legal, 0); //moves_print(&legal, 0);
//printf("Fu "); //printf("Fu ");
@@ -253,7 +253,7 @@ int main(int __unused ac, __unused char**av)
/* sort and print movelists */ /* sort and print movelists */
move_sort_by_sq(&fishmoves); move_sort_by_sq(&fishmoves);
move_sort_by_sq(&legal); move_sort_by_sq(&pseudo);
// printf("\nFs "); // printf("\nFs ");
// moves_print(fishpos, 0); // moves_print(fishpos, 0);
// fflush(stdout); // fflush(stdout);
@@ -262,14 +262,14 @@ int main(int __unused ac, __unused char**av)
// fflush(stdout); // fflush(stdout);
/* compare movelists */ /* compare movelists */
if (!movelists_equal(&fishmoves, &legal)) { if (!movelists_equal(&fishmoves, &pseudo)) {
pos_print(pos); pos_print(pos);
printf("F: "); printf("F: ");
moves_print(&fishmoves, 0); moves_print(&fishmoves, 0);
printf("M: "); printf("M: ");
moves_print(&legal, 0); moves_print(&pseudo, 0);
} else { } else {
printf("[%s]: OK (%d Moves)\n", fen, legal.nmoves); printf("[%s]: OK (%d Moves)\n", fen, pseudo.nmoves);
//moves_print(&fishpos->moves, 0); //moves_print(&fishpos->moves, 0);
} }
//compare_moves(&fishpos->moves, &legal); //compare_moves(&fishpos->moves, &legal);