Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge pull request #11 from glinscott/squash

Add more detailed pawn shelter/storm evaluation

After 10670 games at 10"+0.05
Mod vs Orig 2277 - 1941 - 6452 ELO +11 !!!

The first real increase since 2.2.2, congratulations Gary !!!

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
  • Loading branch information...
commit cc2b3ece5c5d8d1183f8526fbb0ee4e1ea7a69fe 2 parents 22e294e + 374c9e6
Marco Costalba mcostalba authored

Showing 3 changed files with 102 additions and 16 deletions. Show diff stats Hide diff stats

  1. +26 0 src/bitboard.cpp
  2. +25 4 src/bitboard.h
  3. +51 12 src/pawns.cpp
26 src/bitboard.cpp
@@ -58,6 +58,7 @@ namespace {
58 58 CACHE_LINE_ALIGNMENT
59 59
60 60 int BSFTable[64];
  61 + int MS1BTable[256];
61 62 Bitboard RTable[0x19000]; // Storage space for rook attacks
62 63 Bitboard BTable[0x1480]; // Storage space for bishop attacks
63 64
@@ -140,6 +141,26 @@ Square pop_1st_bit(Bitboard* b) {
140 141
141 142 #endif // !defined(USE_BSFQ)
142 143
  144 +#if !defined(USE_BSFQ)
  145 +
  146 +Square last_1(Bitboard b) {
  147 + int result = 0;
  148 + if (b > 0xFFFFFFFF) {
  149 + b >>= 32;
  150 + result = 32;
  151 + }
  152 + if (b > 0xFFFF) {
  153 + b >>= 16;
  154 + result += 16;
  155 + }
  156 + if (b > 0xFF) {
  157 + b >>= 8;
  158 + result += 8;
  159 + }
  160 + return Square(result + MS1BTable[b]);
  161 +}
  162 +
  163 +#endif // !defined(USE_BSFQ)
143 164
144 165 /// bitboards_init() initializes various bitboard arrays. It is called during
145 166 /// program initialization.
@@ -196,6 +217,11 @@ void bitboards_init() {
196 217 else
197 218 BSFTable[((1ULL << i) * 0x218A392CD3D5DBFULL) >> 58] = i;
198 219
  220 + MS1BTable[0] = 0;
  221 + for (int i = 0, k = 1; i < 8; i++)
  222 + for (int j = 0; j < (1 << i); j++)
  223 + MS1BTable[k++] = i;
  224 +
199 225 int steps[][9] = { {}, { 7, 9 }, { 17, 15, 10, 6, -6, -10, -15, -17 },
200 226 {}, {}, {}, { 9, 7, -7, -9, 8, 1, -1, -8 } };
201 227
29 src/bitboard.h
@@ -214,7 +214,6 @@ inline bool single_bit(Bitboard b) {
214 214 return !(b & (b - 1));
215 215 }
216 216
217   -
218 217 /// first_1() finds the least significant nonzero bit in a nonzero bitboard.
219 218 /// pop_1st_bit() finds and clears the least significant nonzero bit in a
220 219 /// nonzero bitboard.
@@ -224,9 +223,15 @@ inline bool single_bit(Bitboard b) {
224 223 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
225 224
226 225 FORCE_INLINE Square first_1(Bitboard b) {
227   - unsigned long index;
228   - _BitScanForward64(&index, b);
229   - return (Square) index;
  226 + unsigned long index;
  227 + _BitScanForward64(&index, b);
  228 + return (Square) index;
  229 +}
  230 +
  231 +FORCE_INLINE Square last_1(Bitboard b) {
  232 + unsigned long index;
  233 + _BitScanReverse64(&index, b);
  234 + return (Square) index;
230 235 }
231 236 #else
232 237
@@ -235,6 +240,12 @@ FORCE_INLINE Square first_1(Bitboard b) { // Assembly code by Heinz van Saanen
235 240 __asm__("bsfq %1, %0": "=r"(dummy): "rm"(b) );
236 241 return (Square) dummy;
237 242 }
  243 +
  244 +FORCE_INLINE Square last_1(Bitboard b) {
  245 + Bitboard dummy;
  246 + __asm__("bsrq %1, %0": "=r"(dummy): "rm"(b) );
  247 + return (Square) dummy;
  248 +}
238 249 #endif
239 250
240 251 FORCE_INLINE Square pop_1st_bit(Bitboard* b) {
@@ -246,10 +257,20 @@ FORCE_INLINE Square pop_1st_bit(Bitboard* b) {
246 257 #else // if !defined(USE_BSFQ)
247 258
248 259 extern Square first_1(Bitboard b);
  260 +extern Square last_1(Bitboard b);
249 261 extern Square pop_1st_bit(Bitboard* b);
250 262
251 263 #endif
252 264
  265 +// relative_rank() returns the relative rank of the closest bit set on the Bitboard.
  266 +// Only to be used with bitboards that contain a single file.
  267 +
  268 +template<Color Us>
  269 +inline Rank relative_rank(Bitboard b) {
  270 + Square s = Us == WHITE ? first_1(b)
  271 + : ~last_1(b);
  272 + return rank_of(s);
  273 +}
253 274
254 275 extern void print_bitboard(Bitboard b);
255 276 extern void bitboards_init();
63 src/pawns.cpp
@@ -65,6 +65,19 @@ namespace {
65 65
66 66 #undef S
67 67
  68 + const File ShelterFile[8] = { FILE_B, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_G };
  69 +
  70 + inline Value score_non_center_file(const Value v) {
  71 + return Value(v * 7 / 16);
  72 + }
  73 +
  74 + typedef Value V;
  75 + // Arrays are indexed by rank. Zeroth value is for when no pawn on that file.
  76 + const Value PawnShelter[8] = { V(141), V(0), V( 38), V(102), V(128), V(141), V(141), V(141) };
  77 + const Value PawnStorm[8] = { V( 26), V(0), V(128), V( 51), V( 26), V( 0), V( 0), V( 0) };
  78 + // We compute shelter as a penalty for the given color, but shelter is used as a bonus, so we invert it using this as the basis.
  79 + const Value PawnShelterBasis = PawnShelter[0] + score_non_center_file(PawnShelter[0]) * 2;
  80 +
68 81 inline Score apply_weight(Score v, Score w) {
69 82 return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
70 83 (int(eg_value(v)) * eg_value(w)) / 0x100);
@@ -209,27 +222,53 @@ Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
209 222 return value;
210 223 }
211 224
  225 +template<Color Us>
  226 +int computePawnShelter(const Position &pos, Square ksq) {
  227 + const Color Them = (Us == WHITE ? BLACK : WHITE);
  228 + const File kingFile = ShelterFile[file_of(ksq)];
  229 + const Bitboard ourPawns = pos.pieces(PAWN, Us) & in_front_bb(Us, ksq);
  230 + const Bitboard theirPawns = pos.pieces(PAWN, Them) & (RankBB[rank_of(ksq)] | in_front_bb(Us, ksq));
  231 +
  232 + int shelter = 0;
  233 +
  234 + // Compute king shelter and storm values for the file the king is on, as well as the two adjacent files.
  235 + for (int fileOffset = -1; fileOffset <= 1; fileOffset++) {
  236 + // Shelter takes full penalty for center file, otherwise it's half penalty
  237 + Bitboard shelterFile = ourPawns & FileBB[kingFile + fileOffset];
  238 + Rank shelterClosest = shelterFile ? relative_rank<Us>(shelterFile)
  239 + : RANK_1;
  240 +
  241 + shelter += fileOffset == 0 ? PawnShelter[shelterClosest]
  242 + : score_non_center_file(PawnShelter[shelterClosest]);
  243 +
  244 + // Storm takes full penalty, unless there is an enemy pawn blocking us
  245 + Bitboard stormFile = theirPawns & FileBB[kingFile + fileOffset];
  246 + Rank stormClosest = stormFile ? relative_rank<Us>(stormFile)
  247 + : RANK_1;
  248 +
  249 + shelter += shelterClosest + 1 == stormClosest ? PawnStorm[stormClosest] / 2
  250 + : PawnStorm[stormClosest];
  251 + }
  252 +
  253 + return shelter;
  254 +}
212 255
213 256 /// PawnInfo::updateShelter() calculates and caches king shelter. It is called
214 257 /// only when king square changes, about 20% of total king_shelter() calls.
215 258 template<Color Us>
216 259 Score PawnInfo::updateShelter(const Position& pos, Square ksq) {
217   -
218   - const int Shift = (Us == WHITE ? 8 : -8);
219   -
220   - Bitboard pawns;
221   - int r, shelter = 0;
  260 + int shelter = 0;
222 261
223 262 if (relative_rank(Us, ksq) <= RANK_4)
224 263 {
225   - pawns = pos.pieces(PAWN, Us) & this_and_adjacent_files_bb(file_of(ksq));
226   - r = ksq & (7 << 3);
227   - for (int i = 0; i < 3; i++)
228   - {
229   - r += Shift;
230   - shelter += BitCount8Bit[(pawns >> r) & 0xFF] << (6 - i);
231   - }
  264 + shelter = computePawnShelter<Us>(pos, ksq);
  265 + if (pos.can_castle(Us == WHITE ? WHITE_OO : BLACK_OO))
  266 + shelter = std::min(shelter, computePawnShelter<Us>(pos, relative_square(Us, SQ_G1)));
  267 + if (pos.can_castle(Us == WHITE ? WHITE_OOO : BLACK_OOO))
  268 + shelter = std::min(shelter, computePawnShelter<Us>(pos, relative_square(Us, SQ_C1)));
  269 + shelter = PawnShelterBasis - shelter;
232 270 }
  271 +
233 272 kingSquares[Us] = ksq;
234 273 kingShelters[Us] = make_score(shelter, 0);
235 274 return kingShelters[Us];

0 comments on commit cc2b3ec

Please sign in to comment.
Something went wrong with that request. Please try again.