X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fendgame.cpp;h=4d93811e7c5d15fa2fc47d1ab16e97377a448d29;hb=23490bd825d60564b1368b6a7e3df7d86a772bf0;hp=76fb597aa096aad7a3431b3b72d33ebf43bcd8c3;hpb=760f77872f3b266c16baa7b53e592e9603735479;p=stockfish diff --git a/src/endgame.cpp b/src/endgame.cpp index 76fb597a..4d93811e 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -1,13 +1,14 @@ /* - Glaurung, a UCI chess playing engine. - Copyright (C) 2004-2008 Tord Romstad + Stockfish, a UCI chess playing engine derived from Glaurung 2.1 + Copyright (C) 2004-2008 Tord Romstad (Glaurung author) + Copyright (C) 2008 Marco Costalba - Glaurung is free software: you can redistribute it and/or modify + Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Glaurung is distributed in the hope that it will be useful, + Stockfish is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -61,6 +62,13 @@ KRKNEvaluationFunction EvaluateKNKR = KRKNEvaluationFunction(BLACK); KQKREvaluationFunction EvaluateKQKR = KQKREvaluationFunction(WHITE); KQKREvaluationFunction EvaluateKRKQ = KQKREvaluationFunction(BLACK); +// KBB vs KN: +KBBKNEvaluationFunction EvaluateKBBKN = KBBKNEvaluationFunction(WHITE); +KBBKNEvaluationFunction EvaluateKNKBB = KBBKNEvaluationFunction(BLACK); + +// K and two minors vs K and one or two minors: +KmmKmEvaluationFunction EvaluateKmmKm = KmmKmEvaluationFunction(WHITE); + /// Scaling functions @@ -186,6 +194,8 @@ KRKPEvaluationFunction::KRKPEvaluationFunction(Color c) : EndgameEvaluationFunct KRKBEvaluationFunction::KRKBEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { } KRKNEvaluationFunction::KRKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { } KQKREvaluationFunction::KQKREvaluationFunction(Color c) : EndgameEvaluationFunction(c) { } +KBBKNEvaluationFunction::KBBKNEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { } +KmmKmEvaluationFunction::KmmKmEvaluationFunction(Color c) : EndgameEvaluationFunction(c) { } ScalingFunction::ScalingFunction(Color c) { @@ -419,6 +429,36 @@ Value KQKREvaluationFunction::apply(const Position &pos) { } +Value KBBKNEvaluationFunction::apply(const Position &pos) { + assert(pos.piece_count(strongerSide, BISHOP) == 2); + assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame); + assert(pos.piece_count(weakerSide, KNIGHT) == 1); + assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame); + assert(pos.pawns() == EmptyBoardBB); + + Value result = BishopValueEndgame; + Square wksq = pos.king_square(strongerSide); + Square bksq = pos.king_square(weakerSide); + Square nsq = pos.piece_list(weakerSide, KNIGHT, 0); + + // Bonus for attacking king close to defending king + result += distance_bonus(square_distance(wksq, bksq)); + + // Bonus for driving the defending king and knight apart + result += Value(square_distance(bksq, nsq) * 32); + + // Bonus for restricting the knight's mobility + result += Value((8 - count_1s_max_15(pos.piece_attacks(nsq))) * 8); + + return (strongerSide == pos.side_to_move())? result : -result; +} + + +Value KmmKmEvaluationFunction::apply(const Position &pos) { + return Value(0); +} + + /// KBPKScalingFunction scales endgames where the stronger side has king, /// bishop and one or more pawns. It checks for draws with rook pawns and a /// bishop of the wrong color. If such a draw is detected, ScaleFactor(0) is @@ -603,6 +643,16 @@ ScaleFactor KRPKRScalingFunction::apply(const Position &pos) { - (8 * square_distance(wpsq, queeningSq) + 2 * square_distance(wksq, queeningSq))); + // If the pawn is not far advanced, and the defending king is somewhere in + // the pawn's path, it's probably a draw: + if(r <= RANK_4 && bksq > wpsq) { + if(square_file(bksq) == square_file(wpsq)) + return ScaleFactor(10); + if(abs(square_file(bksq) - square_file(wpsq)) == 1 + && square_distance(wksq, bksq) > 2) + return ScaleFactor(24 - 2 * square_distance(wksq, bksq)); + } + return SCALE_FACTOR_NONE; }