experiment: add pos_set_checkers_pinners_blockers()

This commit is contained in:
2024-03-30 18:45:13 +01:00
parent 96744cea20
commit 4816b4a53a
6 changed files with 151 additions and 15 deletions

View File

@@ -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.

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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++;
}

View File

@@ -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;
}