00001
00002
00003 #include "osl/search/usiReporter.h"
00004 #include "osl/record/usi.h"
00005 #include "osl/misc/lightMutex.h"
00006 #include "osl/misc/milliSeconds.h"
00007 #include "osl/oslConfig.h"
00008 #include <iostream>
00009
00010 void osl::search::
00011 UsiReporter::newDepth(std::ostream& os, int depth)
00012 {
00013 if (OslConfig::usiModeInSilent())
00014 return;
00015 os << "info depth " << depth << "\n";
00016 }
00017 void osl::search::
00018 UsiReporter::showPV(std::ostream& os, int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last, bool ignore_silent)
00019 {
00020 if (OslConfig::usiModeInSilent() && ! ignore_silent)
00021 return;
00022 int seldepth = last-first;
00023 if (last - first && *first != cur)
00024 ++seldepth;
00025 if (ignore_silent)
00026 std::cerr << "info depth " << depth << " seldepth " << seldepth
00027 << " time " << static_cast<int>(elapsed*1000) << " score cp " << value
00028 << " nodes " << node_count
00029 << " nps " << static_cast<int>(node_count/elapsed)
00030 << " pv " << record::usi::show(cur) << "\n";
00031 os << "info depth " << depth << " seldepth " << seldepth
00032 << " time " << static_cast<int>(elapsed*1000) << " score cp " << value
00033 << " nodes " << node_count << " nps " << static_cast<int>(node_count/elapsed);
00034 os << " pv " << record::usi::show(cur);
00035 if (first != last) {
00036 if (cur == *first)
00037 ++first;
00038 while (first != last) {
00039 os << ' ' << record::usi::show(*first++);
00040 }
00041 }
00042 os << "\n";
00043 }
00044
00045 void osl::search::
00046 UsiReporter::showPVExtended(std::ostream& os, int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last, const bool *tfirst, const bool *tlast)
00047 {
00048 if (OslConfig::usiModeInSilent())
00049 return;
00050 int seldepth = last-first;
00051 assert(seldepth == tlast-tfirst);
00052 if (last - first && *first != cur)
00053 ++seldepth;
00054 os << "info depth " << depth << " seldepth " << seldepth
00055 << " time " << static_cast<int>(elapsed*1000) << " score cp " << value
00056 << " nodes " << node_count << " nps " << static_cast<int>(node_count/elapsed);
00057 os << " pv " << record::usi::show(cur);
00058 if (first != last) {
00059 if (cur == *first)
00060 ++first, ++tfirst;
00061 while (first != last) {
00062 os << ' ' << record::usi::show(*first++);
00063 if (tfirst != tlast && *tfirst++)
00064 os << "(^)";
00065 }
00066 }
00067 os << "\n";
00068 }
00069
00070 static osl::misc::LightMutex usi_root_move_mutex;
00071 void osl::search::
00072 UsiReporter::rootMove(std::ostream& os, Move cur, bool allow_frequent_display)
00073 {
00074 if (OslConfig::usiModeInSilent())
00075 return;
00076 static MilliSeconds prev;
00077 if (! allow_frequent_display)
00078 {
00079 MilliSeconds now = MilliSeconds::now();
00080 {
00081 SCOPED_LOCK(lk, usi_root_move_mutex);
00082 if ((now - prev).toSeconds() < 0.5)
00083 return;
00084 prev = now;
00085 }
00086 }
00087 os << "info currmove " << record::usi::show(cur) << "\n";
00088 }
00089
00090 void osl::search::
00091 UsiReporter::timeInfo(std::ostream& os, size_t node_count, double elapsed)
00092 {
00093 if (OslConfig::usiModeInSilent())
00094 return;
00095 os << "info time " << static_cast<int>(elapsed*1000)
00096 << " nodes " << node_count << " nps " << static_cast<int>(node_count/elapsed) << "\n";
00097 os << std::flush;
00098 }
00099
00100 void osl::search::
00101 UsiReporter::hashInfo(std::ostream& os, double ratio)
00102 {
00103 if (OslConfig::usiModeInSilent())
00104 return;
00105 os << "info hashfull " << static_cast<int>(ratio*1000) << "\n";
00106 os << std::flush;
00107 }
00108
00109
00110
00111 osl::search::
00112 UsiMonitor::UsiMonitor(bool ex, std::ostream& o, double s)
00113 : silent_period(s), extended(ex), os(o), udp_socket(0), udp_endpoint(0)
00114 {
00115 }
00116
00117 osl::search::
00118 UsiMonitor::~UsiMonitor()
00119 {
00120 }
00121
00122 void osl::search::
00123 UsiMonitor::showDeferred()
00124 {
00125 if (depth0.elapsedSeconds() < silent_period || deferred.empty())
00126 return;
00127 os << deferred << std::flush;
00128 if (udp_socket) {
00129 boost::system::error_code ignored_error;
00130 udp_socket->send_to(boost::asio::buffer(deferred.c_str(), deferred.length()),
00131 *udp_endpoint,
00132 0, ignored_error);
00133 }
00134 deferred.clear();
00135 }
00136
00137 void osl::search::
00138 UsiMonitor::newDepth(int depth)
00139 {
00140 last_root_move = Move();
00141 if (depth == 0) {
00142 depth0 = MilliSeconds::now();
00143 return;
00144 }
00145 if (depth0.elapsedSeconds() >= silent_period) {
00146 showDeferred();
00147 UsiReporter::newDepth(os, depth);
00148 }
00149 }
00150
00151 void osl::search::
00152 UsiMonitor::showPV(int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last,
00153 const bool *threatmate_first, const bool *threatmate_last)
00154 {
00155 const bool defer = depth0.elapsedSeconds() < silent_period;
00156 std::ostringstream ss;
00157 if (extended)
00158 UsiReporter::showPVExtended(ss, depth, node_count, elapsed, value, cur, first, last,
00159 threatmate_first, threatmate_last);
00160 else
00161 UsiReporter::showPV(ss, depth, node_count, elapsed, value, cur, first, last);
00162 if (defer)
00163 deferred = ss.str();
00164 else {
00165 std::string msg = ss.str();
00166 os << msg << std::flush;
00167 if (udp_socket) {
00168 boost::system::error_code ignored_error;
00169 udp_socket->send_to(boost::asio::buffer(msg.c_str(), msg.length()),
00170 *udp_endpoint, 0,
00171 ignored_error);
00172 }
00173 deferred.clear();
00174 }
00175 }
00176
00177 void osl::search::
00178 UsiMonitor::rootMove(Move cur)
00179 {
00180 showDeferred();
00181 last_root_move = cur;
00182 }
00183
00184 void osl::search::
00185 UsiMonitor::rootFirstMove(Move cur)
00186 {
00187 showDeferred();
00188 last_root_move = cur;
00189 UsiReporter::rootMove(os, cur, true);
00190 }
00191
00192 void osl::search::
00193 UsiMonitor::timeInfo(size_t node_count, double elapsed)
00194 {
00195 showDeferred();
00196 {
00197 std::ostringstream ss;
00198 UsiReporter::timeInfo(ss, node_count, elapsed);
00199 std::string msg = ss.str();
00200 os << msg << std::flush;
00201 if (udp_socket) {
00202 boost::system::error_code ignored_error;
00203 udp_socket->send_to(boost::asio::buffer(msg.c_str(), msg.length()),
00204 *udp_endpoint, 0,
00205 ignored_error);
00206 }
00207 }
00208 UsiReporter::rootMove(os, last_root_move);
00209 }
00210
00211 void osl::search::
00212 UsiMonitor::hashInfo(double ratio)
00213 {
00214 showDeferred();
00215 UsiReporter::hashInfo(os, ratio);
00216 }
00217
00218 void osl::search::
00219 UsiMonitor::rootForcedMove(Move the_move)
00220 {
00221 if (OslConfig::usiModeInSilent())
00222 return;
00223 showDeferred();
00224 os << "info string forced move at the root: "
00225 << record::usi::show(the_move) << "\n";
00226 os << std::flush;
00227 }
00228
00229 void osl::search::
00230 UsiMonitor::rootLossByCheckmate()
00231 {
00232 if (OslConfig::usiModeInSilent())
00233 return;
00234 deferred.clear();
00235 os << "info string loss by checkmate\n";
00236 os << std::flush;
00237 }
00238
00239 void osl::search::
00240 UsiMonitor::setUdpLogging(boost::asio::ip::udp::socket *s,
00241 boost::asio::ip::udp::endpoint *e)
00242 {
00243 udp_socket = s;
00244 udp_endpoint = e;
00245 }
00246
00247
00248
00249
00250