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