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 "osl/record/kisen.h"
00007 #include "osl/record/csa.h"
00008 #include "osl/stl/hash_map.h"
00009
00010 #include <iostream>
00011 #include <fstream>
00012 #include <sstream>
00013
00014 struct hash
00015 {
00016 unsigned long operator() (const osl::state::SimpleState &state) const
00017 {
00018 return osl::hash::HashKey(state).signature();
00019 }
00020 };
00021
00022 struct equalKey
00023 {
00024 bool operator() (const osl::state::SimpleState &s1, const osl::state::SimpleState &s2) const
00025 {
00026 return s1 == s2;
00027 }
00028 };
00029
00030 struct State
00031 {
00032 State() : count(0)
00033 {
00034 }
00035 int count;
00036 osl::stl::vector<osl::Move> moves;
00037 };
00038
00039 void find_all(const int num_ply, const int threshold,
00040 bool save, const std::vector<std::string> &files)
00041 {
00042 osl::stl::hash_map<osl::state::SimpleState, State, hash, equalKey> states;
00043
00044 for (size_t index = 0; index < files.size(); index++)
00045 {
00046 osl::record::KisenFile kisen(files[index]);
00047 for (size_t i = 0; i < kisen.size(); i++)
00048 {
00049 const osl::vector<osl::Move> moves = kisen.getMoves(i);
00050 osl::state::NumEffectState state(kisen.getInitialState());
00051
00052 size_t j = 0;
00053 for (; j < moves.size() && j < num_ply; j++)
00054 {
00055 const osl::Position opKingPosition
00056 = state.getKingPosition(alt(state.getTurn()));
00057 if (state.hasEffectBy(state.getTurn(), opKingPosition))
00058 {
00059 break;
00060 }
00061 osl::apply_move::ApplyMoveOfTurn::doMove(state, moves[j]);
00062 }
00063 if (j == num_ply)
00064 {
00065 osl::stl::hash_map<osl::state::SimpleState, State, hash, equalKey>::iterator it = states.find(state);
00066 if (it != states.end())
00067 {
00068 (it->second.count)++;
00069 }
00070 else
00071 {
00072 State s;
00073 s.count = 1;
00074 for (size_t k = 0; k < num_ply; k++)
00075 {
00076 s.moves.push_back(moves[k]);
00077 }
00078 states[state] = s;
00079 }
00080 }
00081 }
00082 }
00083
00084 int index = 1;
00085 for (osl::stl::hash_map<osl::state::SimpleState, State, hash, equalKey>::const_iterator it = states.begin();
00086 it != states.end();
00087 ++it)
00088 {
00089 if (it->second.count >= threshold)
00090 {
00091 std::cout << index << " (" << it->second.count << ")" << std::endl;
00092 std::cout << it->first;
00093 std::ofstream output;
00094 if (save)
00095 {
00096 std::ostringstream oss(std::ostringstream::out);
00097 oss << index << ".csa";
00098 const std::string &filename = oss.str();
00099 output.open(filename.c_str());
00100 output << "PI" << std::endl
00101 << "+" << std::endl;
00102 }
00103 const osl::stl::vector<osl::Move> &moves = it->second.moves;
00104 for (size_t i = 0; i < moves.size(); i++)
00105 {
00106 std::cout << osl::record::csa::show(moves[i]) << " ";
00107 if (save)
00108 {
00109 output << osl::record::csa::show(moves[i]) << std::endl;
00110 }
00111 }
00112 if (save)
00113 {
00114 output.close();
00115 }
00116 std::cout << std::endl;
00117 index++;
00118 }
00119 }
00120 }
00121
00122 int main(int argc, char **argv)
00123 {
00124 int num_ply;
00125 int threshold;
00126 bool save_moves;
00127 boost::program_options::options_description command_line_options;
00128 command_line_options.add_options()
00129 ("num-ply",
00130 boost::program_options::value<int>(&num_ply)->default_value(10),
00131 "Show states after this number of plies are played")
00132 ("threshold",
00133 boost::program_options::value<int>(&threshold)->default_value(10),
00134 "Each state must appear this number of times to be shown")
00135 ("save",
00136 boost::program_options::value<bool>(&save_moves)->default_value(false),
00137 "Save moves leading to states to files in CSA format")
00138 ("input-file", boost::program_options::value< std::vector<std::string> >(),
00139 "input files in kisen format")
00140 ("help", "Show help message");
00141 boost::program_options::variables_map vm;
00142 boost::program_options::positional_options_description p;
00143 p.add("input-file", -1);
00144
00145 try
00146 {
00147 boost::program_options::store(
00148 boost::program_options::command_line_parser(
00149 argc, argv).options(command_line_options).positional(p).run(), vm);
00150 boost::program_options::notify(vm);
00151 if (vm.count("help"))
00152 {
00153 std::cerr << "Usage: " << argv[0] << " [options] kisen-file"
00154 << std::endl;
00155 std::cout << command_line_options << std::endl;
00156 return 0;
00157 }
00158 }
00159 catch (std::exception &e)
00160 {
00161 std::cerr << "error in parsing options" << std::endl
00162 << e.what() << std::endl;
00163 std::cerr << "Usage: " << argv[0] << " [options] kisen-file" << std::endl;
00164 std::cerr << command_line_options << std::endl;
00165 return 1;
00166 }
00167
00168 const std::vector<std::string> files =
00169 vm["input-file"].as< std::vector<std::string> >();
00170 find_all(num_ply, threshold, save_moves, files);
00171
00172 return 0;
00173 }