Introduce notation.h
authorMarco Costalba <mcostalba@gmail.com>
Sun, 15 Jul 2012 07:14:25 +0000 (08:14 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 15 Jul 2012 07:29:07 +0000 (08:29 +0100)
And group there all the formatting functions but
uci_pv() that requires access to search.cpp variables.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/misc.h
src/notation.cpp
src/notation.h [new file with mode: 0644]
src/position.cpp
src/search.cpp
src/uci.cpp

index 0cd5a7067cdf883d59a7ca321fcb96c1a9e4379a..57e86553ffa0b1686ab7c06d8e36a6ba8d75da60 100644 (file)
@@ -37,11 +37,6 @@ extern void dbg_hit_on_c(bool c, bool b);
 extern void dbg_mean_of(int v);
 extern void dbg_print();
 
-class Position;
-extern Move move_from_uci(const Position& pos, std::string& str);
-extern const std::string move_to_uci(Move m, bool chess960);
-extern const std::string move_to_san(Position& pos, Move m);
-
 
 struct Log : public std::ofstream {
   Log(const std::string& f = "log.txt") : std::ofstream(f.c_str(), std::ios::out | std::ios::app) {}
index 89b00c553da4b58a100b75274b99369da1834821..eb3c46a0244904e63588ef821b1e5714ffd5d468 100644 (file)
 */
 
 #include <cassert>
+#include <iomanip>
+#include <sstream>
 #include <string>
 
 #include "movegen.h"
+#include "notation.h"
 #include "position.h"
 
-using std::string;
+using namespace std;
 
 static const char* PieceToChar = " PNBRQK pnbrqk";
 
+
+/// score_to_uci() converts a value to a string suitable for use with the UCI
+/// protocol specifications:
+///
+/// cp <x>     The score from the engine's point of view in centipawns.
+/// mate <y>   Mate in y moves, not plies. If the engine is getting mated
+///            use negative values for y.
+
+string score_to_uci(Value v, Value alpha, Value beta) {
+
+  stringstream s;
+
+  if (abs(v) < VALUE_MATE_IN_MAX_PLY)
+      s << "cp " << v * 100 / int(PawnValueMidgame);
+  else
+      s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2;
+
+  s << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
+
+  return s.str();
+}
+
+
 /// move_to_uci() converts a move to a string in coordinate notation
 /// (g1f3, a7a8q, etc.). The only special case is castling moves, where we print
 /// in the e1g1 notation in normal chess mode, and in e1h1 notation in chess960
@@ -153,3 +179,92 @@ const string move_to_san(Position& pos, Move m) {
 
   return san;
 }
+
+
+/// pretty_pv() formats human-readable search information, typically to be
+/// appended to the search log file. It uses the two helpers below to pretty
+/// format time and score respectively.
+
+static string time_to_string(int millisecs) {
+
+  const int MSecMinute = 1000 * 60;
+  const int MSecHour   = 1000 * 60 * 60;
+
+  int hours = millisecs / MSecHour;
+  int minutes =  (millisecs % MSecHour) / MSecMinute;
+  int seconds = ((millisecs % MSecHour) % MSecMinute) / 1000;
+
+  stringstream s;
+
+  if (hours)
+      s << hours << ':';
+
+  s << setfill('0') << setw(2) << minutes << ':' << setw(2) << seconds;
+
+  return s.str();
+}
+
+static string score_to_string(Value v) {
+
+  stringstream s;
+
+  if (v >= VALUE_MATE_IN_MAX_PLY)
+      s << "#" << (VALUE_MATE - v + 1) / 2;
+
+  else if (v <= VALUE_MATED_IN_MAX_PLY)
+      s << "-#" << (VALUE_MATE + v) / 2;
+
+  else
+      s << setprecision(2) << fixed << showpos << float(v) / PawnValueMidgame;
+
+  return s.str();
+}
+
+string pretty_pv(Position& pos, int depth, Value value, int time, Move pv[]) {
+
+  const int64_t K = 1000;
+  const int64_t M = 1000000;
+
+  StateInfo state[MAX_PLY_PLUS_2], *st = state;
+  Move* m = pv;
+  string san, padding;
+  size_t length;
+  stringstream s;
+
+  s << setw(2) << depth
+    << setw(8) << score_to_string(value)
+    << setw(8) << time_to_string(time);
+
+  if (pos.nodes_searched() < M)
+      s << setw(8) << pos.nodes_searched() / 1 << "  ";
+
+  else if (pos.nodes_searched() < K * M)
+      s << setw(7) << pos.nodes_searched() / K << "K  ";
+
+  else
+      s << setw(7) << pos.nodes_searched() / M << "M  ";
+
+  padding = string(s.str().length(), ' ');
+  length = padding.length();
+
+  while (*m != MOVE_NONE)
+  {
+      san = move_to_san(pos, *m);
+
+      if (length + san.length() > 80)
+      {
+          s << "\n" + padding;
+          length = padding.length();
+      }
+
+      s << san << ' ';
+      length += san.length() + 1;
+
+      pos.do_move(*m++, *st++);
+  }
+
+  while (m != pv)
+      pos.undo_move(*--m);
+
+  return s.str();
+}
diff --git a/src/notation.h b/src/notation.h
new file mode 100644 (file)
index 0000000..5c23a2c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+  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
+
+  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.
+
+  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.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#if !defined(NOTATION_H_INCLUDED)
+#define NOTATION_H_INCLUDED
+
+#include <string>
+
+#include "types.h"
+
+class Position;
+
+std::string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE);
+Move move_from_uci(const Position& pos, std::string& str);
+const std::string move_to_uci(Move m, bool chess960);
+const std::string move_to_san(Position& pos, Move m);
+std::string pretty_pv(Position& pos, int depth, Value score, int time, Move pv[]);
+
+#endif // !defined(NOTATION_H_INCLUDED)
index 244a258071d195fd359776b3650af1ea38a34f81..4d3f32a4d984d3b8edc5c92a3aff05d808098078 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "bitcount.h"
 #include "movegen.h"
+#include "notation.h"
 #include "position.h"
 #include "psqtab.h"
 #include "rkiss.h"
index df09007f1538f8f15134e6df34edbc8dafacb93e..472d53725f1414c89d73161844432308b5a0b94b 100644 (file)
@@ -21,7 +21,6 @@
 #include <cassert>
 #include <cmath>
 #include <cstring>
-#include <iomanip>
 #include <iostream>
 #include <sstream>
 
@@ -30,6 +29,7 @@
 #include "history.h"
 #include "movegen.h"
 #include "movepick.h"
+#include "notation.h"
 #include "search.h"
 #include "timeman.h"
 #include "thread.h"
@@ -144,8 +144,6 @@ namespace {
   bool connected_threat(const Position& pos, Move m, Move threat);
   Value refine_eval(const TTEntry* tte, Value ttValue, Value defaultEval);
   Move do_skill_level();
-  string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE);
-  string pretty_pv(Position& pos, int depth, Value score, int time, Move pv[]);
   string uci_pv(const Position& pos, int depth, Value alpha, Value beta);
 
   // MovePickerExt class template extends MovePicker and allows to choose at
@@ -1512,25 +1510,48 @@ split_point_start: // At split points actual search starts from here
   }
 
 
-  // score_to_uci() converts a value to a string suitable for use with the UCI
-  // protocol specifications:
-  //
-  // cp <x>     The score from the engine's point of view in centipawns.
-  // mate <y>   Mate in y moves, not plies. If the engine is getting mated
-  //            use negative values for y.
+  // When playing with strength handicap choose best move among the MultiPV set
+  // using a statistical rule dependent on SkillLevel. Idea by Heinz van Saanen.
 
-  string score_to_uci(Value v, Value alpha, Value beta) {
+  Move do_skill_level() {
 
-    std::stringstream s;
+    assert(MultiPV > 1);
 
-    if (abs(v) < VALUE_MATE_IN_MAX_PLY)
-        s << "cp " << v * 100 / int(PawnValueMidgame);
-    else
-        s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2;
+    static RKISS rk;
 
-    s << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
+    // PRNG sequence should be not deterministic
+    for (int i = Time::current_time().msec() % 50; i > 0; i--)
+        rk.rand<unsigned>();
 
-    return s.str();
+    // RootMoves are already sorted by score in descending order
+    size_t size = std::min(MultiPV, RootMoves.size());
+    int variance = std::min(RootMoves[0].score - RootMoves[size - 1].score, PawnValueMidgame);
+    int weakness = 120 - 2 * SkillLevel;
+    int max_s = -VALUE_INFINITE;
+    Move best = MOVE_NONE;
+
+    // Choose best move. For each move score we add two terms both dependent on
+    // weakness, one deterministic and bigger for weaker moves, and one random,
+    // then we choose the move with the resulting highest score.
+    for (size_t i = 0; i < size; i++)
+    {
+        int s = RootMoves[i].score;
+
+        // Don't allow crazy blunders even at very low skills
+        if (i > 0 && RootMoves[i-1].score > s + EasyMoveMargin)
+            break;
+
+        // This is our magic formula
+        s += (  weakness * int(RootMoves[0].score - s)
+              + variance * (rk.rand<unsigned>() % weakness)) / 128;
+
+        if (s > max_s)
+        {
+            max_s = s;
+            best = RootMoves[i].pv[0];
+        }
+    }
+    return best;
   }
 
 
@@ -1577,141 +1598,6 @@ split_point_start: // At split points actual search starts from here
     return s.str();
   }
 
-
-  // pretty_pv() formats human-readable search information, typically to be
-  // appended to the search log file. It uses the two helpers below to pretty
-  // format time and score respectively.
-
-  string time_to_string(int millisecs) {
-
-    const int MSecMinute = 1000 * 60;
-    const int MSecHour   = 1000 * 60 * 60;
-
-    int hours = millisecs / MSecHour;
-    int minutes =  (millisecs % MSecHour) / MSecMinute;
-    int seconds = ((millisecs % MSecHour) % MSecMinute) / 1000;
-
-    std::stringstream s;
-
-    if (hours)
-        s << hours << ':';
-
-    s << std::setfill('0') << std::setw(2) << minutes << ':'
-                           << std::setw(2) << seconds;
-    return s.str();
-  }
-
-  string score_to_string(Value v) {
-
-    std::stringstream s;
-
-    if (v >= VALUE_MATE_IN_MAX_PLY)
-        s << "#" << (VALUE_MATE - v + 1) / 2;
-
-    else if (v <= VALUE_MATED_IN_MAX_PLY)
-        s << "-#" << (VALUE_MATE + v) / 2;
-
-    else
-        s << std::setprecision(2) << std::fixed << std::showpos
-          << float(v) / PawnValueMidgame;
-
-    return s.str();
-  }
-
-  string pretty_pv(Position& pos, int depth, Value value, int time, Move pv[]) {
-
-    const int64_t K = 1000;
-    const int64_t M = 1000000;
-
-    StateInfo state[MAX_PLY_PLUS_2], *st = state;
-    Move* m = pv;
-    string san, padding;
-    size_t length;
-    std::stringstream s;
-
-    s << std::setw(2) << depth
-      << std::setw(8) << score_to_string(value)
-      << std::setw(8) << time_to_string(time);
-
-    if (pos.nodes_searched() < M)
-        s << std::setw(8) << pos.nodes_searched() / 1 << "  ";
-
-    else if (pos.nodes_searched() < K * M)
-        s << std::setw(7) << pos.nodes_searched() / K << "K  ";
-
-    else
-        s << std::setw(7) << pos.nodes_searched() / M << "M  ";
-
-    padding = string(s.str().length(), ' ');
-    length = padding.length();
-
-    while (*m != MOVE_NONE)
-    {
-        san = move_to_san(pos, *m);
-
-        if (length + san.length() > 80)
-        {
-            s << "\n" + padding;
-            length = padding.length();
-        }
-
-        s << san << ' ';
-        length += san.length() + 1;
-
-        pos.do_move(*m++, *st++);
-    }
-
-    while (m != pv)
-        pos.undo_move(*--m);
-
-    return s.str();
-  }
-
-
-  // When playing with strength handicap choose best move among the MultiPV set
-  // using a statistical rule dependent on SkillLevel. Idea by Heinz van Saanen.
-
-  Move do_skill_level() {
-
-    assert(MultiPV > 1);
-
-    static RKISS rk;
-
-    // PRNG sequence should be not deterministic
-    for (int i = Time::current_time().msec() % 50; i > 0; i--)
-        rk.rand<unsigned>();
-
-    // RootMoves are already sorted by score in descending order
-    size_t size = std::min(MultiPV, RootMoves.size());
-    int variance = std::min(RootMoves[0].score - RootMoves[size - 1].score, PawnValueMidgame);
-    int weakness = 120 - 2 * SkillLevel;
-    int max_s = -VALUE_INFINITE;
-    Move best = MOVE_NONE;
-
-    // Choose best move. For each move score we add two terms both dependent on
-    // weakness, one deterministic and bigger for weaker moves, and one random,
-    // then we choose the move with the resulting highest score.
-    for (size_t i = 0; i < size; i++)
-    {
-        int s = RootMoves[i].score;
-
-        // Don't allow crazy blunders even at very low skills
-        if (i > 0 && RootMoves[i-1].score > s + EasyMoveMargin)
-            break;
-
-        // This is our magic formula
-        s += (  weakness * int(RootMoves[0].score - s)
-              + variance * (rk.rand<unsigned>() % weakness)) / 128;
-
-        if (s > max_s)
-        {
-            max_s = s;
-            best = RootMoves[i].pv[0];
-        }
-    }
-    return best;
-  }
-
 } // namespace
 
 
index 7b7b116ee233999760f381c6e960b57a284739eb..9eab330c07f611de57d20d5e14ddba2edc0a0c2b 100644 (file)
@@ -22,6 +22,7 @@
 #include <string>
 
 #include "evaluate.h"
+#include "notation.h"
 #include "position.h"
 #include "search.h"
 #include "thread.h"