X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fendgame.cpp;h=763a402e7bd3a4683b0e49a05b989877b68f9da5;hp=ac11b76e5f9568bc6b8d8c0ed8418c504c251104;hb=dda0fa1a43e1096415ff8f83dd14e6322f1a8e68;hpb=4554d8b2ac1ad260c3f7123b2a7d3a3385fa8306 diff --git a/src/endgame.cpp b/src/endgame.cpp index ac11b76e..763a402e 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -1,7 +1,7 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) - Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2008-2012 Marco Costalba, Joona Kiiski, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ #include "bitcount.h" #include "endgame.h" -#include "pawns.h" +#include "movegen.h" using std::string; @@ -116,10 +116,8 @@ Endgames::~Endgames() { template void Endgames::add(const string& code) { - typedef typename eg_family::type T; - - map((T*)0)[key(code, WHITE)] = new Endgame(WHITE); - map((T*)0)[key(code, BLACK)] = new Endgame(BLACK); + map((Endgame*)0)[key(code, WHITE)] = new Endgame(WHITE); + map((Endgame*)0)[key(code, BLACK)] = new Endgame(BLACK); } @@ -133,6 +131,13 @@ Value Endgame::operator()(const Position& pos) const { assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO); assert(pos.piece_count(weakerSide, PAWN) == VALUE_ZERO); + // Stalemate detection with lone king + if ( pos.side_to_move() == weakerSide + && !pos.in_check() + && !MoveList(pos).size()) { + return VALUE_DRAW; + } + Square winnerKSq = pos.king_square(strongerSide); Square loserKSq = pos.king_square(weakerSide); @@ -143,9 +148,9 @@ Value Endgame::operator()(const Position& pos) const { if ( pos.piece_count(strongerSide, QUEEN) || pos.piece_count(strongerSide, ROOK) - || pos.piece_count(strongerSide, BISHOP) > 1) - // TODO: check for two equal-colored bishops! - result += VALUE_KNOWN_WIN; + || pos.both_color_bishops(strongerSide)) { + result += VALUE_KNOWN_WIN; + } return strongerSide == pos.side_to_move() ? result : -result; } @@ -205,10 +210,10 @@ Value Endgame::operator()(const Position& pos) const { } else { - wksq = flip(pos.king_square(BLACK)); - bksq = flip(pos.king_square(WHITE)); - wpsq = flip(pos.piece_list(BLACK, PAWN)[0]); - stm = flip(pos.side_to_move()); + wksq = ~pos.king_square(BLACK); + bksq = ~pos.king_square(WHITE); + wpsq = ~pos.piece_list(BLACK, PAWN)[0]; + stm = ~pos.side_to_move(); } if (file_of(wpsq) >= FILE_E) @@ -251,10 +256,10 @@ Value Endgame::operator()(const Position& pos) const { if (strongerSide == BLACK) { - wksq = flip(wksq); - wrsq = flip(wrsq); - bksq = flip(bksq); - bpsq = flip(bpsq); + wksq = ~wksq; + wrsq = ~wrsq; + bksq = ~bksq; + bpsq = ~bpsq; } Square queeningSq = make_square(file_of(bpsq), RANK_1); @@ -369,7 +374,7 @@ Value Endgame::operator()(const Position& pos) const { result += Value(square_distance(bksq, nsq) * 32); // Bonus for restricting the knight's mobility - result += Value((8 - count_1s(pos.attacks_from(nsq))) * 8); + result += Value((8 - popcount(pos.attacks_from(nsq))) * 8); return strongerSide == pos.side_to_move() ? result : -result; } @@ -416,7 +421,7 @@ ScaleFactor Endgame::operator()(const Position& pos) const { && abs(file_of(kingSq) - pawnFile) <= 1) { // The bishop has the wrong color, and the defending king is on the - // file of the pawn(s) or the neighboring file. Find the rank of the + // file of the pawn(s) or the adjacent file. Find the rank of the // frontmost pawn. Rank rank; if (strongerSide == WHITE) @@ -491,11 +496,11 @@ ScaleFactor Endgame::operator()(const Position& pos) const { // pawn is on the left half of the board. if (strongerSide == BLACK) { - wksq = flip(wksq); - wrsq = flip(wrsq); - wpsq = flip(wpsq); - bksq = flip(bksq); - brsq = flip(brsq); + wksq = ~wksq; + wrsq = ~wrsq; + wpsq = ~wpsq; + bksq = ~bksq; + brsq = ~brsq; } if (file_of(wpsq) > FILE_D) { @@ -768,7 +773,7 @@ ScaleFactor Endgame::operator()(const Position& pos) const { return SCALE_FACTOR_NONE; case 1: - // Pawns on neighboring files. Draw if defender firmly controls the square + // Pawns on adjacent files. Draw if defender firmly controls the square // in front of the frontmost pawn's path, and the square diagonally behind // this square on the file of the other pawn. if ( ksq == blockSq1 @@ -867,10 +872,10 @@ ScaleFactor Endgame::operator()(const Position& pos) const { if (strongerSide == BLACK) { - wksq = flip(wksq); - bksq = flip(bksq); - wpsq = flip(wpsq); - stm = flip(stm); + wksq = ~wksq; + bksq = ~bksq; + wpsq = ~wpsq; + stm = ~stm; } if (file_of(wpsq) >= FILE_E)