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 client_id("")
00115 {
00116 }
00117
00118 osl::search::
00119 UsiMonitor::~UsiMonitor()
00120 {
00121 }
00122
00123 void osl::search::
00124 UsiMonitor::showDeferred(bool forced)
00125 {
00126 if ((!forced && depth0.elapsedSeconds() < silent_period)
00127 || deferred.empty())
00128 return;
00129 os << deferred << std::flush;
00130 if (udp_socket) {
00131 if (client_id != "")
00132 deferred = client_id + " " + deferred;
00133 boost::system::error_code ignored_error;
00134 udp_socket->send_to(boost::asio::buffer(deferred.c_str(), deferred.length()),
00135 *udp_endpoint,
00136 0, ignored_error);
00137 }
00138 deferred.clear();
00139 }
00140
00141 void osl::search::
00142 UsiMonitor::newDepth(int depth)
00143 {
00144 last_root_move = Move();
00145 if (depth == 0) {
00146 depth0 = MilliSeconds::now();
00147 return;
00148 }
00149 if (depth0.elapsedSeconds() >= silent_period) {
00150 showDeferred();
00151 UsiReporter::newDepth(os, depth);
00152 }
00153 }
00154
00155 void osl::search::
00156 UsiMonitor::showPV(int depth, size_t node_count, double elapsed, int value, Move cur, const Move *first, const Move *last,
00157 const bool *threatmate_first, const bool *threatmate_last)
00158 {
00159 const bool defer = depth0.elapsedSeconds() < silent_period;
00160 std::ostringstream ss;
00161 if (extended)
00162 UsiReporter::showPVExtended(ss, depth, node_count, elapsed, value, cur, first, last,
00163 threatmate_first, threatmate_last);
00164 else
00165 UsiReporter::showPV(ss, depth, node_count, elapsed, value, cur, first, last);
00166 if (defer)
00167 deferred = ss.str();
00168 else {
00169 std::string msg = ss.str();
00170 os << msg << std::flush;
00171 if (udp_socket) {
00172 if (client_id != "")
00173 msg = client_id + " " + msg;
00174 boost::system::error_code ignored_error;
00175 udp_socket->send_to(boost::asio::buffer(msg.c_str(), msg.length()),
00176 *udp_endpoint, 0,
00177 ignored_error);
00178 }
00179 deferred.clear();
00180 }
00181 }
00182
00183 void osl::search::UsiMonitor::
00184 showFailLow(int depth, size_t node_count, double elapsed, int value, Move cur)
00185 {
00186 showPV(depth, node_count, elapsed, value, cur, 0, 0, 0, 0);
00187 }
00188
00189 void osl::search::
00190 UsiMonitor::rootMove(Move cur)
00191 {
00192 showDeferred();
00193 last_root_move = cur;
00194 }
00195
00196 void osl::search::
00197 UsiMonitor::rootFirstMove(Move cur)
00198 {
00199 showDeferred();
00200 last_root_move = cur;
00201 UsiReporter::rootMove(os, cur, true);
00202 }
00203
00204 void osl::search::
00205 UsiMonitor::timeInfo(size_t node_count, double elapsed)
00206 {
00207 showDeferred();
00208 {
00209 std::ostringstream ss;
00210 UsiReporter::timeInfo(ss, node_count, elapsed);
00211 std::string msg = ss.str();
00212 os << msg << std::flush;
00213 if (udp_socket) {
00214 if (client_id != "")
00215 msg = client_id + " " + msg;
00216 boost::system::error_code ignored_error;
00217 udp_socket->send_to(boost::asio::buffer(msg.c_str(), msg.length()),
00218 *udp_endpoint, 0,
00219 ignored_error);
00220 }
00221 }
00222 UsiReporter::rootMove(os, last_root_move);
00223 }
00224
00225 void osl::search::
00226 UsiMonitor::hashInfo(double ratio)
00227 {
00228 showDeferred();
00229 UsiReporter::hashInfo(os, ratio);
00230 }
00231
00232 void osl::search::
00233 UsiMonitor::rootForcedMove(Move the_move)
00234 {
00235 if (OslConfig::usiModeInSilent())
00236 return;
00237 showDeferred();
00238 os << "info string forced move at the root: "
00239 << record::usi::show(the_move) << "\n";
00240 os << std::flush;
00241 }
00242
00243 void osl::search::
00244 UsiMonitor::rootLossByCheckmate()
00245 {
00246 if (OslConfig::usiModeInSilent())
00247 return;
00248 deferred.clear();
00249 os << "info string loss by checkmate\n";
00250 os << std::flush;
00251 }
00252
00253 void osl::search::
00254 UsiMonitor::setUdpLogging(std::string& udp_client_id,
00255 boost::asio::ip::udp::socket *s,
00256 boost::asio::ip::udp::endpoint *e)
00257 {
00258 client_id = udp_client_id;
00259 udp_socket = s;
00260 udp_endpoint = e;
00261 }
00262
00263 void osl::search::
00264 UsiMonitor::searchFinished()
00265 {
00266 showDeferred(true);
00267 }
00268
00269
00270
00271
00272