Compare commits
5 Commits
e8240c6cab
...
9b5c2253b1
Author | SHA1 | Date | |
---|---|---|---|
9b5c2253b1 | |||
e301e6c726 | |||
e78eae21e6 | |||
711306c92a | |||
660722fadc |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ vgcore.*
|
||||
*.i
|
||||
*.old
|
||||
*.save
|
||||
perf.data
|
||||
/GPATH
|
||||
/GRTAGS
|
||||
/GTAGS
|
||||
|
16
Makefile
16
Makefile
@@ -56,7 +56,6 @@ CPPFILES := $(SRC:.c=.i) $(TSTSRC:.c=.i)
|
||||
CPPFLAGS := -I$(BRINCDIR) -I$(INCDIR)
|
||||
|
||||
CPPFLAGS += -DNDEBUG # assert
|
||||
|
||||
CPPFLAGS += -DBUG_ON # brlib bug.h
|
||||
CPPFLAGS += -DWARN_ON # brlib bug.h
|
||||
|
||||
@@ -88,9 +87,16 @@ CPPFLAGS := $(strip $(CPPFLAGS))
|
||||
CFLAGS := -std=gnu11
|
||||
|
||||
### dev OR release
|
||||
|
||||
# dev
|
||||
#CFLAGS += -O1
|
||||
#CFLAGS += -g
|
||||
# CFLAGS += -O1
|
||||
CFLAGS += -g # symbols (gdb, perf, etc.)
|
||||
CFLAGS += -ginline-points # inlined funcs debug info
|
||||
# for gprof
|
||||
#CFLAGS += -pg
|
||||
# Next one may be useful for valgrind (when invalid instructions)
|
||||
#CFLAGS += -mno-tbm
|
||||
|
||||
# release
|
||||
CFLAGS += -Ofast
|
||||
|
||||
@@ -99,10 +105,6 @@ CFLAGS += -flto
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wextra
|
||||
CFLAGS += -Wmissing-declarations
|
||||
# for gprof
|
||||
#CFLAGS += -pg
|
||||
# Next one may be useful for valgrind (when invalid instructions)
|
||||
# CFLAGS += -mno-tbm
|
||||
|
||||
CFLAGS := $(strip $(CFLAGS))
|
||||
|
||||
|
@@ -40,7 +40,6 @@
|
||||
*/
|
||||
bool sq_is_attacked(const pos_t *pos, const bitboard_t occ, const square_t sq, const color_t c)
|
||||
{
|
||||
bitboard_t sqbb = mask(sq);
|
||||
color_t opp = OPPONENT(c);
|
||||
|
||||
/* bishop / queen */
|
||||
|
@@ -160,10 +160,10 @@ void bitboard_init(void)
|
||||
/* 3) pawn, knight and king attacks
|
||||
*/
|
||||
for (square_t sq = A1; sq <= H8; ++sq) {
|
||||
if (sq >= A2 && sq <= H7) {
|
||||
bb_pawn_attacks[WHITE][sq] = pawn_attacks_bb(mask(sq), WHITE);
|
||||
if (sq >= A2)
|
||||
bb_pawn_attacks[BLACK][sq] = pawn_attacks_bb(mask(sq), BLACK);
|
||||
}
|
||||
if (sq <= H7)
|
||||
bb_pawn_attacks[WHITE][sq] = pawn_attacks_bb(mask(sq), WHITE);
|
||||
|
||||
for (int vec = 0; vec < 8; ++vec) {
|
||||
int dst = sq + knight_vector[vec];
|
||||
|
@@ -314,6 +314,7 @@ static __always_inline bitboard_t shift_nw(const bitboard_t bb)
|
||||
#define pawn_shift_up(bb, c) ((c) == WHITE ? shift_n(bb): shift_s(bb))
|
||||
#define pawn_shift_upleft(bb, c) ((c) == WHITE ? shift_nw(bb): shift_se(bb))
|
||||
#define pawn_shift_upright(bb, c) ((c) == WHITE ? shift_ne(bb): shift_sw(bb))
|
||||
|
||||
#define pawn_attacks_bb(bb, c) (pawn_shift_upleft(bb, c) | \
|
||||
pawn_shift_upright(bb, c))
|
||||
|
||||
@@ -321,8 +322,8 @@ static __always_inline bitboard_t shift_nw(const bitboard_t bb)
|
||||
* Need to make functions with control instead.
|
||||
*/
|
||||
#define pawn_push_up(sq, c) ((sq) + ((c) == WHITE ? NORTH: SOUTH))
|
||||
#define pawn_push_upleft(sq, c) ((sq) + ((c) == WHITE ? NORTH_WEST: SOUTH_EAST))
|
||||
#define pawn_push_upright(sq, c) ((sq) + ((c) == WHITE ? NORTH_EAST: SOUTH_WEST))
|
||||
//#define pawn_push_upleft(sq, c) ((sq) + ((c) == WHITE ? NORTH_WEST: SOUTH_EAST))
|
||||
//#define pawn_push_upright(sq, c) ((sq) + ((c) == WHITE ? NORTH_EAST: SOUTH_WEST))
|
||||
|
||||
bitboard_t bitboard_between_excl(square_t sq1, square_t sq2);
|
||||
void bitboard_init(void);
|
||||
|
@@ -56,6 +56,7 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state)
|
||||
piece_type_t ptype = PIECE(piece);
|
||||
color_t pcolor = COLOR(piece);
|
||||
piece_t new_piece = piece;
|
||||
int up = sq_up(us);
|
||||
|
||||
++pos->clock_50;
|
||||
++pos->plycount;
|
||||
@@ -90,9 +91,9 @@ pos_t *move_do(pos_t *pos, const move_t move) //, state_t *state)
|
||||
} else if (ptype == PAWN) { /* pawn non capture or e.p. */
|
||||
pos->clock_50 = 0;
|
||||
if (is_dpush(move)) /* if pawn double push, set e.p. */
|
||||
pos->en_passant = from + sq_up(us);
|
||||
pos->en_passant = from + up;
|
||||
else if (is_enpassant(move)) { /* clear grabbed pawn */
|
||||
square_t grabbed = pawn_push_up(to, them);
|
||||
square_t grabbed = to - up;
|
||||
pos_clr_sq(pos, grabbed);
|
||||
}
|
||||
}
|
||||
@@ -157,7 +158,7 @@ pos_t *move_undo(pos_t *pos, const move_t move)//, const state_t *state)
|
||||
color_t them = pos->turn, us = OPPONENT(them);
|
||||
square_t from = move_from(move), to = move_to(move);
|
||||
piece_t piece = pos->board[to];
|
||||
|
||||
int up = sq_up(them);
|
||||
|
||||
if (is_promotion(move))
|
||||
piece = MAKE_PIECE(PAWN, us);
|
||||
@@ -182,7 +183,7 @@ pos_t *move_undo(pos_t *pos, const move_t move)//, const state_t *state)
|
||||
pos_set_sq(pos, rookto, pos->board[rookfrom]);
|
||||
pos_clr_sq(pos, rookfrom);
|
||||
} else if (is_enpassant(move)) { /* restore grabbed pawn */
|
||||
square_t grabbed = pawn_push_up(to, them);
|
||||
square_t grabbed = to + up;
|
||||
pos_set_sq(pos, grabbed, MAKE_PIECE(PAWN, them));
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,7 @@ bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
||||
bitboard_t kingbb = pos->bb[us][KING];
|
||||
bitboard_t occ = pos_occ(pos);
|
||||
u64 pinned = mask(from) & pos->blockers;
|
||||
u64 checkers = pos->checkers;
|
||||
|
||||
/* (1) - Castling & King
|
||||
* For castling, we need to check intermediate squares attacks only.
|
||||
@@ -49,12 +50,12 @@ bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
||||
* king from occupation bitboard (to catch king moving away from checker
|
||||
* on same line) !
|
||||
*/
|
||||
if (is_castle(move)) {
|
||||
square_t dir = to > from? 1: -1;
|
||||
if (sq_attackers(pos, occ, from + dir, them))
|
||||
return false;
|
||||
}
|
||||
if (from == king) {
|
||||
if (unlikely(from == king)) {
|
||||
if (unlikely(is_castle(move))) {
|
||||
square_t dir = to > from? 1: -1;
|
||||
if (sq_attackers(pos, occ, from + dir, them))
|
||||
return false;
|
||||
}
|
||||
return !sq_attackers(pos, occ ^ kingbb, to, them);
|
||||
}
|
||||
|
||||
@@ -68,18 +69,18 @@ bool pseudo_is_legal(const pos_t *pos, const move_t move)
|
||||
* e.p., legal if the grabbed pawn is giving check
|
||||
* pinned piece: always illegal
|
||||
*/
|
||||
if (pos->checkers) {
|
||||
if (checkers) {
|
||||
if (pinned)
|
||||
return false;
|
||||
if (bb_multiple(pos->checkers))
|
||||
if (bb_multiple(checkers))
|
||||
return false;
|
||||
square_t checker = ctz64(pos->checkers);
|
||||
square_t checker = ctz64(checkers);
|
||||
if (is_enpassant(move)) {
|
||||
return pos->en_passant + sq_up(them) == checker;
|
||||
}
|
||||
return true;
|
||||
bitboard_t between = bb_between[king][checker] | pos->checkers;
|
||||
return mask(to) & between;
|
||||
//bitboard_t between = bb_between[king][checker] | pos->checkers;
|
||||
//return mask(to) & between;
|
||||
}
|
||||
|
||||
/* (3) - pinned pieces
|
||||
@@ -388,6 +389,30 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
||||
*moves++ = move_make_flags(from, to, M_DPUSH);
|
||||
}
|
||||
|
||||
/* pawn: captures */
|
||||
/*
|
||||
* tmp_bb = pawn_attacks_bb(pos->bb[us][PAWN], us) & enemy_pieces;
|
||||
* //bb_print("FAIL", tmp_bb);
|
||||
* to_bb = tmp_bb & ~rel_rank8;
|
||||
* while (to_bb) {
|
||||
* to = bb_next(&to_bb);
|
||||
* from_bb = bb_pawn_attacks[them][to] & pos->bb[us][PAWN];
|
||||
* while (from_bb) {
|
||||
* from = bb_next(&from_bb);
|
||||
* *moves++ = move_make(from, to);
|
||||
* }
|
||||
* }
|
||||
* to_bb = tmp_bb & rel_rank8;
|
||||
* while (to_bb) {
|
||||
* to = bb_next(&to_bb);
|
||||
* from_bb = bb_pawn_attacks[them][to] & pos->bb[us][PAWN];
|
||||
* while (from_bb) {
|
||||
* from = bb_next(&from_bb);
|
||||
* moves = move_make_promotions(moves, from, to);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/* pawn: captures left */
|
||||
bitboard_t filter = ~bb_rel_file(FILE_A, us);
|
||||
shift = sq_upleft(us);
|
||||
@@ -427,18 +452,26 @@ int pos_gen_pseudomoves(pos_t *pos, movelist_t *movelist)
|
||||
* TODO: special case when in-check here ?
|
||||
*/
|
||||
if ((to = pos->en_passant) != SQUARE_NONE) {
|
||||
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);
|
||||
from_bb = bb_pawn_attacks[them][to] & pos->bb[us][PAWN];
|
||||
while (from_bb) {
|
||||
from = bb_next(&from_bb);
|
||||
*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
|
||||
*/
|
||||
|
@@ -116,7 +116,7 @@ pos_t *pos_clear(pos_t *pos)
|
||||
*
|
||||
* @return: true if equal, false otherwise.
|
||||
*/
|
||||
bool pos_cmp(const pos_t *pos1, const pos_t *pos2)
|
||||
bool pos_cmp(__unused const pos_t *pos1, __unused const pos_t *pos2)
|
||||
{
|
||||
#define _cmpf(a) (pos1->a != pos2->a)
|
||||
bool ret = false;
|
||||
@@ -201,7 +201,7 @@ void pos_set_checkers_pinners_blockers(pos_t *pos)
|
||||
bitboard_t occ = pos_occ(pos);
|
||||
bitboard_t attackers;
|
||||
bitboard_t checkers = 0, blockers = 0, pinners = 0;
|
||||
bitboard_t targets, tmpcheckers, tmpblockers, tmppinners, tmpbb;
|
||||
bitboard_t targets, tmpcheckers, maybeblockers, tmppinners, tmpbb;
|
||||
square_t king = pos->king[us];
|
||||
bitboard_t king_bb = mask(king);
|
||||
int pinner;
|
||||
@@ -217,55 +217,47 @@ void pos_set_checkers_pinners_blockers(pos_t *pos)
|
||||
checkers |= tmpcheckers;
|
||||
|
||||
/* maybe blockers = not checkers */
|
||||
tmpblockers = targets & ~tmpcheckers;
|
||||
maybeblockers = targets & ~tmpcheckers;
|
||||
|
||||
/* we find second targets, by removing only first ones (excl. checkers) */
|
||||
targets = hyperbola_bishop_moves(occ ^ tmpblockers, king) ^ tmpcheckers;
|
||||
/* we find second targets, by removing first ones (excl. checkers) */
|
||||
if (maybeblockers) {
|
||||
targets = hyperbola_bishop_moves(occ ^ maybeblockers, king) ^ tmpcheckers;
|
||||
|
||||
/* pinners = only B/Q */
|
||||
tmppinners = targets & attackers;
|
||||
pinners |= tmppinners;
|
||||
//tmpblockers = 0;
|
||||
/* pinners = only B/Q */
|
||||
tmppinners = targets & attackers;
|
||||
|
||||
/* blockers = we find occupied squares between pinner and king */
|
||||
bit_for_each64(pinner, tmpbb, tmppinners)
|
||||
blockers |= bb_between[pinner][king] & tmpblockers;
|
||||
//blockers |= tmpblockers;
|
||||
/* blockers = we find occupied squares between pinner and king */
|
||||
while (tmppinners) {
|
||||
pinner = bb_next(&tmppinners);
|
||||
pinners |= mask(pinner);
|
||||
blockers |= bb_between[pinner][king] & maybeblockers;
|
||||
}
|
||||
}
|
||||
|
||||
/* same for rook type */
|
||||
attackers = pos->bb[them][ROOK] | pos->bb[them][QUEEN];
|
||||
|
||||
/* targets is all "target" pieces if K was a bishop */
|
||||
targets = hyperbola_rook_moves(occ, king) & occ;
|
||||
|
||||
/* checkers = only opponent B/Q */
|
||||
tmpcheckers = targets & attackers;
|
||||
checkers |= tmpcheckers;
|
||||
|
||||
/* maybe blockers = not checkers */
|
||||
tmpblockers = targets & ~tmpcheckers;
|
||||
|
||||
/* we find second targets, by removing only first ones (excl. checkers) */
|
||||
targets = hyperbola_rook_moves(occ ^ tmpblockers, king) ^ tmpcheckers;
|
||||
|
||||
/* pinners = only B/Q */
|
||||
tmppinners = targets & attackers;
|
||||
pinners |= tmppinners;
|
||||
//tmpblockers = 0;
|
||||
|
||||
/* blockers = we find occupied squares between pinner and king */
|
||||
bit_for_each64(pinner, tmpbb, tmppinners)
|
||||
blockers |= bb_between[pinner][king] & tmpblockers;
|
||||
//blockers |= tmpblockers;
|
||||
maybeblockers = targets & ~tmpcheckers;
|
||||
if (maybeblockers) {
|
||||
targets = hyperbola_rook_moves(occ ^ maybeblockers, king) ^ tmpcheckers;
|
||||
tmppinners = targets & attackers;
|
||||
while (tmppinners) {
|
||||
pinner = bb_next(&tmppinners);
|
||||
pinners |= mask(pinner);
|
||||
blockers |= bb_between[pinner][king] & maybeblockers;
|
||||
}
|
||||
}
|
||||
|
||||
/* pawns */
|
||||
attackers = pos->bb[them][PAWN];
|
||||
targets = pawn_shift_upleft(king_bb, us) | pawn_shift_upright(king_bb, us);
|
||||
checkers |= targets & attackers;
|
||||
checkers |= bb_pawn_attacks[us][king] & pos->bb[them][PAWN];
|
||||
|
||||
/* knight */
|
||||
attackers = pos->bb[them][KNIGHT];
|
||||
targets = bb_knight_moves(attackers, king);
|
||||
targets = bb_knight[king] & attackers;
|
||||
checkers |= targets;
|
||||
|
||||
pos->checkers = checkers;
|
||||
@@ -366,10 +358,10 @@ 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.
|
||||
*/
|
||||
bool pos_ok(const pos_t *pos, const bool strict)
|
||||
bool pos_ok(__unused const pos_t *pos, __unused const bool strict)
|
||||
{
|
||||
int n, count = 0, bbcount = 0, error = 0;
|
||||
bitboard_t tmp;
|
||||
__unused bitboard_t tmp;
|
||||
|
||||
/* pawns on 1st ot 8th rank */
|
||||
tmp = (pos->bb[WHITE][PAWN] | pos->bb[BLACK][PAWN]) & (RANK_1bb | RANK_8bb);
|
||||
@@ -391,7 +383,7 @@ bool pos_ok(const pos_t *pos, const bool strict)
|
||||
}
|
||||
for (square_t sq = 0; sq < 64; ++sq) {
|
||||
piece_t piece = pos->board[sq];
|
||||
bitboard_t match;
|
||||
__unused bitboard_t match;
|
||||
if (piece == EMPTY)
|
||||
continue;
|
||||
color_t c = COLOR(piece);
|
||||
|
51
src/search.c
51
src/search.c
@@ -45,12 +45,13 @@ u64 perft(pos_t *pos, int depth, int ply)
|
||||
{
|
||||
int subnodes, movetmp = 0;
|
||||
u64 nodes = 0;
|
||||
movelist_t pseudo = { .nmoves = 0 };
|
||||
movelist_t pseudo;
|
||||
move_t move;
|
||||
state_t state;
|
||||
|
||||
if (depth == 0)
|
||||
return 1;
|
||||
pseudo.nmoves = 0;
|
||||
pos->checkers = pos_checkers(pos, pos->turn);
|
||||
pos_set_pinners_blockers(pos);
|
||||
state = pos->state;
|
||||
@@ -74,7 +75,7 @@ u64 perft(pos_t *pos, int depth, int ply)
|
||||
}
|
||||
|
||||
/**
|
||||
* perft2() - Perform perft on position
|
||||
* perft_new_pinners() - Perform perft on position
|
||||
* @pos: &position to search
|
||||
* @depth: Wanted depth.
|
||||
* @ply: perft depth level.
|
||||
@@ -82,61 +83,19 @@ u64 perft(pos_t *pos, int depth, int ply)
|
||||
* Run perft on a position. This function displays the available moves at @depth
|
||||
* level for each possible first move, and the total of moves.
|
||||
*
|
||||
* This version uses the algorithm:
|
||||
* if (king in check)
|
||||
* finish;
|
||||
* if last depth
|
||||
* return 1;
|
||||
* gen pseudo-legal moves
|
||||
* foreach pseudo-legal move...
|
||||
*
|
||||
* @return: total moves found at @depth level.
|
||||
*/
|
||||
u64 perft2(pos_t *pos, int depth, int ply)
|
||||
{
|
||||
int subnodes, nmove = 0;
|
||||
u64 nodes = 0;
|
||||
movelist_t pseudo = { .nmoves = 0 };
|
||||
move_t move;
|
||||
state_t state;
|
||||
|
||||
if (depth == 0)
|
||||
return 1;
|
||||
pos->checkers = pos_checkers(pos, pos->turn);
|
||||
pos_set_pinners_blockers(pos);
|
||||
state = pos->state;
|
||||
|
||||
pos_gen_pseudomoves(pos, &pseudo);
|
||||
|
||||
for (nmove = 0; nmove < pseudo.nmoves; ++nmove ) {
|
||||
move = pseudo.move[nmove];
|
||||
move_do(pos, move);
|
||||
if (!is_in_check(pos, OPPONENT(pos->turn))) {
|
||||
subnodes = perft2(pos, depth - 1, ply + 1);
|
||||
nodes += subnodes;
|
||||
if (ply == 1) {
|
||||
char movestr[8];
|
||||
printf("%s: %d\n", move_str(movestr, move, 0), subnodes);
|
||||
}
|
||||
}
|
||||
move_undo(pos, move);
|
||||
pos->state = state;
|
||||
}
|
||||
if (ply == 1)
|
||||
printf("Total: %lu\n", nodes);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
u64 perft_new_pinners(pos_t *pos, int depth, int ply)
|
||||
{
|
||||
int subnodes, movetmp = 0;
|
||||
u64 nodes = 0;
|
||||
movelist_t pseudo = { .nmoves = 0 };
|
||||
movelist_t pseudo;
|
||||
move_t move;
|
||||
state_t state;
|
||||
|
||||
if (depth == 0)
|
||||
return 1;
|
||||
pseudo.nmoves = 0;
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
state = pos->state;
|
||||
|
||||
|
@@ -35,10 +35,9 @@ struct fentest {
|
||||
""
|
||||
},
|
||||
*/
|
||||
/* tests rank movegen bug - FIXED
|
||||
*/
|
||||
//"4k3/pppppppp/8/8/8/8/PPPPPPPP/2BRK3 w - - 0 1",
|
||||
//"4k3/pppppppp/8/8/8/8/PPPPPPPP/1B1R1K2 w - - 0 1",
|
||||
|
||||
/* ***************** TEMP TESTS ABOVE ************************** */
|
||||
|
||||
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||
"illegal white e.p.",
|
||||
"3k4/8/5K2/3pP3/8/2b5/8/8 w - d6 0 1",
|
||||
@@ -92,43 +91,43 @@ struct fentest {
|
||||
* },
|
||||
*/
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: a1 h1",
|
||||
"1k6/8/8/8/8/8/8/r2K3r w - - 1 1"
|
||||
"only 3 K moves (but impossible situation)",
|
||||
"1k6/8/8/8/8/8/8/r2K3r w - - 0 1"
|
||||
},
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: a8 h8",
|
||||
"R2k3R/8/8/8/8/8/8/1K6 b - - 1 1"
|
||||
"R2k3R/8/8/8/8/8/8/1K6 b - - 0 1"
|
||||
},
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: b3 g3",
|
||||
"1k6/8/8/8/8/1r1K2r1/8/8 w - - 1 1"
|
||||
"1k6/8/8/8/8/1r1K2r1/8/8 w - - 0 1"
|
||||
},
|
||||
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: b6 g6",
|
||||
"8/8/1R1k2R1/8/8/8/8/1K6 b - - 1 1"
|
||||
"8/8/1R1k2R1/8/8/8/8/1K6 b - - 0 1"
|
||||
},
|
||||
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: g2 g7",
|
||||
"8/k5r1/8/8/6K1/8/6r1/8 w - - 1 1"
|
||||
"8/k5r1/8/8/6K1/8/6r1/8 w - - 0 1"
|
||||
},
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: g2 g7",
|
||||
"8/6R1/8/6k1/8/8/K5R1/8 b - - 1 1"
|
||||
"8/6R1/8/6k1/8/8/K5R1/8 b - - 0 1"
|
||||
},
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: d5 e3, pinners: none (2 pieces between attacker & K)",
|
||||
"3k4/8/8/3r3b/b7/1N2nn2/2n1B3/rNBK1Rbr w - - 1 1"
|
||||
"3k4/8/8/3r3b/b7/1N2nn2/2n1B3/rNBK1Rbr w - - 0 1"
|
||||
},
|
||||
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: d4 e6 pinners: h4 a5 a8 h8",
|
||||
"Rn1k1r1R/4b3/1n2N3/B7/3R3B/8/8/3K4 b - - 1 1"
|
||||
"Rn1k1r1R/4b3/1n2N3/B7/3R3B/8/8/3K4 b - - 0 1"
|
||||
},
|
||||
{ __LINE__, ATTACK,
|
||||
"checkers: d5 e3, pinners: a1 h1 a4 h5",
|
||||
"3k4/8/8/3r3b/b7/1N2n3/4B3/rN1K1R1r w - - 1 0"
|
||||
"3k4/8/8/3r3b/b7/1N2n3/4B3/rN1K1R1r w - - 0 1"
|
||||
},
|
||||
|
||||
{ __LINE__, MOVEGEN | MOVEDO | PERFT,
|
||||
|
@@ -232,16 +232,15 @@ int main(int __unused ac, __unused char**av)
|
||||
movelist_t fishmoves;
|
||||
//move_t move;
|
||||
FILE *outfd;
|
||||
int depth = 6;
|
||||
s64 ms1 = 0, ms1_total = 0;
|
||||
s64 ms2 = 0, ms2_total = 0;
|
||||
s64 ms3 = 0, ms3_total = 0;
|
||||
int run = 7;
|
||||
|
||||
int depth = 6, run = 3;
|
||||
|
||||
if (ac > 1)
|
||||
depth = atoi(av[1]);
|
||||
if (ac > 2)
|
||||
run = atoi(av[2]);
|
||||
run = atoi(av[2]) & 3;
|
||||
printf("depth = %d run=%d\n", depth, run);
|
||||
|
||||
if (!run)
|
||||
@@ -253,7 +252,6 @@ int main(int __unused ac, __unused char**av)
|
||||
bitboard_init();
|
||||
hyperbola_init();
|
||||
|
||||
|
||||
CLOCK_DEFINE(clock, CLOCK_PROCESS);
|
||||
while ((fen = next_fen(PERFT | MOVEDO))) {
|
||||
test_line = cur_line();
|
||||
@@ -271,46 +269,29 @@ int main(int __unused ac, __unused char**av)
|
||||
ms1_total += ms1;
|
||||
|
||||
if (sf_count == my_count) {
|
||||
printf("pt1 OK : line=%3d perft=%lu %'ldms lps=%'lu \"%s\"\n",
|
||||
printf("pt1 OK : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n",
|
||||
test_line, my_count, ms1,
|
||||
ms1? my_count*1000l/ms1: 0,
|
||||
fen);
|
||||
} else {
|
||||
printf("pt1 ERR: line=%3d sf=%lu me=%lu \"%s\"\n",
|
||||
printf("pt1 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n",
|
||||
test_line, sf_count, my_count, fen);
|
||||
}
|
||||
}
|
||||
|
||||
if (run & 2) {
|
||||
clock_start(&clock);
|
||||
my_count = perft2(pos, depth, 1);
|
||||
my_count = perft_new_pinners(pos, depth, 1);
|
||||
ms2 = clock_elapsed_ms(&clock);
|
||||
ms2_total += ms2;
|
||||
|
||||
if (sf_count == my_count) {
|
||||
printf("pt2 OK : line=%3d perft=%lu %'ldms lps=%'lu \"%s\"\n",
|
||||
printf("pt2 OK : line=%3d perft=%'lu %'ldms lps=%'lu \"%s\"\n",
|
||||
test_line, my_count, ms2,
|
||||
ms2? my_count*1000l/ms2: 0,
|
||||
fen);
|
||||
} else {
|
||||
printf("pt2 ERR: line=%3d sf=%lu me=%lu \"%s\"\n",
|
||||
test_line, sf_count, my_count, fen);
|
||||
}
|
||||
}
|
||||
|
||||
if (run & 4) {
|
||||
clock_start(&clock);
|
||||
my_count = perft_new_pinners(pos, depth, 1);
|
||||
ms3 = clock_elapsed_ms(&clock);
|
||||
ms3_total += ms3;
|
||||
|
||||
if (sf_count == my_count) {
|
||||
printf("pt3 OK : line=%3d perft=%lu %'ldms lps=%'lu \"%s\"\n",
|
||||
test_line, my_count, ms3,
|
||||
ms3? my_count*1000l/ms3: 0,
|
||||
fen);
|
||||
} else {
|
||||
printf("pt3 ERR: line=%3d sf=%lu me=%lu \"%s\"\n",
|
||||
printf("pt2 ERR: line=%3d sf=%'lu me=%'lu \"%s\"\n",
|
||||
test_line, sf_count, my_count, fen);
|
||||
}
|
||||
}
|
||||
@@ -323,7 +304,5 @@ int main(int __unused ac, __unused char**av)
|
||||
printf("total perft %'ldms\n", ms1_total);
|
||||
if (run & 2)
|
||||
printf("total perft2 %'ldms\n", ms2_total);
|
||||
if (run & 4)
|
||||
printf("total perft3 %'ldms\n", ms3_total);
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user