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