Compare commits
4 Commits
movegen-re
...
a6eedebc19
Author | SHA1 | Date | |
---|---|---|---|
a6eedebc19 | |||
ab31274d17 | |||
03da11cc9c | |||
bfed0f417d |
@@ -54,7 +54,6 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state)
|
|||||||
piece_t piece = pos->board[from];
|
piece_t piece = pos->board[from];
|
||||||
piece_t captured = pos->board[to];
|
piece_t captured = pos->board[to];
|
||||||
piece_type_t ptype = PIECE(piece);
|
piece_type_t ptype = PIECE(piece);
|
||||||
color_t pcolor = COLOR(piece);
|
|
||||||
piece_t new_piece = piece;
|
piece_t new_piece = piece;
|
||||||
int up = sq_up(us);
|
int up = sq_up(us);
|
||||||
|
|
||||||
@@ -64,7 +63,7 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state)
|
|||||||
pos->turn = them;
|
pos->turn = them;
|
||||||
pos->captured = captured;
|
pos->captured = captured;
|
||||||
|
|
||||||
bug_on(pcolor != us);
|
bug_on(COLOR(piece) != us);
|
||||||
|
|
||||||
if (is_promotion(move)) {
|
if (is_promotion(move)) {
|
||||||
bug_on(sq_rank(to) != sq_rel_rank(RANK_8, us));
|
bug_on(sq_rank(to) != sq_rel_rank(RANK_8, us));
|
||||||
|
113
src/move-gen.c
113
src/move-gen.c
@@ -230,22 +230,67 @@ static inline __unused move_t *gen_pseudo_king(move_t *moves, square_t from,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* move_make_promotions() - generate all promotions for given pawn and dest.
|
* moves_gen_flags() - generate all moves from square to bitboard (with flags).
|
||||||
|
* @moves: &move_t array where to store moves
|
||||||
|
* @from: square_t piece position
|
||||||
|
* @to_bb: destination bitboard
|
||||||
|
* @flags: flags to apply
|
||||||
|
*
|
||||||
|
* Generate (at address @moves) moves from square @from to each square in @to_bb,
|
||||||
|
* with flags @flags.
|
||||||
|
*
|
||||||
|
* @Return: New @moves.
|
||||||
|
*/
|
||||||
|
static inline __unused move_t *moves_gen_flags(move_t *moves, square_t from, bitboard_t to_bb,
|
||||||
|
__unused move_flags_t flags)
|
||||||
|
{
|
||||||
|
square_t to;
|
||||||
|
while(to_bb) {
|
||||||
|
to = bb_next(&to_bb);
|
||||||
|
*moves++ = move_make_flags(from, to, flags);
|
||||||
|
}
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* move_gen_promotions() - generate all promotions for given pawn and dest.
|
||||||
* @moves: &move_t array where to store moves
|
* @moves: &move_t array where to store moves
|
||||||
* @from: pawn position
|
* @from: pawn position
|
||||||
* @to: promotion square
|
* @to: promotion square
|
||||||
*
|
*
|
||||||
* Generate all (Q/R/B/N) promotion moves on @to for pawn @from.
|
* Generate (at address @moves) all promotion (Q/R/B/N) moves on @to for
|
||||||
|
* pawn @from.
|
||||||
*
|
*
|
||||||
* @Return: New @moves (incremented by 4).
|
* @Return: New @moves.
|
||||||
*/
|
*/
|
||||||
static inline move_t *move_make_promotions(move_t *moves, square_t from, square_t to)
|
static inline move_t *move_gen_promotions(move_t *moves, square_t from, square_t to)
|
||||||
{
|
{
|
||||||
for (piece_type_t pt = QUEEN; pt >= KNIGHT; --pt)
|
for (piece_type_t pt = QUEEN; pt >= KNIGHT; --pt)
|
||||||
*moves++ = move_make_promote(from, to, pt);
|
*moves++ = move_make_promote(from, to, pt);
|
||||||
return moves;
|
return moves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moves_gen() - generate all moves from square to bitboard.
|
||||||
|
* @moves: &move_t array where to store moves
|
||||||
|
* @from: square_t piece position
|
||||||
|
* @to_bb: destination bitboard
|
||||||
|
*
|
||||||
|
* Generate (at address @moves) moves from square @from to each square in @to_bb.
|
||||||
|
*
|
||||||
|
* @Return: New @moves.
|
||||||
|
*/
|
||||||
|
static inline move_t *moves_gen(move_t *moves, square_t from, bitboard_t to_bb)
|
||||||
|
{
|
||||||
|
square_t to;
|
||||||
|
// bb_print(sq_to_string(from), to_bb);
|
||||||
|
while(to_bb) {
|
||||||
|
to = bb_next(&to_bb);
|
||||||
|
*moves++ = move_make(from, to);
|
||||||
|
}
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pos_gen_pseudomoves() - generate position pseudo-legal moves
|
* pos_gen_pseudomoves() - generate position pseudo-legal moves
|
||||||
* @pos: position
|
* @pos: position
|
||||||
@@ -289,12 +334,13 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
|
|
||||||
//*nmoves = 0;
|
//*nmoves = 0;
|
||||||
|
|
||||||
/* king - MUST BE FIRST (we stop if doubler check) */
|
/* king - MUST BE FIRST */
|
||||||
to_bb = bb_king_moves(dest_squares, king);
|
to_bb = bb_king_moves(dest_squares, king);
|
||||||
while(to_bb) {
|
moves = moves_gen(moves, king, to_bb);
|
||||||
to = bb_next(&to_bb);
|
//while(to_bb) {
|
||||||
*moves++ = move_make(king, to);
|
// to = bb_next(&to_bb);
|
||||||
}
|
// *moves++ = move_make(king, to);
|
||||||
|
//}
|
||||||
|
|
||||||
if (bb_multiple(pos->checkers)) /* double check, we stop here */
|
if (bb_multiple(pos->checkers)) /* double check, we stop here */
|
||||||
goto finish;
|
goto finish;
|
||||||
@@ -334,19 +380,21 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
while (from_bb) {
|
while (from_bb) {
|
||||||
from = bb_next(&from_bb);
|
from = bb_next(&from_bb);
|
||||||
to_bb = hyperbola_bishop_moves(occ, from) & dest_squares;
|
to_bb = hyperbola_bishop_moves(occ, from) & dest_squares;
|
||||||
while(to_bb) {
|
moves = moves_gen(moves, from, to_bb);
|
||||||
to = bb_next(&to_bb);
|
//while(to_bb) {
|
||||||
*moves++ = move_make(from, to);
|
// to = bb_next(&to_bb);
|
||||||
}
|
// *moves++ = move_make(from, to);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
from_bb = pos->bb[us][ROOK] | pos->bb[us][QUEEN];
|
from_bb = pos->bb[us][ROOK] | pos->bb[us][QUEEN];
|
||||||
while (from_bb) {
|
while (from_bb) {
|
||||||
from = bb_next(&from_bb);
|
from = bb_next(&from_bb);
|
||||||
to_bb = hyperbola_rook_moves(occ, from) & dest_squares;
|
to_bb = hyperbola_rook_moves(occ, from) & dest_squares;
|
||||||
while(to_bb) {
|
moves = moves_gen(moves, from, to_bb);
|
||||||
to = bb_next(&to_bb);
|
//while(to_bb) {
|
||||||
*moves++ = move_make(from, to);
|
// to = bb_next(&to_bb);
|
||||||
}
|
// *moves++ = move_make(from, to);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* knight */
|
/* knight */
|
||||||
@@ -354,10 +402,11 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
while (from_bb) {
|
while (from_bb) {
|
||||||
from = bb_next(&from_bb);
|
from = bb_next(&from_bb);
|
||||||
to_bb = bb_knight_moves(dest_squares, from);
|
to_bb = bb_knight_moves(dest_squares, from);
|
||||||
while(to_bb) {
|
moves = moves_gen(moves, from, to_bb);
|
||||||
to = bb_next(&to_bb);
|
//while(to_bb) {
|
||||||
*moves++ = move_make(from, to);
|
// to = bb_next(&to_bb);
|
||||||
}
|
// *moves++ = move_make(from, to);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: relative rank and files */
|
/* pawn: relative rank and files */
|
||||||
@@ -374,11 +423,11 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
from = to - shift;
|
from = to - shift;
|
||||||
*moves++ = move_make(from, to);
|
*moves++ = move_make(from, to);
|
||||||
}
|
}
|
||||||
to_bb = tmp_bb & rel_rank8 & dest_squares; /* promotions */
|
to_bb = tmp_bb & rel_rank8 & dest_squares; /* promotions */
|
||||||
while(to_bb) {
|
while(to_bb) {
|
||||||
to = bb_next(&to_bb);
|
to = bb_next(&to_bb);
|
||||||
from = to - shift;
|
from = to - shift;
|
||||||
moves = move_make_promotions(moves, from, to);
|
moves = move_gen_promotions(moves, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* possible second push */
|
/* possible second push */
|
||||||
@@ -428,7 +477,7 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
while (to_bb) {
|
while (to_bb) {
|
||||||
to = bb_next(&to_bb);
|
to = bb_next(&to_bb);
|
||||||
from = to - shift;
|
from = to - shift;
|
||||||
moves = move_make_promotions(moves, from, to);
|
moves = move_gen_promotions(moves, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: captures right */
|
/* pawn: captures right */
|
||||||
@@ -445,7 +494,7 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
while (to_bb) {
|
while (to_bb) {
|
||||||
to = bb_next(&to_bb);
|
to = bb_next(&to_bb);
|
||||||
from = to - shift;
|
from = to - shift;
|
||||||
moves = move_make_promotions(moves, from, to);
|
moves = move_gen_promotions(moves, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pawn: en-passant
|
/* pawn: en-passant
|
||||||
@@ -458,20 +507,6 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
|||||||
*moves++ = move_make_enpassant(from, to);
|
*moves++ = move_make_enpassant(from, to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* to_bb = mask(to);
|
|
||||||
* /\* if e.p not on file H, we may add an e.p move to "up-left" *\/
|
|
||||||
* filter = ~bb_rel_file(FILE_A, us);
|
|
||||||
* shift = sq_upleft(us);
|
|
||||||
* if (bb_shift(pos->bb[us][PAWN] & filter, shift) & to_bb)
|
|
||||||
* *moves++ = move_make_enpassant(to - shift, to);
|
|
||||||
*
|
|
||||||
* filter = ~bb_rel_file(FILE_H, us);
|
|
||||||
* shift = sq_upright(us);
|
|
||||||
* if (bb_shift(pos->bb[us][PAWN] & filter, shift) & to_bb)
|
|
||||||
* *moves++ = move_make_enpassant(to - shift, to);
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO: add function per piece, and type, for easier debug
|
/* TODO: add function per piece, and type, for easier debug
|
||||||
*/
|
*/
|
||||||
|
@@ -101,7 +101,8 @@ static inline move_t move_make(square_t from, square_t to)
|
|||||||
|
|
||||||
static inline move_t move_make_flags(square_t from, square_t to, move_flags_t flags)
|
static inline move_t move_make_flags(square_t from, square_t to, move_flags_t flags)
|
||||||
{
|
{
|
||||||
return move_set_flags(move_make(from, to), flags);
|
return (to << M_OFF_TO) | from | flags;
|
||||||
|
//move_set_flags(move_make(from, to), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline move_t move_make_capture(square_t from, square_t to)
|
static inline move_t move_make_capture(square_t from, square_t to)
|
||||||
|
@@ -120,50 +120,29 @@ bool pos_cmp(__unused const pos_t *pos1, __unused const pos_t *pos2)
|
|||||||
{
|
{
|
||||||
#define _cmpf(a) (pos1->a != pos2->a)
|
#define _cmpf(a) (pos1->a != pos2->a)
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (warn_on(_cmpf(node_count)))
|
|
||||||
goto end;
|
if (_cmpf(node_count) || _cmpf(turn))
|
||||||
if (warn_on(_cmpf(turn)))
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* move_do/undo position state */
|
/* move_do/undo position state */
|
||||||
if (warn_on(_cmpf(en_passant)))
|
if (_cmpf(en_passant) || _cmpf(castle) ||
|
||||||
|
_cmpf(clock_50) || _cmpf(plycount))
|
||||||
goto end;
|
goto end;
|
||||||
if (warn_on(_cmpf(castle)))
|
|
||||||
goto end;
|
|
||||||
if (warn_on(_cmpf(clock_50)))
|
|
||||||
goto end;
|
|
||||||
if (warn_on(_cmpf(plycount)))
|
|
||||||
goto end;
|
|
||||||
//if (warn_on(_cmpf(captured)))
|
|
||||||
// goto end;
|
|
||||||
|
|
||||||
for (square_t sq = A1; sq <= H8; ++sq)
|
for (square_t sq = A1; sq <= H8; ++sq)
|
||||||
if (warn_on(_cmpf(board[sq])))
|
if (_cmpf(board[sq]))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
for (color_t color = WHITE; color <= BLACK; ++color) {
|
for (color_t color = WHITE; color <= BLACK; ++color) {
|
||||||
for (piece_type_t piece = 0; piece <= KING; ++piece)
|
for (piece_type_t piece = 0; piece <= KING; ++piece)
|
||||||
if (warn_on(_cmpf(bb[color][piece])))
|
if (_cmpf(bb[color][piece]))
|
||||||
goto end;
|
goto end;
|
||||||
//pos->controlled[color] = 0;
|
if (_cmpf(king[color]))
|
||||||
if (warn_on(_cmpf(king[color])))
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warn_on(_cmpf(checkers)))
|
if (_cmpf(checkers) ||_cmpf(pinners) || _cmpf(blockers))
|
||||||
goto end;
|
goto end;
|
||||||
if (warn_on(_cmpf(pinners)))
|
|
||||||
goto end;
|
|
||||||
if (warn_on(_cmpf(blockers)))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if (warn_on(_cmpf(moves.nmoves)))
|
|
||||||
* goto end;
|
|
||||||
* for (int i = 0; i < pos1->moves.nmoves; ++i)
|
|
||||||
* if (warn_on(_cmpf(moves.move[i])))
|
|
||||||
* goto end;
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
end:
|
end:
|
||||||
@@ -353,14 +332,13 @@ bitboard_t pos_king_blockers(const pos_t *pos, const color_t color, const bitboa
|
|||||||
*
|
*
|
||||||
* @return: (if @strict is false) return true if check is ok, false otherwise.
|
* @return: (if @strict is false) return true if check is ok, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool pos_ok(__unused const pos_t *pos, __unused const bool strict)
|
bool pos_ok(const pos_t *pos, const bool strict)
|
||||||
{
|
{
|
||||||
int n, count = 0, bbcount = 0, error = 0;
|
int n, count = 0, bbcount = 0, error = 0;
|
||||||
__unused bitboard_t tmp;
|
|
||||||
|
|
||||||
/* pawns on 1st ot 8th rank */
|
/* pawns on 1st ot 8th rank */
|
||||||
tmp = (pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & (RANK_1bb | RANK_8bb);
|
error += warn_on((pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) &
|
||||||
error += warn_on(tmp);
|
(RANK_1bb | RANK_8bb));
|
||||||
|
|
||||||
for (color_t color = WHITE; color <= BLACK; ++color) {
|
for (color_t color = WHITE; color <= BLACK; ++color) {
|
||||||
/* pawn count */
|
/* pawn count */
|
||||||
@@ -396,7 +374,8 @@ bool pos_ok(__unused const pos_t *pos, __unused const bool strict)
|
|||||||
/* kings distance is less than 2 */
|
/* kings distance is less than 2 */
|
||||||
error += warn_on(sq_dist(pos->king[WHITE], pos->king[BLACK]) < 2);
|
error += warn_on(sq_dist(pos->king[WHITE], pos->king[BLACK]) < 2);
|
||||||
|
|
||||||
bug_on(strict && error);
|
if (strict)
|
||||||
|
bug_on(error);
|
||||||
return error? false: true;
|
return error? false: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,8 +52,7 @@ u64 perft(pos_t *pos, int depth, int ply)
|
|||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
return 1;
|
return 1;
|
||||||
pseudo.nmoves = 0;
|
pseudo.nmoves = 0;
|
||||||
pos->checkers = pos_checkers(pos, pos->turn);
|
pos_set_checkers_pinners_blockers(pos);
|
||||||
pos_set_pinners_blockers(pos);
|
|
||||||
state = pos->state;
|
state = pos->state;
|
||||||
|
|
||||||
pos_gen_pseudomoves(pos, &pseudo);
|
pos_gen_pseudomoves(pos, &pseudo);
|
||||||
|
Reference in New Issue
Block a user