usiReporter.cc
Go to the documentation of this file.
00001 /* usiReporter.cc
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 // ;;; Local Variables:
00248 // ;;; mode:c++
00249 // ;;; c-basic-offset:2
00250 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines