mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-17 19:22:18 +01:00
DroidFish: Updated stockfish engine to version 3.
This commit is contained in:
@@ -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-2012 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||
Copyright (C) 2008-2013 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
|
||||
@@ -31,7 +31,7 @@ namespace {
|
||||
|
||||
// Table used to drive the defending king towards the edge of the board
|
||||
// in KX vs K and KQ vs KR endgames.
|
||||
const int MateTable[64] = {
|
||||
const int MateTable[SQUARE_NB] = {
|
||||
100, 90, 80, 70, 70, 80, 90, 100,
|
||||
90, 70, 60, 50, 50, 60, 70, 90,
|
||||
80, 60, 40, 30, 30, 40, 60, 80,
|
||||
@@ -44,7 +44,7 @@ namespace {
|
||||
|
||||
// Table used to drive the defending king towards a corner square of the
|
||||
// right color in KBN vs K endgames.
|
||||
const int KBNKMateTable[64] = {
|
||||
const int KBNKMateTable[SQUARE_NB] = {
|
||||
200, 190, 180, 170, 160, 150, 140, 130,
|
||||
190, 180, 170, 160, 150, 140, 130, 140,
|
||||
180, 170, 155, 140, 140, 125, 140, 150,
|
||||
@@ -95,10 +95,12 @@ Endgames::Endgames() {
|
||||
add<KRKP>("KRKP");
|
||||
add<KRKB>("KRKB");
|
||||
add<KRKN>("KRKN");
|
||||
add<KQKP>("KQKP");
|
||||
add<KQKR>("KQKR");
|
||||
add<KBBKN>("KBBKN");
|
||||
|
||||
add<KNPK>("KNPK");
|
||||
add<KNPKB>("KNPKB");
|
||||
add<KRPKR>("KRPKR");
|
||||
add<KBPKB>("KBPKB");
|
||||
add<KBPKN>("KBPKN");
|
||||
@@ -132,7 +134,7 @@ Value Endgame<KXK>::operator()(const Position& pos) const {
|
||||
|
||||
// Stalemate detection with lone king
|
||||
if ( pos.side_to_move() == weakerSide
|
||||
&& !pos.in_check()
|
||||
&& !pos.checkers()
|
||||
&& !MoveList<LEGAL>(pos).size()) {
|
||||
return VALUE_DRAW;
|
||||
}
|
||||
@@ -169,12 +171,12 @@ Value Endgame<KBNK>::operator()(const Position& pos) const {
|
||||
|
||||
Square winnerKSq = pos.king_square(strongerSide);
|
||||
Square loserKSq = pos.king_square(weakerSide);
|
||||
Square bishopSquare = pos.piece_list(strongerSide, BISHOP)[0];
|
||||
Square bishopSq = pos.piece_list(strongerSide, BISHOP)[0];
|
||||
|
||||
// kbnk_mate_table() tries to drive toward corners A1 or H8,
|
||||
// if we have a bishop that cannot reach the above squares we
|
||||
// mirror the kings so to drive enemy toward corners A8 or H1.
|
||||
if (opposite_colors(bishopSquare, SQ_A1))
|
||||
if (opposite_colors(bishopSq, SQ_A1))
|
||||
{
|
||||
winnerKSq = mirror(winnerKSq);
|
||||
loserKSq = mirror(loserKSq);
|
||||
@@ -198,21 +200,21 @@ Value Endgame<KPK>::operator()(const Position& pos) const {
|
||||
assert(pos.piece_count(weakerSide, PAWN) == 0);
|
||||
|
||||
Square wksq, bksq, wpsq;
|
||||
Color stm;
|
||||
Color us;
|
||||
|
||||
if (strongerSide == WHITE)
|
||||
{
|
||||
wksq = pos.king_square(WHITE);
|
||||
bksq = pos.king_square(BLACK);
|
||||
wpsq = pos.piece_list(WHITE, PAWN)[0];
|
||||
stm = pos.side_to_move();
|
||||
us = pos.side_to_move();
|
||||
}
|
||||
else
|
||||
{
|
||||
wksq = ~pos.king_square(BLACK);
|
||||
bksq = ~pos.king_square(WHITE);
|
||||
wpsq = ~pos.piece_list(BLACK, PAWN)[0];
|
||||
stm = ~pos.side_to_move();
|
||||
us = ~pos.side_to_move();
|
||||
}
|
||||
|
||||
if (file_of(wpsq) >= FILE_E)
|
||||
@@ -222,7 +224,7 @@ Value Endgame<KPK>::operator()(const Position& pos) const {
|
||||
wpsq = mirror(wpsq);
|
||||
}
|
||||
|
||||
if (!Bitbases::probe_kpk(wksq, wpsq, bksq, stm))
|
||||
if (!Bitbases::probe_kpk(wksq, wpsq, bksq, us))
|
||||
return VALUE_DRAW;
|
||||
|
||||
Value result = VALUE_KNOWN_WIN + PawnValueEg + Value(rank_of(wpsq));
|
||||
@@ -326,6 +328,37 @@ Value Endgame<KRKN>::operator()(const Position& pos) const {
|
||||
}
|
||||
|
||||
|
||||
/// KQ vs KP. In general, a win for the stronger side, however, there are a few
|
||||
/// important exceptions. Pawn on 7th rank, A,C,F or H file, with king next can
|
||||
/// be a draw, so we scale down to distance between kings only.
|
||||
template<>
|
||||
Value Endgame<KQKP>::operator()(const Position& pos) const {
|
||||
|
||||
assert(pos.non_pawn_material(strongerSide) == QueenValueMg);
|
||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
||||
assert(pos.non_pawn_material(weakerSide) == 0);
|
||||
assert(pos.piece_count(weakerSide, PAWN) == 1);
|
||||
|
||||
Square winnerKSq = pos.king_square(strongerSide);
|
||||
Square loserKSq = pos.king_square(weakerSide);
|
||||
Square pawnSq = pos.piece_list(weakerSide, PAWN)[0];
|
||||
|
||||
Value result = QueenValueEg
|
||||
- PawnValueEg
|
||||
+ DistanceBonus[square_distance(winnerKSq, loserKSq)];
|
||||
|
||||
if ( square_distance(loserKSq, pawnSq) == 1
|
||||
&& relative_rank(weakerSide, pawnSq) == RANK_7)
|
||||
{
|
||||
File f = file_of(pawnSq);
|
||||
|
||||
if (f == FILE_A || f == FILE_C || f == FILE_F || f == FILE_H)
|
||||
result = Value(DistanceBonus[square_distance(winnerKSq, loserKSq)]);
|
||||
}
|
||||
return strongerSide == pos.side_to_move() ? result : -result;
|
||||
}
|
||||
|
||||
|
||||
/// KQ vs KR. This is almost identical to KX vs K: We give the attacking
|
||||
/// king a bonus for having the kings close together, and for forcing the
|
||||
/// defending king towards the edge. If we also take care to avoid null move
|
||||
@@ -439,6 +472,29 @@ ScaleFactor Endgame<KBPsK>::operator()(const Position& pos) const {
|
||||
return SCALE_FACTOR_DRAW;
|
||||
}
|
||||
}
|
||||
|
||||
// All pawns on same B or G file? Then potential draw
|
||||
if ( (pawnFile == FILE_B || pawnFile == FILE_G)
|
||||
&& !(pos.pieces(PAWN) & ~file_bb(pawnFile))
|
||||
&& pos.non_pawn_material(weakerSide) == 0
|
||||
&& pos.piece_count(weakerSide, PAWN) >= 1)
|
||||
{
|
||||
// Get weaker pawn closest to opponent's queening square
|
||||
Bitboard wkPawns = pos.pieces(weakerSide, PAWN);
|
||||
Square weakerPawnSq = strongerSide == WHITE ? msb(wkPawns) : lsb(wkPawns);
|
||||
|
||||
Square strongerKingSq = pos.king_square(strongerSide);
|
||||
Square weakerKingSq = pos.king_square(weakerSide);
|
||||
Square bishopSq = pos.piece_list(strongerSide, BISHOP)[0];
|
||||
|
||||
// Draw if weaker pawn is on rank 7, bishop can't attack the pawn, and
|
||||
// weaker king can stop opposing opponent's king from penetrating.
|
||||
if ( relative_rank(strongerSide, weakerPawnSq) == RANK_7
|
||||
&& opposite_colors(bishopSq, weakerPawnSq)
|
||||
&& square_distance(weakerPawnSq, weakerKingSq) <= square_distance(weakerPawnSq, strongerKingSq))
|
||||
return SCALE_FACTOR_DRAW;
|
||||
}
|
||||
|
||||
return SCALE_FACTOR_NONE;
|
||||
}
|
||||
|
||||
@@ -849,6 +905,24 @@ ScaleFactor Endgame<KNPK>::operator()(const Position& pos) const {
|
||||
}
|
||||
|
||||
|
||||
/// K, knight and a pawn vs K and bishop. If knight can block bishop from taking
|
||||
/// pawn, it's a win. Otherwise, drawn.
|
||||
template<>
|
||||
ScaleFactor Endgame<KNPKB>::operator()(const Position& pos) const {
|
||||
|
||||
Square pawnSq = pos.piece_list(strongerSide, PAWN)[0];
|
||||
Square bishopSq = pos.piece_list(weakerSide, BISHOP)[0];
|
||||
Square weakerKingSq = pos.king_square(weakerSide);
|
||||
|
||||
// King needs to get close to promoting pawn to prevent knight from blocking.
|
||||
// Rules for this are very tricky, so just approximate.
|
||||
if (forward_bb(strongerSide, pawnSq) & pos.attacks_from<BISHOP>(bishopSq))
|
||||
return ScaleFactor(square_distance(weakerKingSq, pawnSq));
|
||||
|
||||
return SCALE_FACTOR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/// K and a pawn vs K and a pawn. This is done by removing the weakest side's
|
||||
/// pawn and probing the KP vs K bitbase: If the weakest side has a draw without
|
||||
/// the pawn, she probably has at least a draw with the pawn as well. The exception
|
||||
@@ -865,14 +939,14 @@ ScaleFactor Endgame<KPKP>::operator()(const Position& pos) const {
|
||||
Square wksq = pos.king_square(strongerSide);
|
||||
Square bksq = pos.king_square(weakerSide);
|
||||
Square wpsq = pos.piece_list(strongerSide, PAWN)[0];
|
||||
Color stm = pos.side_to_move();
|
||||
Color us = pos.side_to_move();
|
||||
|
||||
if (strongerSide == BLACK)
|
||||
{
|
||||
wksq = ~wksq;
|
||||
bksq = ~bksq;
|
||||
wpsq = ~wpsq;
|
||||
stm = ~stm;
|
||||
us = ~us;
|
||||
}
|
||||
|
||||
if (file_of(wpsq) >= FILE_E)
|
||||
@@ -890,5 +964,5 @@ ScaleFactor Endgame<KPKP>::operator()(const Position& pos) const {
|
||||
|
||||
// Probe the KPK bitbase with the weakest side's pawn removed. If it's a draw,
|
||||
// it's probably at least a draw even with the pawn.
|
||||
return Bitbases::probe_kpk(wksq, wpsq, bksq, stm) ? SCALE_FACTOR_NONE : SCALE_FACTOR_DRAW;
|
||||
return Bitbases::probe_kpk(wksq, wpsq, bksq, us) ? SCALE_FACTOR_NONE : SCALE_FACTOR_DRAW;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user