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::calcHash(state).getSignature(); 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 }