/// Entry::shelter_storm() calculates shelter and storm penalties for the file /// the king is on, as well as the two adjacent files. public Value shelter_storm(Position pos, Square ksq, Color Us) { Color Them = (Us == ColorS.WHITE ? ColorS.BLACK : ColorS.WHITE); Value safety = Pawns.MaxSafetyBonus; Bitboard b = pos.pieces_piecetype(PieceTypeS.PAWN) & (BitBoard.in_front_bb(Us, Types.rank_of(ksq)) | BitBoard.rank_bb_square(ksq)); Bitboard ourPawns = b & pos.pieces_color(Us); Bitboard theirPawns = b & pos.pieces_color(Them); Rank rkUs, rkThem; File kf = Math.Max(FileS.FILE_B, Math.Min(FileS.FILE_G, Types.file_of(ksq))); for (File f = kf - 1; f <= kf + 1; ++f) { b = ourPawns & BitBoard.file_bb_file(f); rkUs = b != 0 ? Types.relative_rank_square(Us, BitBoard.backmost_sq(Us, b)) : RankS.RANK_1; b = theirPawns & BitBoard.file_bb_file(f); rkThem = b != 0 ? Types.relative_rank_square(Us, BitBoard.frontmost_sq(Them, b)) : RankS.RANK_1; if ((MiddleEdges & BitBoard.SquareBB[Types.make_square(f, rkThem)]) != 0 && Types.file_of(ksq) == f && Types.relative_rank_square(Us, ksq) == rkThem - 1) { safety += 200; } else { safety -= ShelterWeakness[rkUs] + StormDanger[rkUs == RankS.RANK_1 ? 0 : rkThem == rkUs + 1 ? 2 : 1][rkThem]; } } return(safety); }
/// K and two or more pawns vs K. There is just a single rule here: If all pawns /// are on the same rook file and are blocked by the defending king, it's a draw. public ScaleFactor KPsK(Position pos) { Debug.Assert(pos.non_pawn_material(strongSide) == ValueS.VALUE_ZERO); Debug.Assert(pos.count(strongSide, PieceTypeS.PAWN) >= 2); Debug.Assert(verify_material(pos, weakSide, ValueS.VALUE_ZERO, 0)); Square ksq = pos.king_square(weakSide); Bitboard pawns = pos.pieces_color_piecetype(strongSide, PieceTypeS.PAWN); Square psq = pos.list(strongSide, PieceTypeS.PAWN)[0]; // If all pawns are ahead of the king, on a single rook file and // the king is within one file of the pawns, it's a draw. if (0 == (pawns & ~BitBoard.in_front_bb(weakSide, Types.rank_of(ksq))) && !((pawns & ~BitBoard.FileABB) != 0 && (pawns & ~BitBoard.FileHBB) != 0) && BitBoard.file_distance(ksq, psq) <= 1) { return(ScaleFactorS.SCALE_FACTOR_DRAW); } return(ScaleFactorS.SCALE_FACTOR_NONE); }