experiment: add pos_set_checkers_pinners_blockers()
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "chessdefs.h"
|
||||
#include "position.h"
|
||||
#include "bitboard.h"
|
||||
#include "hyperbola-quintessence.h"
|
||||
#include "fen.h"
|
||||
#include "piece.h"
|
||||
#include "util.h"
|
||||
@@ -194,17 +195,83 @@ bitboard_t pos_checkers(const pos_t *pos, const color_t color)
|
||||
* It should be faster than @pos_checkers + @pos_set_pinners_blockers, as
|
||||
* some calculation will be done once.
|
||||
*/
|
||||
/*
|
||||
* void pos_set_checkers_pinners_blockers(pos_t *pos)
|
||||
* {
|
||||
* bitboard_t b_bb = pos->bb[WHITE][BISHOP] | pos->bb[BLACK][BISHOP];
|
||||
* bitboard_t r_bb = pos->bb[WHITE][ROOK] | pos->bb[BLACK][ROOK];
|
||||
* bitboard_t q_bb = pos->bb[WHITE][QUEEN] | pos->bb[BLACK][QUEEN];
|
||||
*
|
||||
* /\* find out first piece on every diagonal *\/
|
||||
*
|
||||
* }
|
||||
*/
|
||||
void pos_set_checkers_pinners_blockers(pos_t *pos)
|
||||
{
|
||||
int us = pos->turn, them = OPPONENT(us);
|
||||
bitboard_t occ = pos_occ(pos);
|
||||
bitboard_t attackers;
|
||||
bitboard_t checkers = 0, blockers = 0, pinners = 0;
|
||||
bitboard_t targets, tmpcheckers, tmpblockers, tmppinners, tmpbb;
|
||||
square_t king = pos->king[us];
|
||||
bitboard_t king_bb = mask(king);
|
||||
int pinner;
|
||||
|
||||
/* bishop type - we attack with a bishop from king position */
|
||||
attackers = pos->bb[them][BISHOP] | pos->bb[them][QUEEN];
|
||||
|
||||
/* targets is all "target" pieces if K was a bishop */
|
||||
targets = hyperbola_bishop_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_bishop_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;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* pawns */
|
||||
attackers = pos->bb[them][PAWN];
|
||||
targets = pawn_shift_upleft(king_bb, us) | pawn_shift_upright(king_bb, us);
|
||||
checkers |= targets & attackers;
|
||||
|
||||
/* knight */
|
||||
attackers = pos->bb[them][KNIGHT];
|
||||
targets = bb_knight_moves(attackers, king);
|
||||
checkers |= targets;
|
||||
|
||||
pos->checkers = checkers;
|
||||
pos->pinners = pinners;
|
||||
pos->blockers = blockers;
|
||||
}
|
||||
|
||||
/**
|
||||
* pos_set_pinners_blockers() - set position pinners and blockers.
|
||||
|
@@ -159,7 +159,7 @@ void pos_del(pos_t *pos);
|
||||
pos_t *pos_clear(pos_t *pos);
|
||||
bool pos_cmp(const pos_t *pos1, const pos_t *pos2);
|
||||
|
||||
//bitboard_t set_king_pinners_blockers(pos_t *pos);
|
||||
void pos_set_checkers_pinners_blockers(pos_t *pos);
|
||||
void pos_set_pinners_blockers(pos_t *pos);
|
||||
bitboard_t pos_checkers(const pos_t *pos, const color_t color);
|
||||
bitboard_t pos_king_pinners(const pos_t *pos, const color_t color);
|
||||
|
31
src/search.c
31
src/search.c
@@ -127,6 +127,37 @@ u64 perft2(pos_t *pos, int depth, int ply)
|
||||
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 };
|
||||
move_t move;
|
||||
state_t state;
|
||||
|
||||
if (depth == 0)
|
||||
return 1;
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
state = pos->state;
|
||||
|
||||
pos_gen_pseudomoves(pos, &pseudo);
|
||||
while ((move = pos_next_legal(pos, &pseudo, &movetmp)) != MOVE_NONE) {
|
||||
move_do(pos, move);
|
||||
subnodes = perft(pos, depth - 1, ply + 1);
|
||||
if (ply == 1) {
|
||||
char movestr[8];
|
||||
printf("%s: %d\n", move_str(movestr, move, 0), subnodes);
|
||||
}
|
||||
nodes += subnodes;
|
||||
move_undo(pos, move);
|
||||
pos->state = state;
|
||||
}
|
||||
|
||||
if (ply == 1)
|
||||
printf("Total: %lu\n", nodes);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* negamax() - search position negamax.
|
||||
* @pos: &position to search
|
||||
|
@@ -21,5 +21,6 @@
|
||||
|
||||
u64 perft(pos_t *pos, int depth, int ply);
|
||||
u64 perft2(pos_t *pos, int depth, int ply);
|
||||
u64 perft_new_pinners(pos_t *pos, int depth, int ply);
|
||||
|
||||
#endif /* SEARCH_H */
|
||||
|
@@ -28,6 +28,7 @@ int main(int __unused ac, __unused char**av)
|
||||
int i = 0;
|
||||
char *fen;
|
||||
pos_t *pos;//, *fishpos = pos_new();
|
||||
bitboard_t checkers, pinners, blockers;
|
||||
|
||||
setlinebuf(stdout); /* line-buffered stdout */
|
||||
|
||||
@@ -41,8 +42,22 @@ int main(int __unused ac, __unused char**av)
|
||||
printf("wrong fen %d: [%s]\n", i, fen);
|
||||
continue;
|
||||
}
|
||||
pos->checkers = pos_checkers(pos, pos->turn);
|
||||
pos_set_pinners_blockers(pos);
|
||||
|
||||
pos_print(pos);
|
||||
|
||||
checkers = pos->checkers;
|
||||
pinners = pos->pinners;
|
||||
blockers = pos->blockers;
|
||||
|
||||
pos_set_checkers_pinners_blockers(pos);
|
||||
|
||||
printf("******* %s\n", cur_comment());
|
||||
bb_print_multi("checkers", 2, checkers, pos->checkers);
|
||||
bb_print_multi("pinners", 2, pinners, pos->pinners);
|
||||
bb_print_multi("blockers", 2, blockers, pos->blockers);
|
||||
|
||||
pos_del(pos);
|
||||
i++;
|
||||
}
|
||||
|
@@ -233,7 +233,9 @@ int main(int __unused ac, __unused char**av)
|
||||
//move_t move;
|
||||
FILE *outfd;
|
||||
int depth = 6;
|
||||
s64 ms1 = 0, ms1_total = 0, ms2 = 0, ms2_total = 0;
|
||||
s64 ms1 = 0, ms1_total = 0;
|
||||
s64 ms2 = 0, ms2_total = 0;
|
||||
s64 ms3 = 0, ms3_total = 0;
|
||||
int run = 3;
|
||||
|
||||
if (ac > 1)
|
||||
@@ -288,15 +290,33 @@ int main(int __unused ac, __unused char**av)
|
||||
ms2_total += ms2;
|
||||
|
||||
if (sf_count == my_count) {
|
||||
printf("pt2 OK : line=%03d perft=%lu %'ldms lps=%'lu \"%s\"\n\n",
|
||||
printf("pt2 OK : line=%03d perft=%lu %'ldms lps=%'lu \"%s\"\n",
|
||||
test_line, my_count, ms2,
|
||||
ms2? my_count*1000l/ms2: 0,
|
||||
fen);
|
||||
} else {
|
||||
printf("pt2 ERR: line=%03d sf=%lu me=%lu \"%s\"\n\n",
|
||||
printf("pt2 ERR: line=%03d 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=%03d perft=%lu %'ldms lps=%'lu \"%s\"\n",
|
||||
test_line, my_count, ms3,
|
||||
ms3? my_count*1000l/ms3: 0,
|
||||
fen);
|
||||
} else {
|
||||
printf("pt3 ERR: line=%03d sf=%lu me=%lu \"%s\"\n",
|
||||
test_line, sf_count, my_count, fen);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
pos_del(savepos);
|
||||
pos_del(pos);
|
||||
i++;
|
||||
@@ -305,5 +325,7 @@ 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