+template<Color Us>
+int computePawnShelter(const Position &pos, Square ksq) {
+ const Color Them = (Us == WHITE ? BLACK : WHITE);
+ const File kingFile = ShelterFile[file_of(ksq)];
+ const Bitboard ourPawns = pos.pieces(PAWN, Us) & in_front_bb(Us, ksq);
+ const Bitboard theirPawns = pos.pieces(PAWN, Them) & (RankBB[rank_of(ksq)] | in_front_bb(Us, ksq));
+
+ int shelter = 0;
+
+ // Compute king shelter and storm values for the file the king is on, as well as the two adjacent files.
+ for (int fileOffset = -1; fileOffset <= 1; fileOffset++) {
+ // Shelter takes full penalty for center file, otherwise it's half penalty
+ Bitboard shelterFile = ourPawns & FileBB[kingFile + fileOffset];
+ Rank shelterClosest = shelterFile ? relative_rank<Us>(shelterFile)
+ : RANK_1;
+
+ shelter += fileOffset == 0 ? PawnShelter[shelterClosest]
+ : score_non_center_file(PawnShelter[shelterClosest]);
+
+ // Storm takes full penalty, unless there is an enemy pawn blocking us
+ Bitboard stormFile = theirPawns & FileBB[kingFile + fileOffset];
+ Rank stormClosest = stormFile ? relative_rank<Us>(stormFile)
+ : RANK_1;
+
+ shelter += shelterClosest + 1 == stormClosest ? PawnStorm[stormClosest] / 2
+ : PawnStorm[stormClosest];
+ }
+
+ return shelter;
+}