00001 #include "osl/category/standardMoveGenerator.h"
00002 #include "osl/category/categoryListUtil.h"
00003 #include "osl/category/categoryUtil.h"
00004 #include "osl/category/analyzer/probOfEachCategory.h"
00005 #include "osl/category/analyzer/orderOfMove.h"
00006 #include "osl/stat/histogram.h"
00007 #include "osl/stat/average.h"
00008 #include "osl/container/moveStack.h"
00009 #include "osl/container/moveLogProbSet.h"
00010 #include "osl/eval/pieceEval.h"
00011 #include "osl/eval/progressEval.h"
00012 #include "osl/state/numEffectState.h"
00013 #include "osl/moveLogProb.h"
00014 #include "osl/record/csaRecord.h"
00015 #include "osl/record/csaIOError.h"
00016 #include "osl/record/kanjiPrint.h"
00017 #include "osl/move_generator/legalMoves.h"
00018 #include "osl/apply_move/applyMove.h"
00019 #include <boost/format.hpp>
00020 #include <boost/version.hpp>
00021 #include <iostream>
00022 #include <string>
00023 #include <map>
00024 using namespace osl;
00025 using namespace osl::eval;
00026 using namespace osl::category;
00027 using namespace osl::category::analyzer;
00028
00029 #if (BOOST_VERSION / 100) < 1033 // 1033?
00030
00031 # define BOOST_FORMAT_BUG
00032 #endif
00033
00039 void usage(const char *prog)
00040 {
00041 using namespace std;
00042 cerr << "Usage: " << prog << " [-va] [-l limit] [-O order-limit] [-f skip] csafiles\n"
00043 << "-v verbose output\n"
00044 << "-V very verbose output\n"
00045 << "-a analyze all legal moves\n"
00046 << endl;
00047 exit(1);
00048 }
00049
00051 int limit = 0;
00053 int orderLimit=0;
00055 size_t first_skip = 0;
00056 bool verbose = false;
00057 bool very_verbose = false;
00058 bool all_moves = false;
00059
00060 stat::Average totalProbAverage, totalAllProbAverage,
00061 totalOrderAverage, totalGeneratedAverage;
00062 const size_t phWidth = 200, phLength=8;
00064 stat::Histogram totalProbHistogram(phWidth, phLength);
00066 stat::Histogram totalAllProbHistogram(phWidth, phLength);
00067 const size_t ohWidth = 10, ohLength=10;
00068 stat::Histogram totalOrderHistogram(ohWidth, ohLength);
00069 stat::Histogram totalGeneratedHistogram(ohWidth, ohLength);
00070
00071 void testFile(const char *fileName);
00072
00073 struct CategoryRollBook : private OrderOfMove::Output
00074 {
00075 struct Data
00076 {
00078 stat::Average prob;
00080 stat::Average order;
00082 int redherring;
00083 Data() : redherring(0)
00084 {
00085 }
00086 };
00087 private:
00088 typedef std::map<std::string, Data> map_t;
00089 map_t book;
00090 public:
00092 Move analysisTarget;
00094 void generatorOfEachMove(const char *name, const MoveLogProb& move)
00095 {
00096 if (analysisTarget == move.getMove())
00097 {
00098 book[name].prob.add(move.getLogProb());
00099 book[name].order.add(order);
00100 }
00101 else
00102 {
00103 book[name].redherring++;
00104 }
00105 }
00106 public:
00107 CategoryRollBook();
00108 template <class MG>
00109 MoveLogProb analyzeMove(const CategoryEnv& env, Move target,
00110 int *order, int *generated)
00111 {
00112 this->order = 0;
00113 this->generated = 0;
00114 analysisTarget = target;
00115 OrderOfMove orderAnalyzer(env, target, *this);
00116 const MoveLogProb result = orderAnalyzer.generate(StandardMoveGenerator());
00117 *order = this->order;
00118 *generated = this->generated;
00119 return result;
00120 }
00121 typedef std::multimap<int, std::pair<std::string, const Data*>,
00122 std::greater<int> > sorter_t;
00123 void show(std::ostream& os, const sorter_t& sorter) const
00124 {
00125 os << "\nname Ψ ʾγΨμΨ Ψ\n";
00126 for (sorter_t::const_iterator p=sorter.begin(); p!=sorter.end(); ++p)
00127 {
00128 const int hit = p->first;
00129 const int red = p->second.second->redherring;
00130 const double ratio = 100.0*static_cast<double>(hit)/(hit+red);
00131 #ifndef BOOST_FORMAT_BUG
00132 os << boost::format("%22s % 8d % 8d %5.1f % 6.1f % 6.1f\n")
00133 % p->second.first
00134 % hit % red % ratio
00135 % p->second.second->order.getAverage()
00136 % p->second.second->prob.getAverage();
00137 #else
00138 os << p->second.first
00139 << " " << hit << " " << red << " " << ratio
00140 << " " << p->second.second->order.getAverage()
00141 << " " << p->second.second->prob.getAverage() << "\n";
00142 #endif
00143 }
00144 }
00145 void show(std::ostream& os) const
00146 {
00147 sorter_t sorter;
00148 for (map_t::const_iterator p=book.begin(); p!=book.end(); ++p)
00149 {
00150 sorter.insert(std::make_pair(p->second.order.numElements(),
00151 std::make_pair(p->first, &p->second)));
00152 }
00153 show(os, sorter);
00154 }
00155 };
00156 CategoryRollBook::CategoryRollBook()
00157 {
00158 }
00159
00160 CategoryRollBook book;
00161
00162 int main(int argc, char **argv)
00163 {
00164 const char *program_name = argv[0];
00165 bool error_flag = false;
00166 extern char *optarg;
00167 extern int optind;
00168
00169 char c;
00170 while ((c = getopt(argc, argv, "al:f:O:sVvh")) != EOF)
00171 {
00172 switch(c)
00173 {
00174 case 'a': all_moves = true;
00175 break;
00176 case 'l': limit = atoi(optarg);
00177 break;
00178 case 'f': first_skip = atoi(optarg);
00179 break;
00180 case 'O': orderLimit = atoi(optarg);
00181 break;
00182 case 'V': very_verbose = true;
00183
00184 case 'v': verbose = true;
00185 break;
00186 default: error_flag = true;
00187 }
00188 }
00189 argc -= optind;
00190 argv += optind;
00191
00192 if (error_flag || (argc < 1))
00193 usage(program_name);
00194
00195 for (int i=0; i<argc; ++i)
00196 {
00197 if ((! verbose) && (i % 128 == 0))
00198 std::cerr << '.';
00199 testFile(argv[i]);
00200 }
00201
00202 std::cout << "\n"
00203 << "average order " << totalOrderAverage.getAverage() << "\n";
00204 totalOrderHistogram.show(std::cout);
00205 std::cout << "average generated moves " << totalGeneratedAverage.getAverage() << "\n";
00206 totalGeneratedHistogram.show(std::cout);
00207 std::cout << "average probability of recorded moves " << totalProbAverage.getAverage() << "\n";
00208 totalProbHistogram.show(std::cout);
00209 std::cout << "average probability of all moves " << totalAllProbAverage.getAverage() << "\n";
00210 totalAllProbHistogram.show(std::cout);
00211 book.show(std::cout);
00212 }
00213
00214 void analyze_move(const CategoryEnv& env, const NumEffectState& state, Move move)
00215 {
00216 csaShow(std::cout, move);
00217 ProbOfEachCategory::Reporter reporter(std::cout, very_verbose);
00218 const int diff
00219 = PieceEval::computeDiffAfterMoveForRP(state, move);
00220 std::cout << " soma " << diff << "\n";
00221 ProbOfEachCategory a(env, move, &reporter);
00222 a.analyze(StandardMoveGenerator());
00223 std::cout << "\n";
00224 }
00225 void analyze_all_moves(const CategoryEnv& env, const NumEffectState& state)
00226 {
00227 MoveVector moves;
00228 LegalMoves::generate(state, moves);
00229
00230 for (unsigned int i=0; i<moves.size(); ++i)
00231 {
00232 analyze_move(env, state, moves[i]);
00233 }
00234 }
00235
00236 void testFile(const char *filename)
00237 {
00238 Record rec;
00239 try
00240 {
00241 rec = CsaFile(filename).getRecord();
00242 }
00243 catch (CsaIOError& e)
00244 {
00245 std::cerr << "skip " << filename <<"\n";
00246 std::cerr << e.what() << "\n";
00247 return;
00248 }
00249 catch (...)
00250 {
00251 throw;
00252 }
00253
00254 NumEffectState state(rec.getInitialState());
00255 const osl::stl::vector<osl::Move> moves=rec.getMoves();
00256
00257 record::KanjiPrint printer(std::cout);
00258 MoveStack history;
00259 ProgressEval eval(state);
00260
00261 stat::Histogram probHistogram(phWidth,phLength);
00262 stat::Histogram orderHistogram(ohWidth, ohLength);
00263 stat::Histogram generatedHistogram(ohWidth, ohLength);
00264 stat::Average orderAverage, generatedAverage, probAverage;
00265
00266 for (size_t i=0; i<moves.size(); ++i)
00267 {
00268 const Move move = moves[i];
00269 assert(state.isValidMove(move));
00271 if (i >= first_skip)
00272 {
00273 CategoryEnv env(&state, 2000, &history, eval.progress32());
00274
00275 int order=0, generated = 0;
00276 const MoveLogProb found =
00277 book.analyzeMove<StandardMoveGenerator>(env, move, &order, &generated);
00278
00279 assert(found.validMove()
00280 || (std::cerr << state << move << " " << found << " " << filename << "\n",0));
00281 orderHistogram.add(order);
00282 orderAverage.add(order);
00283 generatedHistogram.add(generated);
00284 generatedAverage.add(generated);
00285 probHistogram.add(found.getLogProb());
00286 probAverage.add(found.getLogProb());
00287 if (verbose
00288 || (limit && (found.getLogProb() > limit))
00289 || (orderLimit && (order > orderLimit)))
00290 {
00291 printer.print(state);
00292 std::cout << found << "\n";
00293 if (all_moves)
00294 analyze_all_moves(env, state);
00295 else
00296 analyze_move(env, state, move);
00297 }
00298
00299 MoveLogProbSet allMoves;
00300 CategoryListUtil::gatherAllMoves<StandardMoveGenerator>(env, allMoves);
00301 for (MoveLogProbSet::const_iterator p=allMoves.begin();
00302 p!=allMoves.end(); ++p)
00303 {
00304 totalAllProbHistogram.add(p->getLogProb());
00305 totalAllProbAverage.add(p->getLogProb());
00306 }
00307 }
00308 ApplyMoveOfTurn::doMove(state, move);
00309 eval.update(state, move);
00310 history.push(move);
00311 }
00312 if (verbose)
00313 {
00314 std::cout << "arevage order " << orderAverage.getAverage() << "\t";
00315 std::cout << "arevage prob. " << probAverage.getAverage() << "\n";
00316 }
00317
00318 totalOrderAverage.merge(orderAverage);
00319 totalOrderHistogram.merge(orderHistogram);
00320 totalGeneratedAverage.merge(generatedAverage);
00321 totalGeneratedHistogram.merge(generatedHistogram);
00322 totalProbAverage.merge(probAverage);
00323 totalProbHistogram.merge(probHistogram);
00324 }
00325
00326
00327
00328
00329
00330