00001 //---------------------------------------------------------------------------- 00002 /** @file SgSearchTracer.cpp 00003 See SgSearchTracer.h. */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "SgSearchTracer.h" 00008 00009 #include <algorithm> 00010 #include <iomanip> 00011 #include <limits> 00012 #include <sstream> 00013 #include <math.h> 00014 #include "SgDebug.h" 00015 #include "SgHashTable.h" 00016 #include "SgVector.h" 00017 #include "SgMath.h" 00018 #include "SgNode.h" 00019 #include "SgSearchValue.h" 00020 #include "SgTime.h" 00021 #include "SgWrite.h" 00022 00023 using namespace std; 00024 00025 //---------------------------------------------------------------------------- 00026 00027 SgSearchTracer::SgSearchTracer(SgNode* root) 00028 : m_traceNode(root) 00029 { 00030 } 00031 00032 SgSearchTracer::~SgSearchTracer() 00033 { 00034 } 00035 00036 void SgSearchTracer::AddMoveProp(SgNode* node, SgMove move, 00037 SgBlackWhite player) 00038 { 00039 node->AddMoveProp(move, player); 00040 } 00041 00042 void SgSearchTracer::AddTraceNode(SgMove move, SgBlackWhite player) 00043 { 00044 if (m_traceNode != 0) 00045 { 00046 m_traceNode = m_traceNode->NewRightMostSon(); 00047 AddMoveProp(m_traceNode, move, player); 00048 } 00049 } 00050 00051 void SgSearchTracer::AppendTrace(SgNode* toNode) 00052 { 00053 if (m_traceNode != 0) 00054 { 00055 m_traceNode->Root()->AppendTo(toNode); 00056 m_traceNode = 0; 00057 } 00058 } 00059 00060 void SgSearchTracer::InitTracing(const string& type) 00061 { 00062 SG_ASSERT(! m_traceNode); 00063 m_traceNode = new SgNode(); 00064 m_traceNode->Add(new SgPropText(SG_PROP_COMMENT, type)); 00065 } 00066 00067 void SgSearchTracer::StartOfDepth(int depth) 00068 { 00069 SG_ASSERT(m_traceNode != 0); 00070 if (depth > 0 && m_traceNode->HasFather()) 00071 { 00072 // true for each depth except the very first 00073 // AR: the 0 should really be the depthMin parameter of iterated 00074 // search. this will break if depthMin != 0 and generate strange 00075 // trace trees. 00076 m_traceNode = m_traceNode->Father(); 00077 // go from root of previous level to root 00078 } 00079 m_traceNode = m_traceNode->NewRightMostSon(); 00080 SG_ASSERT(m_traceNode != 0); 00081 m_traceNode->SetIntProp(SG_PROP_MAX_DEPTH, depth); 00082 ostringstream stream; 00083 stream << "Iteration d = " << depth << ' '; 00084 // @todo: trace search.TimeUsed() 00085 m_traceNode->AddComment(stream.str()); 00086 00087 // @todo would be interesting to know time used for each depth, 00088 // create SG_PROP_TIME_USED property at EndOfDepth (doesn't exist yet) 00089 } 00090 00091 void SgSearchTracer::TakeBackTraceNode() 00092 { 00093 if (m_traceNode != 0) 00094 m_traceNode = m_traceNode->Father(); 00095 } 00096 00097 void SgSearchTracer::TraceComment(const char* comment) const 00098 { 00099 if (m_traceNode != 0) 00100 { 00101 m_traceNode->AddComment(comment); 00102 m_traceNode->AddComment("\n"); 00103 } 00104 } 00105 00106 void SgSearchTracer::TraceValue(int value, SgBlackWhite toPlay) const 00107 { 00108 SG_ASSERT(m_traceNode != 0); 00109 // The value needs to be recorded in absolute terms, not relative to 00110 // the current player. 00111 int v = (toPlay == SG_WHITE) ? -value : +value; 00112 m_traceNode->Add(new SgPropValue(SG_PROP_VALUE, v)); 00113 } 00114 00115 void SgSearchTracer::TraceValue(int value, SgBlackWhite toPlay, 00116 const char* comment, bool isExact) const 00117 { 00118 TraceValue(value, toPlay); 00119 if (comment != 0) 00120 TraceComment(comment); 00121 if (isExact) 00122 { 00123 m_traceNode->Add(new SgPropMultiple(SG_PROP_CHECK, 1)); 00124 TraceComment("exact"); 00125 } 00126 } 00127 00128 //---------------------------------------------------------------------------- 00129