Example #1
0
            /// 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);
        }