rename pos_all_legal() to pos_legal_dup(), new pos_legal()
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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 */
|
||||||
|
50
src/search.c
50
src/search.c
@@ -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;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user