00001 //---------------------------------------------------------------------------- 00002 /** @file GoBook.h 00003 Opening book. 00004 */ 00005 //---------------------------------------------------------------------------- 00006 00007 #ifndef GO_BOOK_H 00008 #define GO_BOOK_H 00009 00010 #include <iosfwd> 00011 #include <map> 00012 #include <string> 00013 #include <vector> 00014 #include "GtpEngine.h" 00015 #include "SgHash.h" 00016 #include "SgPoint.h" 00017 00018 class GoBoard; 00019 00020 //---------------------------------------------------------------------------- 00021 00022 /** Opening book. 00023 The file format contains a single line per entry, containing a board size, 00024 a sequence that leads to the position and, seperated with a pipe symbol, 00025 a list of moves to play in this position. Example: 00026 @verbatim 00027 19 | Q3 Q4 00028 19 P3 D16 | Q16 00029 19 Q3 | C3 C17 D3 D4 D16 Q16 R16 R17 00030 9 E5 D3 G4 | E7 00031 @endverbatim 00032 Equivalent positions are derived automatically by rotating and/or 00033 mirroring. If there are duplicates, because of sequences with move 00034 transpositions or rotating/mirroring, reading will throw an exception 00035 containing an error message with line number information of the 00036 duplicates. 00037 */ 00038 00039 class GoGtpEngine; 00040 00041 class GoBook 00042 { 00043 public: 00044 class Entry 00045 { 00046 public: 00047 /** Board size. */ 00048 int m_size; 00049 00050 /** Line number in the original file. */ 00051 int m_line; 00052 00053 std::vector<SgPoint> m_sequence; 00054 00055 std::vector<SgPoint> m_moves; 00056 00057 /** Setup entry on a board. */ 00058 void ApplyTo(GoBoard& bd) const; 00059 }; 00060 00061 /** Add a book move to the current position. 00062 @throws SgException if move cannot be added (illegal or move sequence 00063 to current position cannot be determined) 00064 */ 00065 void Add(const GoBoard& bd, SgPoint move); 00066 00067 void Clear(); 00068 00069 /** Deletes a book move in the current position. 00070 @throws SgException if the move is not a book move. 00071 */ 00072 void Delete(const GoBoard& bd, SgPoint move); 00073 00074 /** Get an entry. 00075 @param index The index of the entry 00076 @see NuEntries() 00077 */ 00078 const Entry& GetEntry(std::size_t index) const; 00079 00080 /** Return line number of current position in file the book was loaded 00081 from. 00082 @return Line number or 0, if current position is not in book or 00083 was not in book, when the book was loaded. 00084 */ 00085 int Line(const GoBoard& bd) const; 00086 00087 /** Randomly select a move for the current position. 00088 Returns SG_NULLMOVE if position is not in opening book. 00089 */ 00090 SgPoint LookupMove(const GoBoard& bd) const; 00091 00092 std::vector<SgPoint> LookupAllMoves(const GoBoard& bd) const; 00093 00094 std::size_t NuEntries() const; 00095 00096 /** Read book from stream. 00097 @param in 00098 @param streamName Name used for error messages (e.g. file name) 00099 */ 00100 void Read(std::istream& in, const std::string& streamName = ""); 00101 00102 /** Read book from file. */ 00103 void Read(const std::string& filename); 00104 00105 void Write(std::ostream& out) const; 00106 00107 void WriteInfo(std::ostream& out) const; 00108 00109 private: 00110 class MapEntry 00111 { 00112 public: 00113 /** Board size. 00114 The hash code is not enough to differentiate positions with 00115 different board sizes, since the empty board always has the 00116 same hash code. 00117 */ 00118 int m_size; 00119 00120 /** Index of the original (untransformed) book entry in m_entries. */ 00121 std::size_t m_id; 00122 00123 /** Rotation as used in SgPointUtil::Rotate() */ 00124 int m_rotation; 00125 }; 00126 00127 typedef std::multimap<SgHashCode,MapEntry> Map; 00128 00129 bool m_warningMaxSizeShown; 00130 00131 int m_lineCount; 00132 00133 std::string m_streamName; 00134 00135 std::vector<Entry> m_entries; 00136 00137 /** Mapping hash key to entries. */ 00138 Map m_map; 00139 00140 void InsertEntry(const std::vector<SgPoint>& sequence, 00141 const std::vector<SgPoint>& moves, int size, 00142 GoBoard& tempBoard, int line); 00143 00144 const GoBook::MapEntry* LookupEntry(const GoBoard& bd) const; 00145 00146 void ParseLine(const std::string& line, GoBoard& tempBoard); 00147 00148 std::vector<SgPoint> ReadPoints(std::istream& in) const; 00149 00150 void ThrowError(const std::string& message) const; 00151 }; 00152 00153 inline const GoBook::Entry& GoBook::GetEntry(std::size_t index) const 00154 { 00155 SG_ASSERT(index < m_entries.size()); 00156 return m_entries[index]; 00157 } 00158 00159 inline std::size_t GoBook::NuEntries() const 00160 { 00161 return m_entries.size(); 00162 } 00163 00164 //---------------------------------------------------------------------------- 00165 00166 /** GTP commands for GoBook. */ 00167 class GoBookCommands 00168 { 00169 public: 00170 GoBookCommands(GoGtpEngine &engine, const GoBoard& bd, GoBook& book); 00171 00172 void AddGoGuiAnalyzeCommands(GtpCommand& cmd); 00173 00174 void Register(GtpEngine& e); 00175 00176 /** @page gobookcommands GoBookCommands 00177 - @link CmdAdd() @c book_add @endlink 00178 - @link CmdClear() @c book_clear @endlink 00179 - @link CmdDelete() @c book_delete @endlink 00180 - @link CmdInfo() @c book_info @endlink 00181 - @link CmdLoad() @c book_load @endlink 00182 - @link CmdMoves() @c book_moves @endlink 00183 - @link CmdPosition() @c book_position @endlink 00184 - @link CmdSave() @c book_save @endlink 00185 - @link CmdSaveAs() @c book_save_as @endlink 00186 */ 00187 /** @name Command Callbacks */ 00188 // @{ 00189 // The callback functions are documented in the cpp file 00190 void CmdAdd(GtpCommand& cmd); 00191 void CmdClear(GtpCommand& cmd); 00192 void CmdDelete(GtpCommand& cmd); 00193 void CmdInfo(GtpCommand& cmd); 00194 void CmdLoad(GtpCommand& cmd); 00195 void CmdMoves(GtpCommand& cmd); 00196 void CmdPosition(GtpCommand& cmd); 00197 void CmdSave(GtpCommand& cmd); 00198 void CmdSaveAs(GtpCommand& cmd); 00199 // @} // @name 00200 00201 private: 00202 GoGtpEngine &m_engine; 00203 00204 const GoBoard& m_bd; 00205 00206 GoBook& m_book; 00207 00208 std::string m_fileName; 00209 00210 void PositionInfo(GtpCommand& cmd); 00211 }; 00212 00213 //---------------------------------------------------------------------------- 00214 00215 #endif // GO_BOOK_H