movegen: don't separate promotions, perft: loop uses next_legal()
This commit is contained in:
@@ -192,7 +192,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
|
|
||||||
bitboard_t movebits, from_pawns;
|
bitboard_t movebits, from_pawns;
|
||||||
bitboard_t tmp1, tmp2;
|
bitboard_t tmp1, tmp2;
|
||||||
|
|
||||||
move_t *moves = movelist->move;
|
move_t *moves = movelist->move;
|
||||||
int *nmoves = &movelist->nmoves;
|
int *nmoves = &movelist->nmoves;
|
||||||
int from, to;
|
int from, to;
|
||||||
@@ -223,7 +222,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bit_for_each64(from, tmp1, pos->bb[us][ROOK] | pos->bb[us][QUEEN]) {
|
bit_for_each64(from, tmp1, pos->bb[us][ROOK] | pos->bb[us][QUEEN]) {
|
||||||
// printf("rook=%d/%s\n", from, sq_to_string(from));
|
|
||||||
movebits = hyperbola_rook_moves(occ, from) & not_my_pieces;
|
movebits = hyperbola_rook_moves(occ, from) & not_my_pieces;
|
||||||
bit_for_each64(to, tmp2, movebits & empty) {
|
bit_for_each64(to, tmp2, movebits & empty) {
|
||||||
moves[(*nmoves)++] = move_make(from, to);
|
moves[(*nmoves)++] = move_make(from, to);
|
||||||
@@ -245,16 +243,23 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: relative rank and files */
|
/* pawn: relative rank and files */
|
||||||
bitboard_t rel_rank7 = bb_rel_rank(RANK_7, us);
|
bitboard_t rel_rank8 = bb_rel_rank(RANK_8, us);
|
||||||
bitboard_t rel_rank3 = bb_rel_rank(RANK_3, us);
|
bitboard_t rel_rank3 = bb_rel_rank(RANK_3, us);
|
||||||
|
|
||||||
/* pawn: ranks 2-6 push 1 and 2 squares */
|
/* pawn: ranks 2-6 push 1 and 2 squares */
|
||||||
movebits = pawn_shift_up(pos->bb[us][PAWN] & ~rel_rank7, us) & empty;
|
movebits = pawn_shift_up(pos->bb[us][PAWN], us) & empty;
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
bit_for_each64(to, tmp1, movebits & ~rel_rank8) {
|
||||||
from = pawn_push_up(to, them); /* reverse push */
|
from = pawn_push_up(to, them); /* reverse push */
|
||||||
//printf("push %d->%d %s->%s", from, to, sq_to_string(from), sq_to_string(to));
|
|
||||||
moves[(*nmoves)++] = move_make(from, to);
|
moves[(*nmoves)++] = move_make(from, to);
|
||||||
}
|
}
|
||||||
|
bit_for_each64(to, tmp1, movebits & rel_rank8) { /* promotions */
|
||||||
|
from = pawn_push_up(to, them); /* reverse push */
|
||||||
|
moves[(*nmoves)++] = move_make_promote(from, to, QUEEN);
|
||||||
|
moves[(*nmoves)++] = move_make_promote(from, to, ROOK);
|
||||||
|
moves[(*nmoves)++] = move_make_promote(from, to, BISHOP);
|
||||||
|
moves[(*nmoves)++] = move_make_promote(from, to, KNIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
/* possible second push */
|
/* possible second push */
|
||||||
movebits = pawn_shift_up(movebits & rel_rank3, us) & empty;
|
movebits = pawn_shift_up(movebits & rel_rank3, us) & empty;
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
bit_for_each64(to, tmp1, movebits) {
|
||||||
@@ -262,20 +267,33 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
moves[(*nmoves)++] = move_make_flags(from, to, M_DPUSH);
|
moves[(*nmoves)++] = move_make_flags(from, to, M_DPUSH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: ranks 2-6 captures left */
|
/* pawn: captures left */
|
||||||
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_filea;
|
movebits = pawn_shift_upleft(pos->bb[us][PAWN], us) & enemy_pieces;
|
||||||
movebits = pawn_shift_upleft(from_pawns, us) & enemy_pieces;
|
bit_for_each64(to, tmp1, movebits & ~rel_rank8) {
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
|
||||||
from = pawn_push_upleft(to, them); /* reverse capture */
|
from = pawn_push_upleft(to, them); /* reverse capture */
|
||||||
moves[(*nmoves)++] = move_make_capture(from, to);
|
moves[(*nmoves)++] = move_make_capture(from, to);
|
||||||
}
|
}
|
||||||
/* pawn: ranks 2-6 captures right */
|
bit_for_each64(to, tmp1, movebits & rel_rank8) {
|
||||||
from_pawns = pos->bb[us][PAWN] & ~rel_rank7; // & ~rel_fileh;
|
from = pawn_push_upleft(to, them); /* reverse capture */
|
||||||
movebits = pawn_shift_upright(from_pawns, us) & enemy_pieces;
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, QUEEN);
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, ROOK);
|
||||||
from = pawn_push_upright(to, them);
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP);
|
||||||
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pawn: captures right */
|
||||||
|
movebits = pawn_shift_upright(pos->bb[us][PAWN], us) & enemy_pieces;
|
||||||
|
bit_for_each64(to, tmp1, movebits & ~rel_rank8) {
|
||||||
|
from = pawn_push_upright(to, them); /* reverse capture */
|
||||||
moves[(*nmoves)++] = move_make_capture(from, to);
|
moves[(*nmoves)++] = move_make_capture(from, to);
|
||||||
}
|
}
|
||||||
|
bit_for_each64(to, tmp1, movebits & rel_rank8) {
|
||||||
|
from = pawn_push_upright(to, them); /* reverse capture */
|
||||||
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, QUEEN);
|
||||||
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, ROOK);
|
||||||
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP);
|
||||||
|
moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
/* pawn: en-passant */
|
/* pawn: en-passant */
|
||||||
if ((to = pos->en_passant) != SQUARE_NONE) {
|
if ((to = pos->en_passant) != SQUARE_NONE) {
|
||||||
@@ -287,36 +305,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: rank 7 push */
|
|
||||||
movebits = pawn_shift_up(pos->bb[us][PAWN] & rel_rank7, us) & empty;
|
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
|
||||||
from = pawn_push_up(to, them); /* reverse push */
|
|
||||||
moves[(*nmoves)++] = move_make_promote(from, to, QUEEN);
|
|
||||||
moves[(*nmoves)++] = move_make_promote(from, to, ROOK);
|
|
||||||
moves[(*nmoves)++] = move_make_promote(from, to, BISHOP);
|
|
||||||
moves[(*nmoves)++] = move_make_promote(from, to, KNIGHT);
|
|
||||||
}
|
|
||||||
/* pawn promotion: rank 7 captures left */
|
|
||||||
from_pawns = pos->bb[us][PAWN] & rel_rank7; // & ~rel_filea;
|
|
||||||
movebits = pawn_shift_upleft(from_pawns, us) & enemy_pieces;
|
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
|
||||||
from = pawn_push_upleft(to, them); /* reverse capture */
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, QUEEN);
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, ROOK);
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP);
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT);
|
|
||||||
}
|
|
||||||
/* pawn: rank 7 captures right */
|
|
||||||
from_pawns = pos->bb[us][PAWN] & rel_rank7; // & ~rel_fileh;
|
|
||||||
movebits = pawn_shift_upright(from_pawns, us) & enemy_pieces;
|
|
||||||
bit_for_each64(to, tmp1, movebits) {
|
|
||||||
from = pawn_push_upright(to, them); /* reverse capture */
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, QUEEN);
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, ROOK);
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, BISHOP);
|
|
||||||
moves[(*nmoves)++] = move_make_promote_capture(from, to, KNIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* castle - Attention ! Castling flags are assumed correct
|
/* castle - Attention ! Castling flags are assumed correct
|
||||||
*/
|
*/
|
||||||
if (!pos->checkers) {
|
if (!pos->checkers) {
|
||||||
@@ -342,16 +330,7 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TODO
|
/* TODO: add function per piece, and type, for easier debug
|
||||||
* DONE. pawn ranks 2-6 advance (1 push, + 2 squares for rank 2)
|
|
||||||
* DONE. pawns rank 7 advance + promotions
|
|
||||||
* DONE. pawns ranks 2-6 captures, left and right
|
|
||||||
* DONE. pawns en-passant (with capture)
|
|
||||||
* DONE. pawns rank 7 capture + promotion
|
|
||||||
* DONE. castle
|
|
||||||
*
|
|
||||||
* add function per piece, and type, for easier debug
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
return *nmoves;
|
return *nmoves;
|
||||||
}
|
}
|
||||||
|
39
src/search.c
39
src/search.c
@@ -37,33 +37,31 @@
|
|||||||
*/
|
*/
|
||||||
u64 perft(pos_t *pos, int depth, int ply)
|
u64 perft(pos_t *pos, int depth, int ply)
|
||||||
{
|
{
|
||||||
int subnodes, nmove = 0;
|
int subnodes, movetmp = 0;
|
||||||
u64 nodes = 0;
|
u64 nodes = 0;
|
||||||
movelist_t pseudo = { .nmoves = 0 }, legal = { .nmoves = 0 };
|
movelist_t pseudo = { .nmoves = 0 };
|
||||||
move_t move;
|
move_t move;
|
||||||
|
state_t state;
|
||||||
|
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
return 1;
|
return 1;
|
||||||
pos->checkers = pos_checkers(pos, pos->turn);
|
pos->checkers = pos_checkers(pos, pos->turn);
|
||||||
pos_set_pinners_blockers(pos);
|
pos_set_pinners_blockers(pos);
|
||||||
|
state = pos->state;
|
||||||
|
|
||||||
pos_gen_pseudomoves(pos, &pseudo);
|
pos_gen_pseudomoves(pos, &pseudo);
|
||||||
pos_all_legal(pos, &pseudo, &legal);
|
while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) {
|
||||||
|
move_do(pos, move);
|
||||||
for (nmove = 0; nmove < legal.nmoves; ++nmove ) {
|
|
||||||
//while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) {
|
|
||||||
//printf("depth=%d movetmp=%d\n", depth, movetmp);
|
|
||||||
state_t state;
|
|
||||||
move = legal.move[nmove];
|
|
||||||
move_do(pos, move, &state);
|
|
||||||
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, &state);
|
move_undo(pos, move);
|
||||||
|
pos->state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ply == 1)
|
if (ply == 1)
|
||||||
printf("\nTotal: %lu\n", nodes);
|
printf("\nTotal: %lu\n", nodes);
|
||||||
return nodes;
|
return nodes;
|
||||||
@@ -75,32 +73,31 @@ u64 perft2(pos_t *pos, int depth, int ply)
|
|||||||
u64 nodes = 0;
|
u64 nodes = 0;
|
||||||
movelist_t pseudo = { .nmoves = 0 };
|
movelist_t pseudo = { .nmoves = 0 };
|
||||||
move_t move;
|
move_t move;
|
||||||
|
state_t state;
|
||||||
|
|
||||||
if (is_in_check(pos, OPPONENT(pos->turn)))
|
if (is_in_check(pos, OPPONENT(pos->turn)))
|
||||||
return 0;
|
return 0;
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
return 1;
|
return 1;
|
||||||
pos->checkers = pos_checkers(pos, pos->turn);
|
pos->checkers = pos_checkers(pos, pos->turn);
|
||||||
pos->pinners = pos_king_pinners(pos, pos->turn);
|
pos_set_pinners_blockers(pos);
|
||||||
pos->blockers = pos_king_blockers(pos, pos->turn, pos->pinners);
|
state = pos->state;
|
||||||
|
|
||||||
pos_gen_pseudomoves(pos, &pseudo);
|
pos_gen_pseudomoves(pos, &pseudo);
|
||||||
//pos_all_legal(pos, &pseudo, &legal);
|
|
||||||
|
|
||||||
for (nmove = 0; nmove < pseudo.nmoves; ++nmove ) {
|
for (nmove = 0; nmove < pseudo.nmoves; ++nmove ) {
|
||||||
//while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) {
|
|
||||||
//printf("depth=%d movetmp=%d\n", depth, movetmp);
|
|
||||||
state_t state;
|
|
||||||
move = pseudo.move[nmove];
|
move = pseudo.move[nmove];
|
||||||
move_do(pos, move, &state);
|
move_do(pos, move);
|
||||||
|
//if (!is_in_check(pos, OPPONENT(pos->turn))) {
|
||||||
subnodes = perft2(pos, depth - 1, ply + 1);
|
subnodes = perft2(pos, depth - 1, ply + 1);
|
||||||
|
nodes += subnodes;
|
||||||
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;
|
//}
|
||||||
move_undo(pos, move, &state);
|
move_undo(pos, move);
|
||||||
|
pos->state = state;
|
||||||
}
|
}
|
||||||
if (ply == 1)
|
if (ply == 1)
|
||||||
printf("\nTotal: %lu\n", nodes);
|
printf("\nTotal: %lu\n", nodes);
|
||||||
|
Reference in New Issue
Block a user