From f2ce20a50437aed5d716b3cb7c18d4ae0accb119 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Tue, 9 Apr 2024 08:08:13 +0200 Subject: [PATCH] add bb_pawn_attacks[][], bb_shift() --- src/attack.c | 5 +---- src/bitboard.c | 20 +++++++++++--------- src/bitboard.h | 22 +++++++++++++++++++--- src/chessdefs.h | 1 + test/bitboard-test.c | 24 ++++++++++++++++-------- test/common-test.h | 4 ---- test/perft-test.c | 2 -- 7 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/attack.c b/src/attack.c index 150d14d..d6177cd 100644 --- a/src/attack.c +++ b/src/attack.c @@ -43,9 +43,6 @@ bool sq_is_attacked(const pos_t *pos, const bitboard_t occ, const square_t sq, c bitboard_t sqbb = mask(sq); color_t opp = OPPONENT(c); - - //pos_print_raw(pos, 1); - /* bishop / queen */ if (hyperbola_bishop_moves(occ, sq) & (pos->bb[c][BISHOP] | pos->bb[c][QUEEN])) return true; @@ -55,7 +52,7 @@ bool sq_is_attacked(const pos_t *pos, const bitboard_t occ, const square_t sq, c return true; /* pawn */ - if ((pawn_shift_upleft(sqbb, opp) | pawn_shift_upright(sqbb, opp)) & pos->bb[c][PAWN]) + if (bb_pawn_attacks[opp][sq] & pos->bb[c][PAWN]) return true; /* knight */ diff --git a/src/bitboard.c b/src/bitboard.c index 984ccbb..ab919b0 100644 --- a/src/bitboard.c +++ b/src/bitboard.c @@ -27,7 +27,7 @@ bitboard_t bb_between_excl[64][64]; bitboard_t bb_between[64][64]; bitboard_t bb_line[64][64]; -bitboard_t bb_knight[64], bb_king[64]; +bitboard_t bb_knight[64], bb_king[64], bb_pawn_attacks[2][64]; /* vectors are clockwise from N */ static int knight_vector[] = { @@ -105,7 +105,9 @@ void bitboard_init(void) } ; bitboard_t tmpbb[64][4] = { 0 }; - /* 1) square to bitboard, and in-between-sq2-excluded */ + /* 1) square to bitboard + * in-between, sq2 excluded + */ for (square_t sq1 = A1; sq1 <= H8; ++sq1) { bb_sq[sq1] = mask(sq1); for (square_t sq2 = A1; sq2 <= H8; ++sq2) @@ -151,18 +153,18 @@ void bitboard_init(void) bb_line[sq1][sq2] = bb_sqdiag[sq1]; else if (bb_sqanti[sq1] == bb_sqanti[sq2]) bb_line[sq1][sq2] = bb_sqanti[sq1]; - - //if (bb_line[sq1][sq2]) { - // printf("bb_line[%d][%d] = %16lx\n", sq1, sq2, bb_line[sq1][sq2]); - //} } } } - /* 3) knight and king moves */ + /* 3) pawn, knight and king attacks + */ for (square_t sq = A1; sq <= H8; ++sq) { - //rank_t r1 = sq_rank(sq); - //file_t f1 = sq_file(sq); + if (sq >= A2 && sq <= H7) { + bb_pawn_attacks[WHITE][sq] = pawn_attacks_bb(mask(sq), WHITE); + bb_pawn_attacks[BLACK][sq] = pawn_attacks_bb(mask(sq), BLACK); + } + for (int vec = 0; vec < 8; ++vec) { int dst = sq + knight_vector[vec]; if (sq_ok(dst)) { diff --git a/src/bitboard.h b/src/bitboard.h index 3b2b563..a7000fc 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -39,9 +39,8 @@ extern bitboard_t bb_sqrank[64], bb_sqfile[64], bb_sqdiag[64], bb_sqanti[64]; /* line (rank, file, diagonal or anti-diagonal) between two squares */ extern bitboard_t bb_line[64][64]; -/* knight and king moves */ -extern bitboard_t bb_knight[64], bb_king[64]; - +/* pawn, knight and king attacks */ +extern bitboard_t bb_knight[64], bb_king[64], bb_pawn_attacks[2][64]; /* TODO (maybe C23?) when we can ensure an enum can be u64 * @@ -222,11 +221,25 @@ static __always_inline bool bb_multiple(bitboard_t bb) return !!(bb & (bb - 1)); } +/** + * bb_shift() - shift bitboard + * @bb: bitboard + * + * No control is done on off-board shifting (i.e. shifting -1 from A2 gives H3). + * + * @return: true if @bb has more than 1 bit, false otherwise. + */ +static __always_inline bitboard_t bb_shift(bitboard_t bb, int shift) +{ + return shift >= 0 ? bb << shift : bb >> -shift; +} + #define bb_rank(r) ((u64) RANK_1bb << ((r) * 8)) #define bb_file(f) ((u64) FILE_Abb << (f)) #define bb_rel_rank(r, c) bb_rank(sq_rel_rank(r, c)) +#define bb_rel_file(f, c) bb_file(sq_rel_rank(f, c)) /** * bb_sq_aligned() - check if two squares are aligned (same file or rank). @@ -301,6 +314,9 @@ 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)) + /* pawn move (for single pawn) - NO SQUARE CONTROL HERE ! * Need to make functions with control instead. */ diff --git a/src/chessdefs.h b/src/chessdefs.h index f891ae0..476ff1e 100644 --- a/src/chessdefs.h +++ b/src/chessdefs.h @@ -45,6 +45,7 @@ * @return: Relative rank. */ #define sq_rel_rank(rank, c) ((rank_t)((7 * (c)) ^ rank)) +#define sq_rel_file(file, c) ((file_t)((7 * (c)) ^ file)) /* castle_t bits structure */ diff --git a/test/bitboard-test.c b/test/bitboard-test.c index 762056d..cd27540 100644 --- a/test/bitboard-test.c +++ b/test/bitboard-test.c @@ -46,16 +46,24 @@ int main(int __unused ac, __unused char**av) sprintf(str, "between: %-22s%-22s%-22s%-22s%-22s%-22s%-22s%-22s", "c3-c6", "c3-f6", "c3-f3", "c3-e1", "c3-c1", "c3-a1", "c3-a3", "c3-a5"); bb_print_multi(str, 8, - bb_between[C3][C6], bb_between[C3][F6], - bb_between[C3][F3], bb_between[C3][E1], - bb_between[C3][C1], bb_between[C3][A1], - bb_between[C3][A3], bb_between[C3][A5]); + bb_between[C3][C6], bb_between[C3][F6], + bb_between[C3][F3], bb_between[C3][E1], + bb_between[C3][C1], bb_between[C3][A1], + bb_between[C3][A3], bb_between[C3][A5]); sprintf(str, "between: %-22s%-22s%-22s%-22s%-22s%-22s%-22s%-22s", "c4-c6", "c4-f6", "c4-f3", "c4-e1", "c4-c1", "c4-a1", "c4-a3", "c4-a5"); bb_print_multi(str, 8, - bb_between[C4][C6], bb_between[C4][F6], - bb_between[C4][F3], bb_between[C4][E1], - bb_between[C4][C1], bb_between[C4][A1], - bb_between[C4][A3], bb_between[C4][A5]); + bb_between[C4][C6], bb_between[C4][F6], + bb_between[C4][F3], bb_between[C4][E1], + bb_between[C4][C1], bb_between[C4][A1], + bb_between[C4][A3], bb_between[C4][A5]); + sprintf(str, "Pwn att: %-22s%-22s%-22s%-22s%-22s%-22s%-22s%-22s", + "White a2", "Black a2", "White h7", "Black h7", + "White c3", "Black c3", "White e5", "Black e5"); + bb_print_multi(str, 8, + bb_pawn_attacks[WHITE][A2], bb_pawn_attacks[BLACK][A2], + bb_pawn_attacks[WHITE][H7], bb_pawn_attacks[BLACK][H7], + bb_pawn_attacks[WHITE][C3], bb_pawn_attacks[BLACK][C3], + bb_pawn_attacks[WHITE][E5], bb_pawn_attacks[BLACK][E5]); return 0; } diff --git a/test/common-test.h b/test/common-test.h index d433c32..5ac181b 100644 --- a/test/common-test.h +++ b/test/common-test.h @@ -391,10 +391,6 @@ struct fentest { "simple movedo/undo: only 2 W knights", "8/1k6/8/8/8/8/6K1/1NN5 w - - 0 1" }, - { __LINE__, MOVEDO | PERFT, - "simple movedo/undo: only 2 W knights", - "8/1k6/8/8/8/8/6K1/1NN5 w - - 0 1" - }, { __LINE__, MOVEDO | PERFT, "simple movedo/undo: only 2 W knights", "5n2/1k6/8/8/5K2/8/P7/1N6 w - - 0 1" diff --git a/test/perft-test.c b/test/perft-test.c index ea2c807..1ff0669 100644 --- a/test/perft-test.c +++ b/test/perft-test.c @@ -262,9 +262,7 @@ int main(int __unused ac, __unused char**av) continue; } sf_count = send_stockfish_fen(outfd, fishpos, &fishmoves, fen, depth); - //pos_gen_pseudomoves(pos, &pseudo); savepos = pos_dup(pos); - //int j = 0; if (run & 1) { clock_start(&clock);