Skip to content

Commit

Permalink
Added King of the Hill variant support (based on SCIDB 3-checks varia…
Browse files Browse the repository at this point in the history
…nt code)
  • Loading branch information
ddugovic committed Jul 31, 2014
1 parent 5adc678 commit 59e8c59
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Makefile
Expand Up @@ -207,6 +207,7 @@ ifneq ($(comp),mingw)
endif

### 3.4 Debugging
CXXFLAGS += -DKOTH
ifeq ($(debug),no)
CXXFLAGS += -DNDEBUG
else
Expand Down
4 changes: 4 additions & 0 deletions src/benchmark.cpp
Expand Up @@ -133,7 +133,11 @@ void benchmark(const Position& current, istream& is) {

for (size_t i = 0; i < fens.size(); ++i)
{
#ifdef KOTH
Position pos(fens[i], Options["UCI_Chess960"], Options["UCI_VariantKOTH"], Threads.main());
#else
Position pos(fens[i], Options["UCI_Chess960"], Threads.main());
#endif

cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;

Expand Down
4 changes: 4 additions & 0 deletions src/endgame.cpp
Expand Up @@ -96,7 +96,11 @@ namespace {
string fen = sides[0] + char(8 - sides[0].length() + '0') + "/8/8/8/8/8/8/"
+ sides[1] + char(8 - sides[1].length() + '0') + " w - - 0 10";

#ifdef KOTH
return Position(fen, NULL).material_key();
#else
return Position(fen, false, NULL).material_key();
#endif
}

template<typename M>
Expand Down
29 changes: 29 additions & 0 deletions src/evaluate.cpp
Expand Up @@ -153,6 +153,15 @@ namespace {
// Hanging contains a bonus for each enemy hanging piece
const Score Hanging = S(23, 20);

#ifdef KOTH
const Score KOTHDistanceBonus[4] = {
S(9*PawnValueMg + PawnValueMg/2, 9*PawnValueEg),
S(4*PawnValueMg + PawnValueMg/2, 4*PawnValueEg),
S(2*PawnValueMg + PawnValueMg/2, 2*PawnValueEg),
S(0, 0)
};
#endif

#undef S

const Score RookOnPawn = make_score(10, 28);
Expand Down Expand Up @@ -394,6 +403,15 @@ namespace {
// King shelter and enemy pawns storm
Score score = ei.pi->king_safety<Us>(pos, ksq);

#ifdef KOTH
if (pos.is_koth())
{
// Initial attempt to adjust score based on KOTH distance
score += KOTHDistanceBonus[pos.koth_distance(Us)];
score -= KOTHDistanceBonus[pos.koth_distance(Them)];
}
#endif

// Main king safety evaluation
if (ei.kingAttackersCount[Them])
{
Expand Down Expand Up @@ -680,6 +698,17 @@ namespace {
// Score is computed from the point of view of white.
score = pos.psq_score();

#ifdef KOTH
if (pos.is_koth())
{
// TODO: Do we need or want both conditions here?
if (pos.is_koth_win())
return VALUE_MATE;
if (pos.is_koth_loss())
return -VALUE_MATE;
}
#endif

// Probe the material hash table
ei.mi = Material::probe(pos, thisThread->materialTable, thisThread->endgames);
score += ei.mi->material_value();
Expand Down
8 changes: 8 additions & 0 deletions src/movepick.cpp
Expand Up @@ -302,6 +302,14 @@ void MovePicker::generate_next_stage() {
template<>
Move MovePicker::next_move<false>() {

#ifdef KOTH
assert(!pos.is_koth_win());

// Best move can only be MOVE_NONE when searching on a lost KOTH position
if (pos.is_koth_loss())
return MOVE_NONE;
#endif

Move move;

while (true)
Expand Down
15 changes: 15 additions & 0 deletions src/position.cpp
Expand Up @@ -191,7 +191,11 @@ void Position::clear() {
/// This function is not very robust - make sure that input FENs are correct,
/// this is assumed to be the responsibility of the GUI.

#ifdef KOTH
void Position::set(const string& fenStr, bool isChess960, bool isKOTH, Thread* th) {
#else
void Position::set(const string& fenStr, bool isChess960, Thread* th) {
#endif
/*
A FEN string defines a particular position using only the ASCII character set.
Expand Down Expand Up @@ -300,6 +304,9 @@ void Position::set(const string& fenStr, bool isChess960, Thread* th) {
gamePly = std::max(2 * (gamePly - 1), 0) + (sideToMove == BLACK);

chess960 = isChess960;
#ifdef KOTH
koth = isKOTH;
#endif
thisThread = th;
set_state(st);

Expand Down Expand Up @@ -712,6 +719,10 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI

assert(is_ok(m));
assert(&newSt != st);
#ifdef KOTH
assert(!is_koth_win());
assert(!is_koth_loss());
#endif

++nodes;
Key k = st->key;
Expand Down Expand Up @@ -1178,7 +1189,11 @@ void Position::flip() {
std::getline(ss, token); // Half and full moves
f += token;

#ifdef KOTH
set(f, is_chess960(), is_koth(), this_thread());
#else
set(f, is_chess960(), this_thread());
#endif

assert(pos_is_ok());
}
Expand Down
44 changes: 44 additions & 0 deletions src/position.h
Expand Up @@ -76,12 +76,21 @@ class Position {
public:
Position() {}
Position(const Position& pos, Thread* t) { *this = pos; thisThread = t; }
#ifdef KOTH
Position(const std::string& f, Thread* t) { set(f, false, false, t); }
Position(const std::string& f, bool c960, bool isKOTH, Thread* t) { set(f, c960, isKOTH, t); }
#else
Position(const std::string& f, bool c960, Thread* t) { set(f, c960, t); }
#endif
Position& operator=(const Position&);
static void init();

// Text input/output
#ifdef KOTH
void set(const std::string& fenStr, bool isChess960, bool isKOTH, Thread* th);
#else
void set(const std::string& fenStr, bool isChess960, Thread* th);
#endif
const std::string fen() const;
const std::string pretty(Move m = MOVE_NONE) const;

Expand Down Expand Up @@ -159,6 +168,12 @@ class Position {
Phase game_phase() const;
int game_ply() const;
bool is_chess960() const;
#ifdef KOTH
bool is_koth() const;
bool is_koth_win() const;
bool is_koth_loss() const;
int koth_distance(Color c) const;
#endif
Thread* this_thread() const;
uint64_t nodes_searched() const;
void set_nodes_searched(uint64_t n);
Expand Down Expand Up @@ -201,6 +216,9 @@ class Position {
Thread* thisThread;
StateInfo* st;
bool chess960;
#ifdef KOTH
bool koth;
#endif
};

inline uint64_t Position::nodes_searched() const {
Expand Down Expand Up @@ -366,6 +384,32 @@ inline bool Position::pawn_on_7th(Color c) const {
return pieces(c, PAWN) & rank_bb(relative_rank(c, RANK_7));
}

#ifdef KOTH
inline bool Position::is_koth() const {
return koth;
}

// Win if king is in the center (KOTH)
inline bool Position::is_koth_win() const {
return koth_distance(side_to_move()) == 0;
}

// Loss if king is in the center (KOTH)
inline bool Position::is_koth_loss() const {
return koth_distance(~side_to_move()) == 0;
}

inline int Position::koth_distance(Color c) const {
Square ksq = king_square(c);
return std::min(
std::min(square_distance(ksq, SQ_D4),
square_distance(ksq, SQ_E4)),
std::min(square_distance(ksq, SQ_D5),
square_distance(ksq, SQ_E5))
);
}
#endif

inline bool Position::is_chess960() const {
return chess960;
}
Expand Down
6 changes: 6 additions & 0 deletions src/search.cpp
Expand Up @@ -250,6 +250,12 @@ void Search::think() {
RootPos.this_thread()->wait_for(Signals.stop);
}

#ifdef KOTH
// Best move can only be MOVE_NONE when searching on a lost KOTH position
if (RootPos.is_koth() && RootPos.is_koth_loss())
sync_cout << "bestmove " << "(none) ponder (none)" << sync_endl;
else
#endif
// Best move could be MOVE_NONE when searching on a stalemate position
sync_cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], RootPos.is_chess960())
<< " ponder " << move_to_uci(RootMoves[0].pv[1], RootPos.is_chess960())
Expand Down
8 changes: 8 additions & 0 deletions src/uci.cpp
Expand Up @@ -68,7 +68,11 @@ namespace {
else
return;

#ifdef KOTH
pos.set(fen, Options["UCI_Chess960"], Options["UCI_VariantKOTH"], Threads.main());
#else
pos.set(fen, Options["UCI_Chess960"], Threads.main());
#endif
SetupStates = Search::StateStackPtr(new std::stack<StateInfo>());

// Parse move list (if any)
Expand Down Expand Up @@ -145,7 +149,11 @@ namespace {

void UCI::loop(int argc, char* argv[]) {

#ifdef KOTH
Position pos(StartFEN, Threads.main()); // The root position
#else
Position pos(StartFEN, false, Threads.main()); // The root position
#endif
string token, cmd;

for (int i = 1; i < argc; ++i)
Expand Down
3 changes: 3 additions & 0 deletions src/ucioption.cpp
Expand Up @@ -71,6 +71,9 @@ void init(OptionsMap& o) {
o["Minimum Thinking Time"] << Option(20, 0, 5000);
o["Slow Mover"] << Option(80, 10, 1000);
o["UCI_Chess960"] << Option(false);
#ifdef KOTH
o["UCI_VariantKOTH"] << Option(false);
#endif
}


Expand Down

0 comments on commit 59e8c59

Please sign in to comment.