dotWriter.cc
Go to the documentation of this file.
00001 /* dotWriter.cc
00002  */
00003 #include "osl/search/analyzer/dotWriter.h"
00004 #include "osl/search/analyzer/recordSet_.h"
00005 #include "osl/search/simpleHashRecord.h"
00006 #include "osl/record/csa.h"
00007 #include <boost/format.hpp>
00008 #include <sstream>
00009 #include <iostream>
00010 #include <cassert>
00011 
00012 #define BOOST_FORMAT_BUG
00013 
00014 osl::search::analyzer::DotWriter::
00015 DotWriter(std::ostream& o)
00016     : written(new RecordSet()), os(o)
00017 {
00018   os << "digraph OSL_DotWriter {\n";
00019 }
00020 
00021 osl::search::analyzer::DotWriter::
00022 ~DotWriter()
00023 {
00024   os << "}\n" << std::flush;
00025 }
00026 
00027 void osl::search::analyzer::DotWriter::
00028 showComment(const char *line) const
00029 {
00030   os << "// " << line << "\n";
00031 }
00032 
00033 void osl::search::analyzer::DotWriter::
00034 showNode(Player turn, const SimpleHashRecord *record,
00035          int limit, NodeType type) const
00036 {
00037   const bool black_turn = turn == BLACK;
00038   if (written->find(record) != written->end())
00039     return;
00040   written->insert(record);
00041   assert(record);
00042   std::stringstream range;
00043   int lower_limit = record->lowerLimit();
00044   int lower_bound = record->lowerBound();
00045   int upper_limit = record->upperLimit();
00046   int upper_bound = record->upperBound();
00047   if (! black_turn)
00048   {
00049     std::swap(lower_limit, upper_limit);
00050     std::swap(lower_bound, upper_bound);
00051   }
00052   int bound = 0;
00053   if (lower_limit >= 0) 
00054   {
00055     ++bound;
00056 #ifndef BOOST_FORMAT_BUG
00057     range << (boost::format("%d(%d)") % lower_bound % lower_limit);
00058 #else
00059     range << lower_bound << "(" << lower_limit << ")";
00060 #endif
00061   }
00062   range << '<'; 
00063   if (upper_limit >= 0) 
00064   {
00065     ++bound;
00066 #ifndef BOOST_FORMAT_BUG
00067     range << (boost::format("%d(%d)") % upper_bound % upper_limit);
00068 #else
00069     range << upper_bound << "(" << upper_limit << ")";
00070 #endif
00071   }
00072   const char *color = 0;
00073   switch (type)
00074   {
00075   case IMPORTANT:
00076     color = "blue";
00077     break;
00078   case ABNORMAL:
00079     color = "magenta";
00080     break;
00081   default:
00082     color = (bound == 2) ? "red" : "black";
00083   }
00084   std::stringstream bestMove;
00085   csaShow(bestMove, record->bestMove().move());
00086 #ifndef BOOST_FORMAT_BUG
00087   os << (boost::format("N%x [label=\"l=%d\\n%s\\n%s\",color=%s,shape=box]\n")
00088          % record % limit % range.str() % bestMove.str()
00089          % color);
00090 #else
00091   os << "N" << record << " [label=\"l=" << limit << "\\n" << range.str() 
00092      << "\\n" << bestMove.str()
00093      << "\",color=" << color << ",shape=box]\n";
00094 #endif
00095 }
00096 
00097 // TODO: 選手権後に showNode と共通部分をまとめる
00098 void osl::search::analyzer::DotWriter::
00099 showNodeQuiescence(Player turn, const SimpleHashRecord *record,
00100                    int limit, NodeType type) const
00101 {
00102   bool black_turn = (turn == BLACK);
00103   if (written->find(record) != written->end())
00104     return;
00105   written->insert(record);
00106   assert(record);
00107   const QuiescenceRecord *qrecord = &record->qrecord;
00108   std::stringstream range;
00109   int lower_limit = qrecord->lowerDepth();
00110   int lower_bound = qrecord->lowerBound();
00111   int upper_limit = qrecord->upperDepth();
00112   int upper_bound = qrecord->upperBound();
00113   if (! black_turn)
00114   {
00115     std::swap(lower_limit, upper_limit);
00116     std::swap(lower_bound, upper_bound);
00117   }
00118   int bound = 0;
00119   if (lower_limit >= 0) 
00120   {
00121     ++bound;
00122 #ifndef BOOST_FORMAT_BUG
00123     range << (boost::format("%d(%d)") % lower_bound % lower_limit);
00124 #else
00125     range << lower_bound << "(" << lower_limit << ")";
00126 #endif
00127   }
00128   range << '<'; 
00129   if (upper_limit >= 0) 
00130   {
00131     ++bound;
00132 #ifndef BOOST_FORMAT_BUG
00133     range << (boost::format("%d(%d)") % upper_bound % upper_limit);
00134 #else
00135     range << upper_bound << "(" << upper_limit << ")";
00136 #endif
00137   }
00138   const char *color = 0;
00139   switch (type)
00140   {
00141   case IMPORTANT:
00142     color = "blue";
00143     break;
00144   case ABNORMAL:
00145     color = "magenta";
00146     break;
00147   default:
00148     color = (bound == 2) ? "burlywood" : "cyan";
00149   }
00150 #ifndef BOOST_FORMAT_BUG
00151   os << (boost::format("N%x [label=\"l=%d\\n%s\",color=%s,shape=box]\n")
00152          % record % limit % range.str() 
00153          % color);
00154 #else
00155   os << "N" << record << " [label=\"l=" << limit << "\\n" << range.str() 
00156      << "\",color=" << color << ",shape=box]\n";
00157 #endif
00158 }
00159 
00160 void osl::search::analyzer::DotWriter::
00161 showArc(const SimpleHashRecord *from, const SimpleHashRecord *to,
00162         const MoveLogProb& move, bool important) const
00163 {
00164   if ((written->find(from) != written->end())
00165       && (written->find(to) != written->end()))
00166     return;
00167   assert(from);
00168   assert(to);
00169   std::stringstream move_string;
00170   csaShow(move_string, move.move());
00171   const char *color = 0;
00172   if (important)
00173     color = "blue";
00174   else
00175     color = (move.logProb() <= 100) ? "red" : "black";
00176 #ifndef BOOST_FORMAT_BUG
00177   os << (boost::format("N%x -> N%x [label=\"%s (%d)\", color=%s, style=bold]\n")
00178          % from % to % move_string.str() % move.logProb() % color);
00179 #else
00180   os << "N" << from <<  " -> N" << to << " [label=\"" << move_string.str()
00181      << " (" << move.logProb() << ")\", color=" << color
00182      << ", style=bold]\n";
00183 #endif
00184 }
00185 
00186 /* ------------------------------------------------------------------------- */
00187 // ;;; Local Variables:
00188 // ;;; mode:c++
00189 // ;;; c-basic-offset:2
00190 // ;;; coding:utf-8
00191 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines