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