X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fbitboard.h;h=529e3dfe5f44e31e18099dfa85e372a11e31c76e;hp=8fa774818db69b71c34d5e357ce722dd7cdab1b6;hb=ddcbacd04d1c860e808202ce8c1206c8acdca627;hpb=dd4796fcd5559847d4b8aab7d21ffff9929799ce diff --git a/src/bitboard.h b/src/bitboard.h index 8fa77481..529e3dfe 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -2,7 +2,7 @@ Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad - Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad + Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -60,13 +60,22 @@ constexpr Bitboard Rank6BB = Rank1BB << (8 * 5); constexpr Bitboard Rank7BB = Rank1BB << (8 * 6); constexpr Bitboard Rank8BB = Rank1BB << (8 * 7); -extern int8_t SquareDistance[SQUARE_NB][SQUARE_NB]; +constexpr Bitboard QueenSide = FileABB | FileBBB | FileCBB | FileDBB; +constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB; +constexpr Bitboard KingSide = FileEBB | FileFBB | FileGBB | FileHBB; +constexpr Bitboard Center = (FileDBB | FileEBB) & (Rank4BB | Rank5BB); + +constexpr Bitboard KingFlank[FILE_NB] = { + QueenSide ^ FileDBB, QueenSide, QueenSide, + CenterFiles, CenterFiles, + KingSide, KingSide, KingSide ^ FileEBB +}; + +extern uint8_t PopCnt16[1 << 16]; +extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; extern Bitboard SquareBB[SQUARE_NB]; -extern Bitboard ForwardRanksBB[COLOR_NB][RANK_NB]; -extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; -extern Bitboard DistanceRingBB[SQUARE_NB][8]; extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; @@ -96,43 +105,35 @@ struct Magic { extern Magic RookMagics[SQUARE_NB]; extern Magic BishopMagics[SQUARE_NB]; +inline Bitboard square_bb(Square s) { + assert(s >= SQ_A1 && s <= SQ_H8); + return SquareBB[s]; +} /// Overloads of bitwise operators between a Bitboard and a Square for testing /// whether a given bit is set in a bitboard, and for setting and clearing bits. -inline Bitboard operator&(Bitboard b, Square s) { - assert(s >= SQ_A1 && s <= SQ_H8); - return b & SquareBB[s]; -} +inline Bitboard operator&( Bitboard b, Square s) { return b & square_bb(s); } +inline Bitboard operator|( Bitboard b, Square s) { return b | square_bb(s); } +inline Bitboard operator^( Bitboard b, Square s) { return b ^ square_bb(s); } +inline Bitboard& operator|=(Bitboard& b, Square s) { return b |= square_bb(s); } +inline Bitboard& operator^=(Bitboard& b, Square s) { return b ^= square_bb(s); } -inline Bitboard operator|(Bitboard b, Square s) { - assert(s >= SQ_A1 && s <= SQ_H8); - return b | SquareBB[s]; -} +inline Bitboard operator&(Square s, Bitboard b) { return b & s; } +inline Bitboard operator|(Square s, Bitboard b) { return b | s; } +inline Bitboard operator^(Square s, Bitboard b) { return b ^ s; } -inline Bitboard operator^(Bitboard b, Square s) { - assert(s >= SQ_A1 && s <= SQ_H8); - return b ^ SquareBB[s]; -} - -inline Bitboard& operator|=(Bitboard& b, Square s) { - assert(s >= SQ_A1 && s <= SQ_H8); - return b |= SquareBB[s]; -} - -inline Bitboard& operator^=(Bitboard& b, Square s) { - assert(s >= SQ_A1 && s <= SQ_H8); - return b ^= SquareBB[s]; -} +inline Bitboard operator|(Square s, Square s2) { return square_bb(s) | square_bb(s2); } constexpr bool more_than_one(Bitboard b) { return b & (b - 1); } -inline bool opposite_colors(Square s1, Square s2) { - return bool(DarkSquares & s1) != bool(DarkSquares & s2); +constexpr bool opposite_colors(Square s1, Square s2) { + return (s1 + rank_of(s1) + s2 + rank_of(s2)) & 1; } + /// rank_bb() and file_bb() return a bitboard representing all the squares on /// the given file or rank. @@ -153,11 +154,12 @@ inline Bitboard file_bb(Square s) { } -/// shift() moves a bitboard one step along direction D (mainly for pawns) +/// shift() moves a bitboard one or two steps as specified by the direction D template constexpr Bitboard shift(Bitboard b) { return D == NORTH ? b << 8 : D == SOUTH ? b >> 8 + : D == NORTH+NORTH? b <<16 : D == SOUTH+SOUTH? b >>16 : D == EAST ? (b & ~FileHBB) << 1 : D == WEST ? (b & ~FileABB) >> 1 : D == NORTH_EAST ? (b & ~FileHBB) << 9 : D == NORTH_WEST ? (b & ~FileABB) << 7 : D == SOUTH_EAST ? (b & ~FileHBB) >> 7 : D == SOUTH_WEST ? (b & ~FileABB) >> 9 @@ -165,8 +167,8 @@ constexpr Bitboard shift(Bitboard b) { } -/// pawn_attacks_bb() returns the pawn attacks for the given color from the -/// squares in the given bitboard. +/// pawn_attacks_bb() returns the squares attacked by pawns of the given color +/// from the squares in the given bitboard. template constexpr Bitboard pawn_attacks_bb(Bitboard b) { @@ -175,11 +177,11 @@ constexpr Bitboard pawn_attacks_bb(Bitboard b) { } -/// double_pawn_attacks_bb() returns the pawn attacks for the given color -/// from the squares in the given bitboard. +/// pawn_double_attacks_bb() returns the squares doubly attacked by pawns of the +/// given color from the squares in the given bitboard. template -constexpr Bitboard double_pawn_attacks_bb(Bitboard b) { +constexpr Bitboard pawn_double_attacks_bb(Bitboard b) { return C == WHITE ? shift(b) & shift(b) : shift(b) & shift(b); } @@ -188,52 +190,52 @@ constexpr Bitboard double_pawn_attacks_bb(Bitboard b) { /// adjacent_files_bb() returns a bitboard representing all the squares on the /// adjacent files of the given one. -inline Bitboard adjacent_files_bb(File f) { - return shift(file_bb(f)) | shift(file_bb(f)); +inline Bitboard adjacent_files_bb(Square s) { + return shift(file_bb(s)) | shift(file_bb(s)); } -/// between_bb() returns a bitboard representing all the squares between the two -/// given ones. For instance, between_bb(SQ_C4, SQ_F7) returns a bitboard with -/// the bits for square d5 and e6 set. If s1 and s2 are not on the same rank, file -/// or diagonal, 0 is returned. + +/// between_bb() returns squares that are linearly between the given squares +/// If the given squares are not on a same file/rank/diagonal, return 0. inline Bitboard between_bb(Square s1, Square s2) { - return BetweenBB[s1][s2]; + Bitboard b = LineBB[s1][s2] & ((AllSquares << s1) ^ (AllSquares << s2)); + return b & (b - 1); //exclude lsb } -/// forward_ranks_bb() returns a bitboard representing the squares on all the ranks +/// forward_ranks_bb() returns a bitboard representing the squares on the ranks /// in front of the given one, from the point of view of the given color. For instance, /// forward_ranks_bb(BLACK, SQ_D3) will return the 16 squares on ranks 1 and 2. inline Bitboard forward_ranks_bb(Color c, Square s) { - return ForwardRanksBB[c][rank_of(s)]; + return c == WHITE ? ~Rank1BB << 8 * (rank_of(s) - RANK_1) + : ~Rank8BB >> 8 * (RANK_8 - rank_of(s)); } -/// forward_file_bb() returns a bitboard representing all the squares along the line -/// in front of the given one, from the point of view of the given color: -/// ForwardFileBB[c][s] = forward_ranks_bb(c, s) & file_bb(s) +/// forward_file_bb() returns a bitboard representing all the squares along the +/// line in front of the given one, from the point of view of the given color. inline Bitboard forward_file_bb(Color c, Square s) { - return ForwardRanksBB[c][rank_of(s)] & file_bb(s); + return forward_ranks_bb(c, s) & file_bb(s); } -/// pawn_attack_span() returns a bitboard representing all the squares that can be -/// attacked by a pawn of the given color when it moves along its file, starting -/// from the given square: +/// pawn_attack_span() returns a bitboard representing all the squares that can +/// be attacked by a pawn of the given color when it moves along its file, +/// starting from the given square. inline Bitboard pawn_attack_span(Color c, Square s) { - return forward_ranks_bb(c, s) & adjacent_files_bb(file_of(s)); + return forward_ranks_bb(c, s) & adjacent_files_bb(s); } -/// passed_pawn_mask() returns a bitboard mask which can be used to test if a -/// pawn of the given color and on the given square is a passed pawn: +/// passed_pawn_span() returns a bitboard which can be used to test if a pawn of +/// the given color and on the given square is a passed pawn. -inline Bitboard passed_pawn_mask(Color c, Square s) { - return pawn_attack_span(c, s) | forward_file_bb(c, s); +inline Bitboard passed_pawn_span(Color c, Square s) { + return forward_ranks_bb(c, s) & (adjacent_files_bb(s) | file_bb(s)); } @@ -246,15 +248,15 @@ inline bool aligned(Square s1, Square s2, Square s3) { /// distance() functions return the distance between x and y, defined as the -/// number of steps for a king in x to reach y. Works with squares, ranks, files. +/// number of steps for a king in x to reach y. -template inline int distance(T x, T y) { return x < y ? y - x : x - y; } +template inline int distance(Square x, Square y); +template<> inline int distance(Square x, Square y) { return std::abs(file_of(x) - file_of(y)); } +template<> inline int distance(Square x, Square y) { return std::abs(rank_of(x) - rank_of(y)); } template<> inline int distance(Square x, Square y) { return SquareDistance[x][y]; } -template inline int distance(T2 x, T2 y); -template<> inline int distance(Square x, Square y) { return distance(file_of(x), file_of(y)); } -template<> inline int distance(Square x, Square y) { return distance(rank_of(x), rank_of(y)); } - +inline File edge_distance(File f) { return std::min(f, File(FILE_H - f)); } +inline Rank edge_distance(Rank r) { return std::min(r, Rank(RANK_8 - r)); } /// attacks_bb() returns a bitboard representing all the squares attacked by a /// piece of type Pt (bishop or rook) placed on 's'. @@ -286,7 +288,6 @@ inline int popcount(Bitboard b) { #ifndef USE_POPCNT - extern uint8_t PopCnt16[1 << 16]; union { Bitboard bb; uint16_t u[4]; } v = { b }; return PopCnt16[v.u[0]] + PopCnt16[v.u[1]] + PopCnt16[v.u[2]] + PopCnt16[v.u[3]]; @@ -374,16 +375,18 @@ inline Square msb(Bitboard b) { /// pop_lsb() finds and clears the least significant bit in a non-zero bitboard inline Square pop_lsb(Bitboard* b) { + assert(*b); const Square s = lsb(*b); *b &= *b - 1; return s; } -/// frontmost_sq() and backmost_sq() return the square corresponding to the -/// most/least advanced bit relative to the given color. - -inline Square frontmost_sq(Color c, Bitboard b) { return c == WHITE ? msb(b) : lsb(b); } -inline Square backmost_sq(Color c, Bitboard b) { return c == WHITE ? lsb(b) : msb(b); } +/// frontmost_sq() returns the most advanced square for the given color, +/// requires a non-zero bitboard. +inline Square frontmost_sq(Color c, Bitboard b) { + assert(b); + return c == WHITE ? msb(b) : lsb(b); +} #endif // #ifndef BITBOARD_H_INCLUDED