diff --git a/src/attack.c b/src/attack.c index b56db1c..9c2e003 100644 --- a/src/attack.c +++ b/src/attack.c @@ -20,6 +20,9 @@ #include "hyperbola-quintessence.h" #include "attack.h" + +// #define DEBUG_ATTACK_ATTACKERS1 + /** * sq_attackers() - find attackers on a square * @pos: position @@ -36,9 +39,6 @@ * * @Return: a bitboard of attackers. */ - -// #define DEBUG_ATTACK_ATTACKERS1 - bitboard_t sq_attackers(const pos_t *pos, const square_t sq, const color_t c) { bitboard_t attackers = 0, tmp; @@ -96,24 +96,24 @@ bitboard_t sq_attackers(const pos_t *pos, const square_t sq, const color_t c) } /** - * sq_pinners() - find pinners on a square + * sq_pinners() - get "pinners" on a square * @pos: position * @sq: square to test - * @c: attacker color + * @color: attacker color * * Find all @c pieces which are separated from @sq by only one piece (of * any color). * - * @Return: a bitboard of attackers. + * @Return: bitboard of pinners. */ -bitboard_t sq_pinners(const pos_t *pos, const square_t sq, const color_t c) +bitboard_t sq_pinners(const pos_t *pos, const square_t sq, const color_t color) { bitboard_t attackers, pinners = 0; bitboard_t occ = pos_occ(pos); bitboard_t maybe_pinner, tmp, lines; /* bishop type */ - attackers = pos->bb[c][BISHOP] | pos->bb[c][QUEEN]; + attackers = pos->bb[color][BISHOP] | pos->bb[color][QUEEN]; /* occupancy on sq diag and antidiag */ lines = (bb_sqdiag[sq] | bb_sqanti[sq]) & occ; bit_for_each64(maybe_pinner, tmp, attackers) { @@ -124,7 +124,7 @@ bitboard_t sq_pinners(const pos_t *pos, const square_t sq, const color_t c) } /* same for rook type */ - attackers = pos->bb[c][ROOK] | pos->bb[c][QUEEN]; + attackers = pos->bb[color][ROOK] | pos->bb[color][QUEEN]; lines = (bb_sqrank[sq] | bb_sqfile[sq]) & occ; bit_for_each64(maybe_pinner, tmp, attackers) { bitboard_t between = bb_between_excl[maybe_pinner][sq]; diff --git a/src/fen.c b/src/fen.c index 1abf318..de9fbaf 100644 --- a/src/fen.c +++ b/src/fen.c @@ -133,7 +133,8 @@ static int fen_check(pos_t *pos) if (!(error = pos_check(pos, 0))) { /* TODO: Should it really be here ? */ pos->checkers = pos_checkers(pos, pos->turn); - pos->pinners = pos_pinners(pos, pos->turn); + pos->pinners = pos_king_pinners(pos, pos->turn); + pos->blockers = pos_king_blockers(pos, pos->turn, pos->pinners); } return error ? -1: warning; } diff --git a/src/position.c b/src/position.c index eba638f..d33b7ad 100644 --- a/src/position.c +++ b/src/position.c @@ -132,18 +132,46 @@ bitboard_t pos_checkers(const pos_t *pos, const color_t color) } /** - * pos_pinners() - find all pinners on a king. + * pos_king_pinners() - get the "pinners" on a king "pinners". * @pos: &position - * @color: king color + * @color: king color. * - * Get a bitboard of all pinners on @color king. - * Just a wrapper over @sq_pinners(). + * get position "pinners" on @color king. Here, pinner means a piece separated from king + * by one piece (any color) only. + * This is just a wrapper over @sq_pinners(). * - * @return: a bitboard of pinners. + * @return: pinners bitboard. */ -bitboard_t pos_pinners(const pos_t *pos, const color_t color) +bitboard_t pos_king_pinners(const pos_t *pos, const color_t color) { - return sq_pinners(pos, pos->king[color], OPPONENT(color)); + return sq_pinners(pos, pos->king[color], OPPONENT(pos->turn)); +} + +/** + * pos_king_blockers() - get the pin blockers on a king. + * @pos: &position + * @color: king color. + * @pinners: pinners bitboard. + * + * get @pinners blockers pieces on @color king. + * + * @return: blockers bitboard. + */ +bitboard_t pos_king_blockers(const pos_t *pos, const color_t color, const bitboard_t pinners) +{ + bitboard_t tmp, blockers = 0, occ = pos_occ(pos); + square_t pinner, king = pos->king[color]; + + bit_for_each64(pinner, tmp, pinners) { + bitboard_t blocker = bb_between_excl[pinner][king] & occ; + warn_on(popcount64(blocker) != 1); + if (popcount64(blocker) != 1) { + printf("n blockers = %d\n", popcount64(blocker)); + bb_print("blockers", blocker); + } + blockers |= blocker; + } + return blockers; } /** @@ -233,6 +261,7 @@ void pos_print(const pos_t *pos) printf("fen %s\n", pos2fen(pos, str)); printf("checkers: %s\n", pos_checkers2str(pos, str, sizeof(str))); printf("pinners : %s\n", pos_pinners2str(pos, str, sizeof(str))); + printf("blockers: %s\n", pos_blockers2str(pos, str, sizeof(str))); } /** diff --git a/src/position.h b/src/position.h index cb15ec5..1cb2390 100644 --- a/src/position.h +++ b/src/position.h @@ -39,10 +39,13 @@ typedef struct __pos_s { bitboard_t controlled[2]; /* unsure */ bitboard_t checkers; /* opponent checkers */ bitboard_t pinners; /* opponent pinners */ + bitboard_t blockers; /* pieces blocking pin */ piece_t board[BOARDSIZE]; movelist_t moves; } pos_t; +#define pos_pinned(p) (p->blockers & p->bb[p->turn][ALL_PIECES]) + /** * pos_set_sq - unconditionally set a piece on a square * @pos: position @@ -120,7 +123,7 @@ static __always_inline int pos_between_count(const pos_t *pos, /** * pos_checkers2str() - get of string of checkers. - * @pos: position + * @p: position * @str: destination string * @len: max @str len. * @@ -128,8 +131,9 @@ static __always_inline int pos_between_count(const pos_t *pos, * * @return: @str. */ -#define pos_checkers2str(pos, str, len) bb_sq2str((pos)->checkers, (str), (len)) -#define pos_pinners2str(pos, str, len) bb_sq2str((pos)->pinners, (str), (len)) +#define pos_checkers2str(p, str, len) bb_sq2str(p->checkers, str, len) +#define pos_pinners2str(p, str, len) bb_sq2str(p->pinners, str, len) +#define pos_blockers2str(p, str, len) bb_sq2str(p->blockers, str, len) //void bitboard_print(bitboard_t bb, char *title); //void bitboard_print2(bitboard_t bb1, bitboard_t bb2, char *title); @@ -140,7 +144,9 @@ extern void pos_del(pos_t *pos); extern pos_t *pos_clear(pos_t *pos); extern bitboard_t pos_checkers(const pos_t *pos, const color_t color); -extern bitboard_t pos_pinners(const pos_t *pos, const color_t color); +extern bitboard_t pos_king_pinners(const pos_t *pos, const color_t color); +extern bitboard_t pos_king_blockers(const pos_t *pos, const color_t color, const bitboard_t ); +//extern bitboard_t set_king_pinners_blockers(pos_t *pos); //extern char *pos_checkers2str(const pos_t *pos, char *str); //extern char *pos_pinners2str(const pos_t *pos, char *str);