14 #include <boost/shared_ptr.hpp>
15 #include <boost/program_options.hpp>
16 #include <boost/progress.hpp>
17 #include <boost/format.hpp>
25 #include <boost/shared_ptr.hpp>
39 const boost::program_options::options_description& command_line_options)
41 out <<
"Usage: " << argv[0] <<
" [options] <book-a.dat> <book-b.dat>\n"
42 << command_line_options
46 typedef osl::hash_map<osl::HashKey,int>
table_t;
51 std::fill(parents.begin(), parents.end(), -1);
54 typedef std::pair<int, int> state_depth_t;
55 std::deque<state_depth_t> stateToVisit;
56 stateToVisit.push_back(state_depth_t(book.
getStartState(), 1));
60 typedef std::pair<int, int> eval_depth_t;
63 while (!stateToVisit.empty())
65 const state_depth_t state_depth = stateToVisit.front();
66 const int stateIndex = state_depth.first;
67 const int depth = state_depth.second;
68 stateToVisit.pop_front();
70 assert(parents[stateIndex] >= 0 || stateIndex == book.
getStartState());
72 depth_found =
std::max(depth_found, depth);
78 if ( !moves.empty() &&
85 min = moves.at(0).getWeight();
90 const int weight = moves.at(i).getWeight();
91 if ((
double)weight < (
double)moves.at(i-1).getWeight()*
ratio)
98 if (min == 0) min = 1;
100 WMoveContainer::iterator each = moves.begin();
101 for (; each != moves.end(); ++each)
103 if (each->getWeight() <
min)
106 moves.erase(each, moves.end());
115 if (moves[0].getWeight()) {
118 const osl::HashKey key(state);
119 table[key] = stateIndex;
124 for (std::vector<osl::record::opening::WMove>::const_iterator each = moves.begin();
125 each != moves.end(); ++each)
127 const int nextIndex = each->getStateIndex();
128 if (parents[nextIndex] < 0) {
129 parents[nextIndex] = stateIndex;
130 stateToVisit.push_back(state_depth_t(nextIndex, depth+1));
136 std::cout << std::endl;
137 std::cout << boost::format(
"Player: %s\n") %
the_player;
139 boost::format(
"#leaves: %d, max_depth %d\n")
149 if (! moves.empty() && moves[0].getWeight()) {
151 for (
size_t i=0; i<moves.size(); ++i) {
152 if (moves[i].getWeight() == 0)
154 const int next_state_index = moves[i].getStateIndex();
158 <<
"(" << moves[i].getWeight() <<
"," << black_win <<
"," << white_win <<
")";
166 std::cout <<
"[" << history.size() <<
"]";
167 for (
size_t i=0; i<history.size(); ++i)
169 std::cout << std::endl;
174 osl::vector<int> history;
175 history.push_back(node);
176 while (parents[node] >= 0) {
177 node = parents[node];
178 history.push_back(node);
180 std::reverse(history.begin(), history.end());
184 for (
size_t i=0; i<history.size()-1; ++i) {
186 for (WMoveContainer::const_iterator p=moves.begin(); p!=moves.end(); ++p) {
187 if (p->getStateIndex() != history[i+1])
189 result.push_back(p->getMove());
201 boost::shared_ptr<osl::record::Characters>(
204 printer.print(state);
205 const osl::MoveVector history_a =
make_history(book_a, parents_a, node_a);
206 const osl::MoveVector history_b =
make_history(book_b, parents_b, node_b);
208 if (! (history_a == history_b))
218 boost::shared_ptr<osl::record::Characters>(
221 printer.print(state);
236 for (; i<
std::min(moves_a.size(), moves_b.size()); ++i) {
237 if (moves_a[i].getWeight() == 0)
238 return moves_b[i].getWeight() == 0;
239 if (moves_b[i].getWeight() == 0)
241 if (moves_a[i].getMove() != moves_b[i].getMove())
244 if (i == moves_a.size())
245 return i == moves_b.size() || moves_b[i].getWeight() == 0;
246 return moves_a[i].getWeight() == 0;
252 long only_a = 0, only_b = 0, same = 0, diff = 0;
253 for (table_t::const_iterator p=table_a.begin(); p!=table_a.end(); ++p) {
254 table_t::const_iterator q=table_b.find(p->first);
255 if (q == table_b.end()) {
258 dump(
"a", book_a, parents_a, p->second);
266 dump(book_a, parents_a, p->second,
267 book_b, parents_b, q->second);
270 for (table_t::const_iterator p=table_b.begin(); p!=table_b.end(); ++p) {
271 table_t::const_iterator q=table_a.find(p->first);
272 if (q == table_a.end()) {
275 dump(
"b", book_b, parents_b, p->second);
279 std::cout <<
"same " << same <<
" diff " << diff
280 <<
" only-in-a " << only_a <<
" only-in-b " << only_b << std::endl;
283 int main(
int argc,
char **argv)
285 std::string player_str;
287 namespace bp = boost::program_options;
288 bp::variables_map
vm;
289 bp::options_description command_line_options;
290 command_line_options.add_options()
291 (
"player,p", bp::value<std::string>(&player_str)->default_value(
"black"),
292 "specify a player, black or white, in whose point of view the book is validated. "
294 (
"input-file,f", bp::value<std::vector<std::string> >(),
295 "a joseki file to validate.")
297 "common: dump positions where two books have different moves\n"
298 "(a|b): dump positions registered to only book_[ab]\n")
299 (
"determinate", bp::value<int>(&
is_determinate)->default_value(0),
300 "only search the top n moves. (0 for all, 1 for determinate).")
302 "use the best move where the depth is greater than this value")
303 (
"max-depth", bp::value<int>(&
max_depth)->default_value(100),
304 "do not go beyond this depth from the root")
305 (
"ratio", bp::value<double>(&
ratio)->default_value(0.0),
306 "skip move[i] (i >= n), if weight[n] < weight[n-1]*ratio")
307 (
"help,h",
"show this help message.");
308 bp::positional_options_description p;
309 p.add(
"input-file", -1);
311 std::vector<std::string> filenames;
315 bp::command_line_parser(
316 argc, argv).options(command_line_options).positional(p).
run(), vm);
318 filenames = vm[
"input-file"].as<std::vector<std::string> >();
319 if (vm.count(
"help") || filenames.size() != 2
322 printUsage(std::cout, argv, command_line_options);
326 catch (std::exception &e)
328 std::cerr <<
"error in parsing options\n"
329 << e.what() << std::endl;
330 printUsage(std::cerr, argv, command_line_options);
334 if (player_str ==
"black")
336 else if (player_str ==
"white")
340 printUsage(std::cerr, argv, command_line_options);
345 osl::CArray<osl::vector<int>,2> parents;
346 osl::CArray<table_t,2> tables;
347 std::cout << boost::format(
"Book: %s\n") % filenames[0];
348 store(book_a, tables[0], parents[0]);
349 std::cout << boost::format(
"Book: %s\n") % filenames[1];
350 store(book_b, tables[1], parents[1]);
352 compare(book_a, tables[0], parents[0], book_b, tables[1], parents[1]);