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