checkmate-kisen.cc
Go to the documentation of this file.
00001 #include "osl/container/moveVector.h"
00002 #include "osl/hash/hashKey.h"
00003 #include "osl/state/numEffectState.h"
00004 #include "osl/record/kisen.h"
00005 #include "osl/record/csaRecord.h"
00006 #include "osl/checkmate/dualDfpn.h"
00007 #include "osl/eval/see.h"
00008 
00009 #include <boost/accumulators/accumulators.hpp>
00010 #include <boost/accumulators/statistics/mean.hpp>
00011 #include <boost/accumulators/statistics/max.hpp>
00012 #include <boost/scoped_ptr.hpp>
00013 #include <boost/program_options.hpp>
00014 #include <boost/filesystem/convenience.hpp>
00015 #include <boost/foreach.hpp>
00016 #include <boost/format.hpp>
00017 #include <iostream>
00018 #include <fstream>
00019 
00020 static void convert(const std::vector<std::string> &input_filename,
00021                     const std::string &output_kisen_filename,
00022                     size_t checkmate_limit, bool output_ipx)
00023 {
00024   namespace acc = boost::accumulators;
00025   acc::accumulator_set<double, acc::features<acc::tag::max, acc::tag::mean> > accumulator;
00026   std::ofstream ofs(output_kisen_filename.c_str());
00027   osl::record::OKisenStream ks(ofs);
00028 
00029   boost::scoped_ptr<osl::record::KisenIpxWriter> ipx_writer;
00030   boost::scoped_ptr<std::ofstream> ipx_ofs;
00031   if (output_ipx)
00032   {
00033     const boost::filesystem::path ipx_path =
00034       boost::filesystem::change_extension(boost::filesystem::path(output_kisen_filename), ".ipx");
00035     const std::string ipx = ipx_path.file_string();
00036     ipx_ofs.reset(new std::ofstream(ipx.c_str()));
00037     ipx_writer.reset(new osl::record::KisenIpxWriter(*ipx_ofs));
00038   }
00039 
00040   for (size_t i = 0; i < input_filename.size(); ++i)
00041   {
00042     osl::KisenFile kisen(input_filename[i]);
00043     osl::KisenIpxFile ipx(kisen.ipxFileName());
00044     for (size_t j=0; j<kisen.size(); ++j) 
00045     {
00046       osl::NumEffectState state = kisen.getInitialState();
00047       osl::vector<osl::Move> moves = kisen.getMoves(j);
00048       osl::vector<osl::Move> new_moves;
00049       osl::record::Record new_record;
00050       new_record.setPlayer(osl::BLACK, ipx.getPlayer(j, osl::BLACK));
00051       new_record.setPlayer(osl::WHITE, ipx.getPlayer(j, osl::WHITE));
00052       osl::SimpleState record_state = state;
00053       osl::record::RecordVisitor visitor;
00054       visitor.setState(&record_state);
00055       visitor.setRecord(&new_record);
00056       osl::DualDfpn dfpn;
00057       for (size_t k=0; k<moves.size(); ++k) 
00058       {
00059         const int see = osl::See::see
00060           (state, moves[k], state.pin(state.turn()), state.pin(alt(state.turn())));
00061         visitor.addMoveAndAdvance(moves[k]);
00062         new_moves.push_back(moves[k]);
00063         state.makeMove(moves[k]);
00064         if (state.inCheck() && see < 0
00065             && dfpn.isLosingState(checkmate_limit, state, 
00066                                   osl::HashKey(state), osl::PathEncoding(state.turn())))
00067           break;
00068       }
00069       new_record.setResult(state.turn() == osl::BLACK
00070                            ? osl::Record::WHITE_WIN : osl::Record::BLACK_WIN);
00071       accumulator(moves.size() - new_record.getMoves().size());
00072       if (new_record.getMoves().size() >= 256)
00073         std::cerr << "long record " << j << ' ' << new_record.getMoves().size() << "\n";
00074       ks.save(&new_record);
00075       if (output_ipx)
00076       {
00077         ipx_writer->save(new_record, 0, 0, "", "");
00078       }
00079       if ((j % 1000) == 999)
00080         std::cerr << input_filename[i] << " " << j
00081                   << " max " << acc::max(accumulator)
00082                   << " mean " << acc::mean(accumulator) << "\n";
00083     }
00084     std::cerr << input_filename[i]
00085               << " max " << acc::max(accumulator)
00086               << " mean " << acc::mean(accumulator) << "\n";
00087   }
00088 }
00089 
00090 int main(int argc, char **argv)
00091 {
00092   bool output_ipx;
00093   std::string kisen_filename;
00094   size_t checkmate_limit;
00095   boost::program_options::options_description command_line_options;
00096   command_line_options.add_options()
00097     ("output-ipx",
00098      boost::program_options::value<bool>(&output_ipx)->default_value(true),
00099      "Whether output IPX file in addition to KIF file")
00100     ("output-kisen-filename,o",
00101      boost::program_options::value<std::string>(&kisen_filename)->
00102      default_value("test.kif"),
00103      "Output filename of Kisen file")
00104     ("checkmate-limit,l",
00105      boost::program_options::value<size_t>(&checkmate_limit)->default_value(1000),
00106      "Whether output IPX file in addition to KIF file")
00107     ("input-file", boost::program_options::value< std::vector<std::string> >(),
00108      "input files in kisen format")
00109     ("help", "Show help message");
00110   boost::program_options::variables_map vm;
00111   boost::program_options::positional_options_description p;
00112   p.add("input-file", -1);
00113 
00114   try
00115   {
00116     boost::program_options::store(
00117       boost::program_options::command_line_parser(
00118         argc, argv).options(command_line_options).positional(p).run(), vm);
00119     boost::program_options::notify(vm);
00120     if (vm.count("help"))
00121     {
00122       std::cerr << "Usage: " << argv[0] << " [options] kisen-files\n";
00123       std::cerr << "       " << argv[0] << " [options]\n";
00124       std::cout << command_line_options << std::endl;
00125       return 0;
00126     }
00127   }
00128   catch (std::exception &e)
00129   {
00130     std::cerr << "error in parsing options" << std::endl
00131               << e.what() << std::endl;
00132     std::cerr << "Usage: " << argv[0] << " [options] kisen-files\n";
00133     std::cerr << "       " << argv[0] << " [options]\n";
00134     std::cerr << command_line_options << std::endl;
00135     return 1;
00136   }
00137 
00138   std::vector<std::string> files;
00139   if (vm.count("input-file"))
00140     files = vm["input-file"].as<std::vector<std::string> >();
00141 
00142   convert(files, kisen_filename, checkmate_limit, output_ipx);
00143   return 0;
00144 }
00145 // ;;; Local Variables:
00146 // ;;; mode:c++
00147 // ;;; c-basic-offset:2
00148 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines