Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

BookCommands.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file BookCommands.cpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #include "BookBuilder.hpp"
00007 #include "BookCommands.hpp"
00008 #include "VCUtils.hpp"
00009 
00010 using namespace benzene;
00011 
00012 //----------------------------------------------------------------------------
00013 
00014 BookCommands::BookCommands(Game& game, HexEnvironment& env, 
00015                            boost::scoped_ptr<Book>& book, 
00016                            BookCheck& bookCheck)
00017     : m_game(game),
00018       m_env(env),
00019       m_book(book), 
00020       m_bookCheck(bookCheck)
00021 {
00022 }
00023 
00024 BookCommands::~BookCommands()
00025 {
00026 }
00027 
00028 void BookCommands::Register(GtpEngine& e)
00029 {
00030     Register(e, "book-open", &BookCommands::CmdBookOpen);
00031     Register(e, "book-close", &BookCommands::CmdBookClose);
00032     Register(e, "book-stat", &BookCommands::CmdBookStat);
00033     Register(e, "book-depths", &BookCommands::CmdBookMainLineDepth);
00034     Register(e, "book-counts", &BookCommands::CmdBookCounts);
00035     Register(e, "book-scores", &BookCommands::CmdBookScores);
00036     Register(e, "book-visualize", &BookCommands::CmdBookVisualize);
00037     Register(e, "book-dump-polarized-leafs", 
00038              &BookCommands::CmdBookDumpPolarizedLeafs);
00039     Register(e, "book-import-solved", 
00040              &BookCommands::CmdBookImportSolvedStates);
00041     Register(e, "book-set-value", &BookCommands::CmdBookSetValue);
00042     Register(e, "param_book", &BookCommands::CmdBookParam);
00043 }
00044 
00045 void BookCommands::Register(GtpEngine& engine, const std::string& command,
00046                           GtpCallback<BookCommands>::Method method)
00047 {
00048     engine.Register(command, new GtpCallback<BookCommands>(this, method));
00049 }
00050 
00051 //----------------------------------------------------------------------------
00052 
00053 /** Opens/Creates an opening book for the current boardsize.
00054     Usage: "book-expand [filename]"
00055 */
00056 void BookCommands::CmdBookOpen(HtpCommand& cmd)
00057 {
00058     cmd.CheckNuArgLessEqual(2);
00059     std::string fn = cmd.Arg(0);
00060     try {
00061         m_book.reset(new Book(fn));
00062     }
00063     catch (BenzeneException& e) {
00064         cmd << "Error opening book: '" << e.what() << "'\n";
00065     }
00066 }
00067 
00068 /** Closes a book if one is open. */
00069 void BookCommands::CmdBookClose(HtpCommand& cmd)
00070 {
00071     cmd.CheckArgNone();
00072     if (m_book.get() == 0)
00073         throw HtpFailure() << "No open book.";        
00074     m_book.reset(0);
00075 }
00076 
00077 void BookCommands::CmdBookStat(HtpCommand& cmd)
00078 {
00079     cmd.CheckNuArg(0);
00080     if (m_book.get() == 0)
00081         throw HtpFailure("No open book!\n");
00082     cmd << m_book->BDBStatistics();
00083 }
00084 
00085 void BookCommands::CmdBookMainLineDepth(HtpCommand& cmd)
00086 {
00087     if (m_book.get() == 0) 
00088         throw HtpFailure() << "No open book.";
00089     HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00090     for (BitsetIterator p(state.Position().GetEmpty()); p; ++p) 
00091     {
00092         state.PlayMove(*p);
00093         cmd << " " << *p << " " << BookUtil::GetMainLineDepth(*m_book, state);
00094         state.UndoMove(*p);
00095     }
00096 }
00097 
00098 void BookCommands::CmdBookCounts(HtpCommand& cmd)
00099 {
00100     if (m_book.get() == 0) 
00101         throw HtpFailure() << "No open book.";
00102     HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00103     for (BitsetIterator p(state.Position().GetEmpty()); p; ++p) 
00104     {
00105         state.PlayMove(*p);
00106         HexBookNode node;
00107         if (m_book->Get(state, node))
00108             cmd << " " << *p << " " << node.m_count;
00109         state.UndoMove(*p);
00110     }
00111 }
00112 
00113 void BookCommands::CmdBookScores(HtpCommand& cmd)
00114 {
00115     if (m_book.get() == 0) 
00116         throw HtpFailure() << "No open book.";
00117     float countWeight = m_bookCheck.CountWeight();
00118     HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00119 
00120     std::map<HexPoint, HexEval> values;
00121     std::map<HexPoint, unsigned> counts;
00122     std::vector<std::pair<float, HexPoint> > scores;
00123     for (BitsetIterator p(state.Position().GetEmpty()); p; ++p) 
00124     {
00125         state.PlayMove(*p);
00126         HexBookNode node;
00127         if (m_book->Get(state, node))
00128         {
00129             counts[*p] = node.m_count;
00130             values[*p] = BookUtil::InverseEval(BookUtil::Value(node, state));
00131             scores.push_back(std::make_pair
00132                              (-BookUtil::Score(node, state, countWeight), *p));
00133         }
00134         state.UndoMove(*p);
00135     }
00136     std::stable_sort(scores.begin(), scores.end());
00137     std::vector<std::pair<float, HexPoint> >::const_iterator it 
00138         = scores.begin();
00139     for (; it != scores.end(); ++it)
00140     {
00141         HexPoint p = it->second;
00142         HexEval value = values[p];
00143         cmd << ' ' << p;
00144         if (HexEvalUtil::IsWin(value))
00145             cmd << " W";
00146         else if (HexEvalUtil::IsLoss(value))
00147             cmd << " L";
00148         else
00149             cmd << " " << std::fixed << std::setprecision(3) << value;
00150         cmd << '@' << counts[p];
00151     }
00152 }
00153 
00154 void BookCommands::CmdBookVisualize(HtpCommand& cmd)
00155 {
00156     if (m_book.get() == 0) 
00157         throw HtpFailure() << "No open book.";
00158     cmd.CheckNuArg(1);
00159     std::string filename = cmd.Arg(0);
00160     HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00161     std::ofstream f(filename.c_str());
00162     if (!f)
00163         throw HtpFailure() << "Could not open file for output.";
00164     BookUtil::DumpVisualizationData(*m_book, state, 0, f);
00165     f.close();
00166 }
00167 
00168 /** Dumps variations leading to non-terminal leafs whose value is
00169     polarized. The ignore file is an optional argument that lists
00170     states that should not be ingored (not dumped again). 
00171     Usage:
00172       book-dump-polarized-leafs [polarization] [output file] { [ignore file] }
00173 */
00174 void BookCommands::CmdBookDumpPolarizedLeafs(HtpCommand& cmd)
00175 {
00176     if (m_book.get() == 0) 
00177         throw HtpFailure() << "No open book.";
00178     cmd.CheckNuArgLessEqual(3);
00179     float polarization = cmd.FloatArg(0);
00180     std::string filename = cmd.Arg(1);
00181     StateSet ignoreSet;
00182     if (cmd.NuArg() == 3u)
00183     {
00184         std::string ignoreFile = cmd.Arg(2);
00185         HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00186         std::ifstream ifs(ignoreFile.c_str()); 
00187         if (!ifs)
00188             throw HtpFailure() << "Could not open ignore file for reading.";
00189         std::string line;
00190         while (std::getline(ifs, line))
00191         {
00192             PointSequence seq;
00193             HexPointUtil::FromString(line, seq);
00194             if (!seq.empty())
00195             {
00196                 state.Position().StartNewGame();
00197                 state.SetToPlay(FIRST_TO_PLAY);
00198                 for (std::size_t i = 0; i < seq.size(); ++i)
00199                     state.PlayMove(seq[i]);
00200                 ignoreSet.Insert(state);
00201             }
00202         }
00203         LogInfo() << "Read " << ignoreSet.Size() << " positions to ignore.\n";
00204     }
00205     HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00206     PointSequence pv;
00207     GameUtil::HistoryToSequence(m_game.History(), pv);
00208     std::ofstream f(filename.c_str());
00209     if (!f)
00210         throw HtpFailure() << "Could not open file for output.";
00211     BookUtil::DumpPolarizedLeafs(*m_book, state, polarization, pv, f, 
00212                                  ignoreSet);
00213     f.close();
00214 }
00215 
00216 /** Imports positions from file into book. */
00217 void BookCommands::CmdBookImportSolvedStates(HtpCommand& cmd)
00218 {
00219     if (m_book.get() == 0)
00220         throw HtpFailure() << "No open book.";
00221     cmd.CheckNuArg(1);
00222     std::string filename = cmd.Arg(0);
00223     std::ifstream f(filename.c_str());
00224     if (!f)
00225         throw HtpFailure() << "Could not open file for reading.";
00226     BookUtil::ImportSolvedStates(*m_book, m_game.Board().Const(), f);
00227     f.close();
00228 }
00229 
00230 /** Sets value of current state in the book.
00231     Usage:
00232       book-set-value [value]
00233     Where [value] can be one of W, L, or value in rage [0, 1]. 
00234  */
00235 void BookCommands::CmdBookSetValue(HtpCommand& cmd)
00236 {
00237     if (m_book.get() == 0) 
00238         throw HtpFailure() << "No open book.";
00239     float value = 0.5;
00240     std::string vstr = cmd.ArgToLower(0);
00241     if (vstr == "w")
00242         value = IMMEDIATE_WIN;
00243     else if (vstr == "l")
00244         value = IMMEDIATE_LOSS;
00245     else
00246         value = cmd.FloatArg(0);
00247     HexBookNode node;
00248     HexState state(m_game.Board(), m_game.Board().WhoseTurn());
00249     if (!m_book->Get(state, node))
00250         m_book->Put(state, HexBookNode(value));
00251     else
00252     {
00253         node.m_value = value;
00254         m_book->Put(state, node);
00255     }
00256     m_book->Flush();
00257 }
00258 
00259 void BookCommands::CmdBookParam(HtpCommand& cmd)
00260 {
00261     if (cmd.NuArg() == 0)
00262     {
00263         cmd << '\n'
00264             << "[string] book_count_weight "
00265             << m_bookCheck.CountWeight() << '\n'
00266             << "[string] book_min_count "
00267             << m_bookCheck.MinCount() << '\n';
00268     }
00269     else if (cmd.NuArg() == 2)
00270     {
00271         std::string name = cmd.Arg(0);
00272         if (name == "book_min_count")
00273             m_bookCheck.SetMinCount(cmd.SizeTypeArg(1, 0));
00274         else if (name == "book_count_weight")
00275             m_bookCheck.SetCountWeight(cmd.FloatArg(1));
00276         else 
00277             throw HtpFailure() << "Unknown parameter: " << name;
00278     }
00279     else 
00280         throw HtpFailure("Expected 0 ore 2 arguments");
00281 }
00282 
00283 //----------------------------------------------------------------------------


6 Jan 2011 Doxygen 1.6.3