00001 #include "osl/apply_move/applyMove.h"
00002 #include "osl/state/numEffectState.h"
00003 #include "osl/hash/hashKey.h"
00004
00005 #include <boost/program_options.hpp>
00006 #include <boost/format.hpp>
00007 #include "osl/record/kisen.h"
00008 #include "osl/record/csa.h"
00009 #include <osl/stl/hash_set.h>
00010
00011 #include <iostream>
00012 #include <fstream>
00013 #include <sstream>
00014
00015 struct hash
00016 {
00017 unsigned long operator() (const osl::state::SimpleState &state) const
00018 {
00019 return osl::hash::HashKey(state).signature();
00020 }
00021 };
00022
00023 void find_all(const int num_ply, const int threshold,
00024 bool save, const std::vector<std::string> &files)
00025 {
00026 osl::stl::hash_set<osl::state::SimpleState, hash> states;
00027
00028 for (size_t index = 0; index < files.size(); index++)
00029 {
00030 osl::record::KisenFile kisen(files[index]);
00031 for (size_t i = 0; i < kisen.size(); i++)
00032 {
00033 const osl::vector<osl::Move> moves = kisen.getMoves(i);
00034 osl::state::NumEffectState state(kisen.getInitialState());
00035
00036 states.insert(state);
00037 for (size_t j = 0; j < moves.size() && j < static_cast<size_t>(num_ply);
00038 j++)
00039 {
00040 const osl::Position opKingPosition
00041 = state.getKingPosition(alt(state.getTurn()));
00042 if (state.hasEffectBy(state.getTurn(), opKingPosition))
00043 {
00044 break;
00045 }
00046 osl::apply_move::ApplyMoveOfTurn::doMove(state, moves[j]);
00047 states.insert(state);
00048 }
00049 }
00050 }
00051
00052 int index = 0;
00053 for (osl::stl::hash_set<osl::state::SimpleState, hash>::const_iterator it =
00054 states.begin();
00055 it != states.end();
00056 ++it)
00057 {
00058 if (save)
00059 {
00060 std::ofstream output;
00061 output.open((boost::format("%05d.csa") % index++).str().c_str());
00062 output << *it;
00063 output.close();
00064 }
00065 else
00066 {
00067 std::cout << *it;
00068 }
00069 }
00070 }
00071
00072 int main(int argc, char **argv)
00073 {
00074 int num_ply;
00075 int threshold;
00076 bool save_moves;
00077 boost::program_options::options_description command_line_options;
00078 command_line_options.add_options()
00079 ("num-ply",
00080 boost::program_options::value<int>(&num_ply)->default_value(10),
00081 "Show states after this number of plies are played")
00082 ("threshold",
00083 boost::program_options::value<int>(&threshold)->default_value(10),
00084 "Each state must appear this number of times to be shown")
00085 ("save",
00086 boost::program_options::value<bool>(&save_moves)->default_value(false),
00087 "Save moves leading to states to files in CSA format")
00088 ("input-file", boost::program_options::value< std::vector<std::string> >(),
00089 "input files in kisen format")
00090 ("help", "Show help message");
00091 boost::program_options::variables_map vm;
00092 boost::program_options::positional_options_description p;
00093 p.add("input-file", -1);
00094
00095 try
00096 {
00097 boost::program_options::store(
00098 boost::program_options::command_line_parser(
00099 argc, argv).options(command_line_options).positional(p).run(), vm);
00100 boost::program_options::notify(vm);
00101 if (vm.count("help"))
00102 {
00103 std::cerr << "Usage: " << argv[0] << " [options] kisen-file"
00104 << std::endl;
00105 std::cout << command_line_options << std::endl;
00106 return 0;
00107 }
00108 }
00109 catch (std::exception &e)
00110 {
00111 std::cerr << "error in parsing options" << std::endl
00112 << e.what() << std::endl;
00113 std::cerr << "Usage: " << argv[0] << " [options] kisen-file" << std::endl;
00114 std::cerr << command_line_options << std::endl;
00115 return 1;
00116 }
00117
00118 const std::vector<std::string> files =
00119 vm["input-file"].as< std::vector<std::string> >();
00120 find_all(num_ply, threshold, save_moves, files);
00121
00122 return 0;
00123 }