From: Marco Costalba Date: Sun, 21 Dec 2008 14:38:10 +0000 (+0100) Subject: Merged two new endgames from Glaurung 2.2 X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=f178f0a2912082e2e9d07d9b0926031322d78f67;hp=72ca727b382212705d2a31588d03eb0c85abddba Merged two new endgames from Glaurung 2.2 It is two bishop against a knight and two minor pieces against one minor piece. Signed-off-by: Marco Costalba --- diff --git a/src/endgame.cpp b/src/endgame.cpp index 11f060bb..4d93811e 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -62,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 @@ -187,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) { @@ -420,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 @@ -604,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; } diff --git a/src/endgame.h b/src/endgame.h index dabf233e..dc477288 100644 --- a/src/endgame.h +++ b/src/endgame.h @@ -99,6 +99,20 @@ public: Value apply(const Position &pos); }; +// KBB vs KN: +class KBBKNEvaluationFunction : public EndgameEvaluationFunction { +public: + KBBKNEvaluationFunction(Color C); + Value apply(const Position &pos); +}; + +// K and two minors vs K and one or two minors: +class KmmKmEvaluationFunction : public EndgameEvaluationFunction { +public: + KmmKmEvaluationFunction(Color c); + Value apply(const Position &pos); +}; + /// Abstract base class for all evaluation scaling functions: @@ -205,6 +219,12 @@ extern KRKNEvaluationFunction EvaluateKRKN, EvaluateKNKR; // KQ vs KR: extern KQKREvaluationFunction EvaluateKQKR, EvaluateKRKQ; +// KBB vs KN: +extern KBBKNEvaluationFunction EvaluateKBBKN, EvaluateKNKBB; + +// K and two minors vs K and one or two minors: +extern KmmKmEvaluationFunction EvaluateKmmKm; + // KBP vs K: extern KBPKScalingFunction ScaleKBPK, ScaleKKBP; diff --git a/src/material.cpp b/src/material.cpp index 595eee29..11fd3c9b 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -161,6 +161,22 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) { mi->evaluationFunction = &EvaluateKKX; return mi; } + else if ( pos.pawns() == EmptyBoardBB + && pos.rooks() == EmptyBoardBB + && pos.queens() == EmptyBoardBB) + { + // Minor piece endgame with at least one minor piece per side, + // and no pawns. + assert(pos.knights(WHITE) | pos.bishops(WHITE)); + assert(pos.knights(BLACK) | pos.bishops(BLACK)); + + if ( pos.piece_count(WHITE, BISHOP) + pos.piece_count(WHITE, KNIGHT) <= 2 + && pos.piece_count(BLACK, BISHOP) + pos.piece_count(BLACK, KNIGHT) <= 2) + { + mi->evaluationFunction = &EvaluateKmmKm; + return mi; + } + } // OK, we didn't find any special evaluation function for the current // material configuration. Is there a suitable scaling function? @@ -309,6 +325,8 @@ EndgameFunctions::EndgameFunctions() { add(z[W][KNIGHT][1] ^ z[B][ROOK][1], &EvaluateKNKR); add(z[W][QUEEN][1] ^ z[B][ROOK][1], &EvaluateKQKR); add(z[W][ROOK][1] ^ z[B][QUEEN][1], &EvaluateKRKQ); + add(z[W][BISHOP][2] ^ z[B][KNIGHT][1], &EvaluateKBBKN); + add(z[W][KNIGHT][1] ^ z[B][BISHOP][2], &EvaluateKNKBB); add(z[W][KNIGHT][1] ^ z[W][PAWN][1], W, &ScaleKNPK); add(z[B][KNIGHT][1] ^ z[B][PAWN][1], B, &ScaleKKNP);