ratingstat.cc
Go to the documentation of this file.
00001 #include "osl/rating/featureSet.h"
00002 #include "osl/rating/ratingEnv.h"
00003 #include "osl/rating/bradleyTerry.h"
00004 #include "osl/eval/progressEval.h"
00005 #include "osl/effect_util/effectUtil.h"
00006 #include "osl/record/csaRecord.h"
00007 #include "osl/record/csaIOError.h"
00008 #include "osl/record/kisen.h"
00009 #include "osl/misc/perfmon.h"
00010 #include "osl/stat/histogram.h"
00011 #include "osl/stat/variance.h"
00012 #include "osl/stl/vector.h"
00013 
00014 #include <boost/format.hpp>
00015 #include <string>
00016 #include <iostream>
00017 #include <iomanip>
00018 #include <cmath>
00019 using namespace osl;
00020 using namespace osl::rating;
00021 
00022 void usage(const char *prog)
00023 {
00024   using namespace std;
00025   cerr << "Usage: " << prog << " [-v] [-f skip] csafiles or -k kisen-filename -n num\n"
00026        << endl;
00027   exit(1);
00028 }
00029 
00030 size_t first_skip = 3;
00031 int verbose = 0;
00032 const char *kisen_filename=0;
00033 size_t num_kisen = 4000;
00034 size_t kisen_start = 200000;
00035 size_t min_rating = 1500;
00036 
00037 struct KeepMin
00038 {
00039   int min;
00040   explicit KeepMin(int initial = 10000) : min(initial)
00041   {
00042   }
00043   void add(int value) { min = std::min(value, min); }
00044   int value() const { return min; }
00045 };
00046 
00047 struct KeepMax
00048 {
00049   int max;
00050   explicit KeepMax(int initial = -10000) : max(initial)
00051   {
00052   }
00053   void add(int value) { max = std::max(value, max); }
00054   int value() const { return max; }
00055 };
00056 
00057 struct Histogram8
00058 {
00059   CArray<stat::Histogram*,8> histograms;
00060   const stat::Histogram& operator[](size_t i) const 
00061   {
00062     return *histograms[i];
00063   }
00064   Histogram8(int width, int length, int start=0)
00065   {
00066     for (int i=0; i<8; ++i)
00067       histograms[i] = new stat::Histogram(width, length, start);
00068   }
00069   void add(Progress16 progress, int data, double weight = 1.0)
00070   {
00071     const int min = histograms[0]->start();
00072     const int max = histograms[0]->start() + histograms[0]->width()*histograms[0]->length();
00073     if (data < min || data >= max) {
00074       return;
00075     }
00076     histograms[progress.value()/2]->add(data, weight);
00077   }
00078 };
00079 
00080 stat::Average moves, probs, order, top_score, selected_score;
00081 const int width = 4, length = 20;
00082 Histogram8 moves_histogram(width, length), selected_histogram(width, length);
00083 Histogram8 all_moves_histogram(width, length);
00084 const int sc_width = 100, sc_length = 16, sc_start = -400;
00085 stat::Histogram takeback_histogram(sc_width, sc_length, sc_start), selected_takeback(sc_width, sc_length, sc_start);
00086 stat::Histogram takeback_order(1, 10), takeback_order_all(1, 10), takeback_order_selected(1, 10);
00087 stat::Histogram seeplus_histogram(sc_width, sc_length, sc_start), selected_seeplus(sc_width, sc_length, sc_start);
00088 stat::Histogram seeplus_order(1, 10), seeplus_order_all(1, 10), seeplus_order_selected(1, 10);
00089 stat::Histogram king_escape_histogram(sc_width, sc_length, sc_start), selected_king_escape(sc_width, sc_length, sc_start);
00090 stat::Histogram kingescape_order(1, 10), kingescape_order_all(1, 10), kingescape_order_selected(1, 10);
00091 Histogram8 score_histogram(sc_width, sc_length+4, sc_start), selected_score_histogram(sc_width, sc_length+4, sc_start);
00092 Histogram8 all_score_histogram(sc_width, sc_length+4, sc_start);
00093 Histogram8 rscore_histogram(sc_width, sc_length), rselected_score_histogram(sc_width, sc_length);
00094 Histogram8 rall_score_histogram(sc_width, sc_length);
00095 KeepMin min_selected, min_top;
00096 KeepMax max_notakeback, max_nocapture;
00097 const int sc_length_2d = sc_length+2;
00098 const int sc_start_2d = -100;
00099 
00100 namespace osl
00101 {
00102   void showLogProb(const stat::Histogram& numerator, const stat::Histogram& denominator)
00103   {
00104     assert(numerator.width() == denominator.width());
00105     assert(numerator.length() == denominator.length());
00106     assert(numerator.start() == denominator.start());
00107     stat::Histogram logprob(numerator.width(), numerator.length(), numerator.start());
00108     for (size_t i=0; i<numerator.length(); ++i) {
00109       const double n = numerator.frequency(i);
00110       const double d = denominator.frequency(i);
00111       const double prob = n / d;
00112       logprob.frequency(i) = d >= 15 ? static_cast<int>(-100.0*log(prob)/log(2.0)) : 0;
00113     }  
00114     logprob.show(std::cout);
00115   }
00116   void showLogProb(const stat::Histogram& numerator, const stat::Histogram& denom1, const stat::Histogram& denom2)
00117   {
00118     assert(numerator.width() == denom1.width());
00119     assert(numerator.length() == denom1.length());
00120     assert(numerator.start() == denom1.start());
00121     assert(denom1.width() == denom2.width() && denom1.length() == denom2.length() && denom1.start() == denom2.start());
00122     stat::Histogram l1(numerator.width(), numerator.length(), numerator.start()), 
00123       l2(numerator.width(), numerator.length(), numerator.start());
00124     for (size_t i=0; i<numerator.length(); ++i) {
00125       const double n = numerator.frequency(i);
00126       const double d1 = denom1.frequency(i);
00127       const double d2 = denom2.frequency(i);
00128       const double p1 = n / d1;
00129       const double p2 = n / d2;
00130       l1.frequency(i) = d1 > 20 ? static_cast<int>(-100.0*log(p1)/log(2.0)) : 0;
00131       l2.frequency(i) = d2 > 20 ? static_cast<int>(-100.0*log(p2)/log(2.0)) : 0;
00132     }  
00133     int value=l1.start();
00134     for (size_t i=0; i<l1.length(); ++i, value+=l1.width()) {
00135       std::cout << std::setw(5) << value << " - " 
00136                 << std::setw(5) << value+(int)l1.width();
00137       std::cout << " " << std::setw(8) << l1.frequency(i)
00138                 << " " << std::setw(8) << l2.frequency(i) << "\n";
00139     }
00140   }
00141   void showLogProb(const Histogram8& numerator, const Histogram8& denom1, const Histogram8& denom2)
00142   {
00143     assert(numerator[0].width()  == denom1[0].width());
00144     assert(numerator[0].length() == denom1[0].length());
00145     assert(numerator[0].start()  == denom1[0].start());
00146     assert(denom1[0].width() == denom2[0].width() && denom1[0].length() == denom2[0].length() && denom1[0].start() == denom2[0].start());
00147     // for human
00148     int value=numerator[0].start();
00149     for (size_t i=0; i<numerator[0].length(); ++i, value+=numerator[0].width()) {
00150       std::cout << std::setw(4) << value << " - " 
00151                 << std::setw(4) << value+(int)numerator[0].width();
00152 
00153       for (int p=0; p<8; ++p) {
00154         const double n = numerator[p].frequency(i);
00155         const double d1 = denom1[p].frequency(i);
00156         const double d2 = denom2[p].frequency(i);
00157         const double p1 = n / d1;
00158         const double p2 = n / d2;
00159         const double f1 = n > 20 ? static_cast<int>(-100.0*log(p1)/log(2.0)) : 0;
00160         const double f2 = n > 20 ? static_cast<int>(-100.0*log(p2)/log(2.0)) : 0;
00161         std::cout << " " << std::setw(5) << f1
00162                   << " " << std::setw(4) << f2;
00163       }
00164       std::cout << "\n";
00165     }
00166     // depth
00167     std::cout << "static const osl::CArray2d<int, 8, " 
00168               << numerator[0].length() << "> xxx_to_depth = {{\n";
00169     for (int p=0; p<8; ++p) {
00170       std::cout << " { ";
00171       for (size_t i=0; i<numerator[0].length(); ++i, value+=numerator[0].width()) {
00172         const double n = numerator[p].frequency(i);
00173         const double d = denom1[p].frequency(i);
00174         const double p = n / d;
00175         const double f = n > 20 ? static_cast<int>(-100.0*log(p)/log(2.0)) : 0;
00176         std::cout << std::setw(4) << f << ",";
00177         if (i % 5 == 4)
00178           std::cout << " ";
00179       }
00180       std::cout << "},\n";
00181     }
00182     std::cout << "}};\n";
00183     // width
00184     std::cout << "static const osl::CArray2d<int, 8, " 
00185               << numerator[0].length() << "> xxx_to_width = {{\n";
00186     for (int p=0; p<8; ++p) {
00187       std::cout << " { ";
00188       for (size_t i=0; i<numerator[0].length(); ++i, value+=numerator[0].width()) {
00189         const double n = numerator[p].frequency(i);
00190         const double d = denom2[p].frequency(i);
00191         const double p = n / d;
00192         const double f = n > 20 ? static_cast<int>(-100.0*log(p)/log(2.0)) : 0;
00193         std::cout << std::setw(4) << f << ",";
00194         if (i % 5 == 4)
00195           std::cout << " ";
00196       }
00197       std::cout << "},\n";
00198     }
00199     std::cout << "}};\n";
00200   }
00201   
00202   enum Property { 
00203     All, 
00205     TakeBack, 
00207     TakeBack2, 
00209     NoTakeBack, 
00211     SeePlus, 
00212     SeePlus2, 
00214     SeePlusX, 
00216     NoSeePlus 
00217   };
00218   size_t find(Property property, const NumEffectState& state, const RatingEnv& e,
00219               const RatedMoveVector& moves, Move selected)
00220   {
00221     if (moves.empty())
00222       return 1;
00223     size_t i = 0;
00224     if (property == TakeBack || property == TakeBack2) {
00225       if (! e.history.lastMove().isNormal())
00226         return moves.size();
00227       for (; i<moves.size(); ++i)
00228         if (moves[i].move().to() == e.history.lastMove().to())
00229           break;
00230     } 
00231     if (property == TakeBack2) {
00232       ++i;
00233       for (; i<moves.size(); ++i)
00234         if (moves[i].move().to() == e.history.lastMove().to())
00235           break;
00236     }
00237     if (property == NoTakeBack) {
00238       if (e.history.lastMove().isNormal()) {
00239         for (; i<moves.size(); ++i)
00240           if (moves[i].move().to() != e.history.lastMove().to())
00241             break;
00242       }
00243     }
00244     if (property == SeePlus || property == SeePlus2) {
00245       for (; i<moves.size(); ++i) {
00246         if (e.history.lastMove().isNormal() && moves[i].move().to() == e.history.lastMove().to())
00247           continue;
00248         if (PieceEval::computeDiffAfterMoveForRP(state, moves[i].move()) > 0)
00249           break;
00250       }
00251     }
00252     if (property == SeePlus2) {
00253       ++i;
00254       for (; i<moves.size(); ++i) {
00255         if (PieceEval::computeDiffAfterMoveForRP(state, moves[i].move()) > 0)
00256           break;
00257       }
00258     }
00259     if (property == SeePlusX) {
00260       int num_seeplus=0;
00261       for (; i<moves.size(); ++i) {
00262         if (e.history.lastMove().isNormal() && moves[i].move().to() == e.history.lastMove().to())
00263           continue;
00264         if (PieceEval::computeDiffAfterMoveForRP(state, moves[i].move()) > 0) {
00265           if (++num_seeplus <= 1) // use 2 for 3rd see+
00266             continue;
00267         }
00268         break;
00269       }
00270     }
00271     if (property == NoSeePlus) {
00272       for (; i<moves.size(); ++i) {
00273         if (e.history.lastMove().isNormal() && moves[i].move().to() == e.history.lastMove().to())
00274           continue;
00275         if (PieceEval::computeDiffAfterMoveForRP(state, moves[i].move()) > 0)
00276           continue;
00277         break;
00278       }
00279     }
00280     return i;
00281   }
00283   struct TopProb
00284   {
00285     stat::Histogram selected;
00286     stat::Histogram generated, generated_all;
00287     Property property;
00288     TopProb(Property p) 
00289       : selected(sc_width,sc_length+1,200), generated(sc_width,sc_length+1,200), 
00290         generated_all(sc_width,sc_length+1,200), 
00291         property(p)
00292     {
00293     }
00294     void add(const NumEffectState& state, const RatingEnv& e,
00295              const RatedMoveVector& moves, Move selected) 
00296     {
00297       const size_t i = find(property, state, e, moves, selected);
00298       if (i >= moves.size())
00299         return;
00300       generated_all.add(moves[i].rating());
00301       const RatedMove *found = moves.find(selected);
00302       if (found && (found - &*moves.begin()) <= (int)i) {
00303         if (moves[i].move() == selected)
00304           this->selected.add(moves[i].rating());
00305         generated.add(moves[i].rating());
00306       }
00307     }
00308     void show()
00309     {
00310       showLogProb(selected, generated, generated_all);
00311     }
00312   };
00314   struct RatingDiffRange
00315   {
00316     stat::Histogram selected;
00317     stat::Histogram generated;
00318     stat::Histogram all_generated;
00319     CArray<stat::Variance, sc_length_2d*sc_length_2d> variance;
00320     size_t first, last;
00321     
00322     RatingDiffRange(size_t f, size_t l) 
00323       : selected(1,sc_length_2d*sc_length_2d), generated(1,sc_length_2d*sc_length_2d), all_generated(1,sc_length_2d*sc_length_2d),
00324         first(f), last(l)
00325     {
00326     }
00327 
00328     static int index(int score, int diff) 
00329     {
00330       const int score_index = std::max(0, std::min((score - sc_start_2d) / sc_width, sc_length_2d-1));
00331       const int diff_index = std::min(diff / sc_width, sc_length_2d-1);
00332       assert(diff_index >= 0);
00333       return score_index*sc_length_2d + diff_index;
00334     }
00335     void add(const NumEffectState& state, const RatedMoveVector& moves, Move selected)
00336     {
00337       if (moves.empty() || state.inCheck())
00338         return;
00339       const int highest = moves[0].rating();
00340       const RatedMove *found = moves.find(selected);
00341       if (! found) 
00342         return;                 // records may contain illegal move
00343       const size_t selected_order = found - &*moves.begin();
00344       if (first <= selected_order && selected_order < last) {
00345         const int selected_index = index(found->rating(), highest - found->rating());
00346         this->selected.add(selected_index);
00347       }
00348       for (size_t i=first; i<std::min(last,moves.size()); ++i) {
00349         const int index = this->index(moves[i].rating(), highest - moves[i].rating());
00350         all_generated.add(index);
00351         if (i <= selected_order)
00352           generated.add(index);
00353         variance[index].add(i);
00354       }
00355     }
00356   
00357     void show(std::ostream& os)
00358     {
00359       os << "depth\n";
00360       for (int i=0; i<sc_length_2d; ++i) {
00361         for (int j=0; j<sc_length_2d; ++j) {
00362           double s = selected.frequency(i*sc_length_2d+j);
00363           double g = generated.frequency(i*sc_length_2d+j);
00364           // os << std::setw(5) << (g > 20 ? s/g : 0.0);
00365           os << std::setw(5) << (std::min(s,g) > 20 ? static_cast<int>(-100.0*log(s/g)/log(2.0)) : 0);
00366         }
00367         os << "\n";
00368       }
00369       os << "width\n";
00370       for (int i=0; i<sc_length_2d; ++i) {
00371         for (int j=0; j<sc_length_2d; ++j) {
00372           double s = selected.frequency(i*sc_length_2d+j);
00373           double a = all_generated.frequency(i*sc_length_2d+j);
00374           // os << std::setw(5) << (a > 20 ? s/a : 0.0);
00375           os << std::setw(5) << (std::min(s,a) > 20 ? static_cast<int>(-100.0*log(s/a)/log(2.0)) : 0);
00376         }
00377         os << "\n";
00378       }
00379       os << "order\n";
00380       for (int i=0; i<sc_length_2d; ++i) {
00381         for (int j=0; j<sc_length_2d; ++j) {
00382           // os << std::setw(5) << std::setprecision(3) << variance[i*sc_length_2d+j].getAverage();
00383           os << std::setw(5) << static_cast<int>(variance[i*sc_length_2d+j].getAverage());
00384         }
00385         os << "\n";
00386       }
00387     }
00388   };
00389   struct RatingDiff
00390   {
00391     RatingDiffRange r0, r1, r_all;
00392     RatingDiff() :
00393       r0(1,25), r1(25,800), r_all(1,800)
00394     {
00395     }
00396     void add(const NumEffectState& state, const RatedMoveVector& moves, Move selected)
00397     {
00398 #ifdef SHOW_SPLIT_RATING
00399       r0.add(state, moves, selected);
00400       r1.add(state, moves, selected);
00401 #endif
00402       r_all.add(state, moves, selected);
00403     }
00404     void show(std::ostream& os)
00405     {
00406 #if SHOW_SPLIT_RATING
00407       r0.show(os);
00408       r1.show(os);
00409 #endif
00410       r_all.show(os);
00411     }
00412   };
00413 }
00414 
00415 RatingDiff rating_diff;
00416 TopProb top_prob(All), takeback_topprob(TakeBack), takeback2_topprob(TakeBack2), 
00417   no_takeback_topprob(NoTakeBack), seeplus_topprob(SeePlus), seeplus2_topprob(SeePlus2), seeplusx_topprob(SeePlusX);
00418 CArray<stat::Variance, 8> top_rating_progress;
00419 
00420 void test_file(const FeatureSet&, const char *filename);
00421 void test_record(const FeatureSet& f, 
00422                  const SimpleState& initial,
00423                  const osl::stl::vector<osl::Move>& moves);
00424 
00425 int main(int argc, char **argv)
00426 {
00427   const char *program_name = argv[0];
00428   bool error_flag = false;
00429   extern char *optarg;
00430   extern int optind;
00431     
00432   char c;
00433   while ((c = getopt(argc, argv, "f:k:n:vh")) != EOF)
00434   {
00435     switch(c)
00436     {
00437     case 'f':   first_skip = atoi(optarg);
00438       break;
00439     case 'k':   kisen_filename = optarg;
00440       break;
00441     case 'n':   num_kisen = atoi(optarg);
00442       break;
00443     case 'v':   ++verbose;
00444       break;
00445     default:    error_flag = true;
00446     }
00447   }
00448   argc -= optind;
00449   argv += optind;
00450 
00451   if (error_flag || (!kisen_filename && argc < 1))
00452     usage(program_name);
00453 
00454   eval::ProgressEval::setUp();
00455   StandardFeatureSet f;
00456 
00457   if (kisen_filename) {
00458     KisenFile kisen_file(kisen_filename);
00459     KisenIpxFile ipx(kisen_file.ipxFileName());
00460     size_t skip = 0;
00461     for (size_t i=0; i<num_kisen; i++) {
00462       if (ipx.getRating(i, BLACK) < min_rating 
00463           || ipx.getRating(i, WHITE) < min_rating) {
00464         ++skip;
00465         continue;
00466       }
00467       if (i % 128 == 0)
00468         std::cerr << '.';
00469       test_record(f, kisen_file.getInitialState(), kisen_file.getMoves(i+kisen_start));
00470     }
00471   }
00472   
00473   for (int i=0; i<argc; ++i)
00474   {
00475     if (i % 128 == 0)
00476       std::cerr << '.';
00477     test_file(f, argv[i]);
00478   }
00479 
00480   std::cout << "\n"
00481             << "average moves/position " << moves.getAverage() << "\n"
00482             << "average order " << order.getAverage() << "\n"
00483             << "average selected score " << selected_score.getAverage() << "\n"
00484             << "min selected score " << min_selected.value() << "\n"
00485             << "average top score " << top_score.getAverage() << "\n"
00486             << "min top score " << min_top.value() << "\n"
00487             << "max top score (notakeback) " << max_notakeback.value() << "\n"
00488             << "max top score (nocapture) " << max_nocapture.value() << "\n";
00489   std::cout << "order to logprob (depth, width)\n";
00490   showLogProb(selected_histogram, moves_histogram, all_moves_histogram);
00491   std::cout << "score to logprob (all)\n";
00492   showLogProb(selected_score_histogram, score_histogram, all_score_histogram);
00493   std::cout << "relative score to logprob (all)\n";
00494   showLogProb(rselected_score_histogram, rscore_histogram, rall_score_histogram);
00495   std::cout << "score to logprob (takeback)\n";
00496   showLogProb(selected_takeback, takeback_histogram);
00497   std::cout << "score to logprob (see+)\n";
00498   showLogProb(selected_seeplus, seeplus_histogram);
00499   std::cout << "score to logprob (king_escape)\n";
00500   showLogProb(selected_king_escape, king_escape_histogram);
00501   if (verbose) {
00502     std::cout << "order to logprob (takeback)\n";
00503     showLogProb(takeback_order_selected, takeback_order, takeback_order_all);
00504     std::cout << "order to logprob (seeplus)\n";
00505     showLogProb(seeplus_order_selected, seeplus_order, seeplus_order_all);
00506     std::cout << "order to logprob (kingescape)\n";
00507     showLogProb(kingescape_order_selected, kingescape_order, kingescape_order_all);
00508     rating_diff.show(std::cout);
00509     std::cout << "top move\n";
00510     top_prob.show();
00511     std::cout << "top move (takeback)\n";
00512     takeback_topprob.show();
00513     std::cout << "top move (2nd takeback)\n";
00514     takeback2_topprob.show();
00515     if (verbose > 1) {
00516       std::cout << "top move (no takeback)\n";
00517       no_takeback_topprob.show();
00518     }
00519     std::cout << "top move (see+)\n";
00520     seeplus_topprob.show();
00521     std::cout << "top move (2nd see+)\n";
00522     seeplus2_topprob.show();
00523     std::cout << "top move (2nd see+ or no see+)\n";
00524     seeplusx_topprob.show();
00525   }
00526   std::cout << "top rating for each progress8\n";
00527   for (size_t i=0; i<top_rating_progress.size(); ++i)
00528     std::cout << "progress8 " << i << "\tave. " << std::setprecision(3) << top_rating_progress[i].getAverage()
00529               << "\tsigma " << sqrt(top_rating_progress[i].variance()) << "\n";
00530 }
00531 
00532 /* ------------------------------------------------------------------------- */
00533 
00534 size_t num_positions = 0;
00535 void test_position(const FeatureSet& f, Move next_move, Move last_move, const RatingEnv& env,
00536                    const NumEffectState& state, const eval::ProgressEval& eval)
00537 {
00538   const bool in_check = state.inCheck();
00539   RatedMoveVector moves;
00540   f.generateRating(state, env, 2000, moves);
00541 
00542   if (moves.empty()) 
00543     return;
00544   const RatedMove *p = moves.find(next_move);
00545   if (! p) 
00546     return;
00547 
00548   rating_diff.add(state, moves, next_move);
00549   top_prob.add(state, env, moves, next_move);
00550   takeback_topprob.add(state, env, moves, next_move);
00551   takeback2_topprob.add(state, env, moves, next_move);
00552   no_takeback_topprob.add(state, env, moves, next_move);
00553   seeplus_topprob.add(state, env, moves, next_move);
00554   seeplus2_topprob.add(state, env, moves, next_move);
00555   seeplusx_topprob.add(state, env, moves, next_move);
00556   
00557   bool notakeback_added = in_check, nocapture_added = in_check;
00558   const int highest = moves[0].rating();
00559   min_top.add(highest);
00560   top_score.add(highest);
00561   if (! in_check) {
00562     size_t index = find(NoSeePlus, state, env, moves, next_move);
00563     if (index < moves.size())
00564       top_rating_progress[eval.progress16().value()/2].add(moves[index].rating());
00565   }
00566   if (! notakeback_added
00567       && moves[0].move().to() != last_move.to()) {
00568     nocapture_added = true;
00569     max_notakeback.add(highest);
00570   }
00571   if (! nocapture_added
00572       && moves[0].move().capturePtype() == PTYPE_EMPTY
00573       && ! moves[0].move().isPromotion()) {
00574     nocapture_added = true;
00575     max_nocapture.add(highest);
00576   }
00577 
00578   const int count = moves.size();
00579   const int order = p ? p - &*moves.begin() +1 : count;
00580   ::order.add(order);
00581   const double selected_weight = 1.0-1.0/(moves.size()-order+1);
00582   const double other_weight    = 1.0; // -1.0/moves.size();
00583 
00584   if (in_check) {
00585     for (int i=0; i<count; ++i) {
00586       if (i < order) {
00587         king_escape_histogram.add(moves[i].rating(), other_weight);
00588         kingescape_order.add(i);
00589         if (moves[i].move() == next_move) {
00590           selected_king_escape.add(moves[i].rating(), selected_weight);
00591           kingescape_order_selected.add(i);
00592         }
00593       }
00594       kingescape_order_all.add(i);
00595     }
00596     return;
00597   }
00598   selected_histogram.add(env.progress, order, selected_weight);
00599   selected_score.add(p->rating());
00600   min_selected.add(p->rating());
00601   if (p->rating() < -2000) {
00602     std::cerr << state << "selected " << *p << "\n" << moves;
00603   }
00604   for (int i=0; i<order; ++i)
00605     moves_histogram.add(env.progress, i, other_weight);
00606   for (size_t i=0; i<moves.size(); ++i)
00607     all_moves_histogram.add(env.progress, i, other_weight);
00608   ::moves.add(count);
00609   ++num_positions;
00610 
00611   int j=0;
00612   for (int i=0; i<count; ++i) {
00613     if (moves[i].move().to() != last_move.to())
00614       continue;
00615     if (i < order) {
00616       takeback_histogram.add(moves[i].rating(), other_weight);
00617       takeback_order.add(j);
00618       if (moves[i].move() == next_move) {
00619         selected_takeback.add(moves[i].rating(), selected_weight);
00620         takeback_order_selected.add(j);
00621       }
00622     }
00623     takeback_order_all.add(j);
00624     ++j;
00625   }
00626   j=0;
00627   for (int i=0; i<count; ++i) {
00628     if (moves[i].move().to() == last_move.to())
00629       continue;
00630     if (! (moves[i].move().capturePtype() != PTYPE_EMPTY
00631            || moves[i].move().isPromotion())
00632         || PieceEval::computeDiffAfterMoveForRP(state, moves[i].move()) <= 0)
00633       continue;
00634     if (i<order) {
00635       seeplus_histogram.add(moves[i].rating(), other_weight);
00636       seeplus_order.add(j);
00637       if (moves[i].move() == next_move) {
00638         selected_seeplus.add(moves[i].rating(), selected_weight);
00639         seeplus_order_selected.add(j);
00640       }
00641     }
00642     seeplus_order_all.add(j);
00643     ++j;
00644   }
00645 
00646   for (int i=0; i<order; ++i) {
00647     score_histogram.add(env.progress, moves[i].rating(), other_weight);
00648     if (moves[i].move() == next_move)
00649       selected_score_histogram.add(env.progress, moves[i].rating(), selected_weight);
00650   }
00651   for (size_t i=0; i<moves.size(); ++i) {
00652     all_score_histogram.add(env.progress, moves[i].rating(), other_weight);
00653     if (! notakeback_added && moves[i].move().to() != last_move.to()) {
00654       notakeback_added = true;
00655       max_notakeback.add(moves[i].rating());
00656     }
00657     if (! nocapture_added && moves[i].move().capturePtype() == PTYPE_EMPTY
00658         && ! moves[i].move().isPromotion()) {
00659       nocapture_added = true;
00660       max_nocapture.add(moves[i].rating());
00661     }
00662   }
00663   if (moves[0].move() != next_move) {
00664     const int top_score = moves[0].rating();
00665     for (int i=1; i<order; ++i) {
00666       rscore_histogram.add(env.progress, top_score - moves[i].rating(), other_weight);
00667       if (moves[i].move() == next_move)
00668         rselected_score_histogram.add(env.progress, top_score - moves[i].rating(), selected_weight);
00669     }
00670     for (size_t i=1; i<moves.size(); ++i) {
00671       rall_score_histogram.add(env.progress, top_score - moves[i].rating(), other_weight);
00672     }
00673   }
00674 }
00675 
00676 void test_record(const FeatureSet& f, 
00677                  const SimpleState& initial,
00678                  const osl::stl::vector<osl::Move>& moves)
00679 {
00680   NumEffectState state(initial);
00681 
00682   RatingEnv env;
00683   env.make(state);
00684   eval::ProgressEval eval(state);
00685   for (size_t i=0; i<moves.size(); ++i) {
00686     if (state.inCheck(alt(state.turn())))
00687       break;                    // illegal
00688 
00689     const Move move = moves[i];
00690     assert(state.isValidMove(move));
00691     if (i >= first_skip) {
00692       test_position(f, moves[i], (i>0 ? moves[i-1] : Move::PASS(alt(moves[i].player()))),
00693                     env, state, eval);
00694     }
00695     state.makeMove(move);
00696     eval.update(state, move);
00697     env.update(state, move);
00698   }
00699 }
00700 
00701 void test_file(const FeatureSet& f, const char *filename)
00702 {
00703   Record rec;
00704   try {
00705     rec = CsaFile(filename).getRecord();
00706   }
00707   catch (CsaIOError& e) {
00708     std::cerr << "skip " << filename <<"\n";
00709     std::cerr << e.what() << "\n";
00710     return;
00711   }
00712   catch (...) {
00713     throw;
00714   }
00715   test_record(f, rec.getInitialState(), rec.getMoves());
00716 }
00717 
00718 /* ------------------------------------------------------------------------- */
00719 // ;;; Local Variables:
00720 // ;;; mode:c++
00721 // ;;; c-basic-offset:2
00722 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines