00001 //---------------------------------------------------------------------------- 00002 /** @file GoAutoBook.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "GoAutoBook.h" 00007 00008 //---------------------------------------------------------------------------- 00009 00010 GoAutoBookState::GoAutoBookState(const GoBoard& brd) 00011 : m_synchronizer(brd) 00012 { 00013 m_synchronizer.SetSubscriber(m_brd[0]); 00014 } 00015 00016 GoAutoBookState::~GoAutoBookState() 00017 { 00018 } 00019 00020 SgHashCode GoAutoBookState::GetHashCode() const 00021 { 00022 return m_hash; 00023 } 00024 00025 void GoAutoBookState::Synchronize() 00026 { 00027 m_synchronizer.UpdateSubscriber(); 00028 int size = m_brd[0].Size(); 00029 int numMoves = m_brd[0].MoveNumber(); 00030 for (int rot = 1; rot < 8; ++rot) 00031 { 00032 m_brd[rot].Init(size, size); 00033 for (int i = 0; i < numMoves; ++i) 00034 { 00035 SgMove move = m_brd[0].Move(i).Point(); 00036 m_brd[rot].Play(SgPointUtil::Rotate(rot, move, size)); 00037 } 00038 } 00039 ComputeHashCode(); 00040 } 00041 00042 void GoAutoBookState::Play(SgMove move) 00043 { 00044 m_hash = m_brd[0].GetHashCodeInclToPlay(); 00045 for (int rot = 0; rot < 8; ++rot) 00046 m_brd[rot].Play(SgPointUtil::Rotate(rot, move, m_brd[0].Size())); 00047 ComputeHashCode(); 00048 } 00049 00050 void GoAutoBookState::Undo() 00051 { 00052 for (int rot = 0; rot < 8; ++rot) 00053 m_brd[rot].Undo(); 00054 ComputeHashCode(); 00055 } 00056 00057 void GoAutoBookState::ComputeHashCode() 00058 { 00059 m_hash = m_brd[0].GetHashCodeInclToPlay(); 00060 for (int rot = 1; rot < 8; ++rot) 00061 { 00062 SgHashCode curHash = m_brd[rot].GetHashCodeInclToPlay(); 00063 if (curHash < m_hash) 00064 m_hash = curHash; 00065 } 00066 } 00067 00068 //---------------------------------------------------------------------------- 00069 00070 GoAutoBook::GoAutoBook(const std::string& filename) throw() 00071 : m_filename(filename) 00072 { 00073 std::ifstream is(filename.c_str()); 00074 if (!is) 00075 { 00076 std::ofstream of(filename.c_str()); 00077 if (!of) 00078 throw SgException("Invalid file name!"); 00079 of.close(); 00080 } 00081 else 00082 { 00083 while (is) 00084 { 00085 std::string line; 00086 std::getline(is, line); 00087 if (line.size() < 19) 00088 continue; 00089 std::string str; 00090 std::istringstream iss(line); 00091 iss >> str; 00092 SgHashCode hash; 00093 hash.FromString(str); 00094 SgBookNode node(line.substr(19)); 00095 m_data[hash] = node; 00096 } 00097 SgDebug() << "GoAutoBook: Parsed " << m_data.size() << " lines.\n"; 00098 } 00099 } 00100 00101 GoAutoBook::~GoAutoBook() 00102 { 00103 } 00104 00105 bool GoAutoBook::Get(const GoAutoBookState& state, SgBookNode& node) const 00106 { 00107 Map::const_iterator it = m_data.find(state.GetHashCode()); 00108 if (it != m_data.end()) 00109 { 00110 node = it->second; 00111 return true; 00112 } 00113 return false; 00114 } 00115 00116 void GoAutoBook::Put(const GoAutoBookState& state, const SgBookNode& node) 00117 { 00118 m_data[state.GetHashCode()] = node; 00119 } 00120 00121 void GoAutoBook::Flush() 00122 { 00123 Save(m_filename); 00124 } 00125 00126 void GoAutoBook::Save(const std::string& filename) const 00127 { 00128 std::ofstream out(filename.c_str()); 00129 for (Map::const_iterator it = m_data.begin(); it != m_data.end(); ++it) 00130 { 00131 out << it->first.ToString() << '\t' 00132 << it->second.ToString() << '\n'; 00133 } 00134 out.close(); 00135 } 00136 00137 SgMove GoAutoBook::FindBestChild(GoAutoBookState& state) const 00138 { 00139 std::size_t bestCount = 0; 00140 SgMove bestMove = SG_NULLMOVE; 00141 SgBookNode node; 00142 if (!Get(state, node)) 00143 return SG_NULLMOVE; 00144 if (node.IsLeaf()) 00145 return SG_NULLMOVE; 00146 for (GoBoard::Iterator it(state.Board()); it; ++it) 00147 { 00148 if (state.Board().IsLegal(*it)) 00149 { 00150 state.Play(*it); 00151 if (Get(state, node) && !node.IsLeaf() && !node.IsTerminal()) 00152 { 00153 if (node.m_count > bestCount) 00154 { 00155 bestCount = node.m_count; 00156 bestMove = *it; 00157 } 00158 } 00159 state.Undo(); 00160 } 00161 } 00162 return bestMove; 00163 } 00164 00165 SgMove GoAutoBook::LookupMove(const GoBoard& brd) const 00166 { 00167 GoAutoBookState state(brd); 00168 state.Synchronize(); 00169 return FindBestChild(state); 00170 } 00171 00172 //----------------------------------------------------------------------------