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
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
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
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)
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;
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
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
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
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;
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;
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
00720
00721
00722