00001
00002
00003 #include "osl/rating/featureSet.h"
00004 #include "osl/config.h"
00005 #include "osl/rating/group.h"
00006 #include "osl/rating/group/captureGroup.h"
00007 #include "osl/rating/group/escape.h"
00008 #include "osl/rating/group/squareGroup.h"
00009 #include "osl/rating/group/patternGroup.h"
00010 #include "osl/rating/group/bigramGroup.h"
00011 #include "osl/rating/group/king8Group.h"
00012 #include "osl/rating/group/checkmateGroup.h"
00013 #include "osl/rating/group/pinGroup.h"
00014 #include "osl/move_generator/allMoves.h"
00015 #include "osl/move_generator/escape_.h"
00016 #include "osl/move_classifier/moveAdaptor.h"
00017 #include "osl/move_classifier/safeMove.h"
00018 #include "osl/stat/variance.h"
00019 #include "osl/oslConfig.h"
00020 #include <boost/format.hpp>
00021 #include <map>
00022 #include <iostream>
00023 #include <fstream>
00024 #include <sstream>
00025 #include <iomanip>
00026 #include <stdexcept>
00027 #include <cmath>
00028
00029
00030
00031
00032
00033
00034
00035
00036 const int MinRating = -4000;
00037
00038 struct osl::rating::FeatureSet::Statistics
00039 {
00041 int average_after, sigma_after;
00043 double average, variance, probability;
00044 Statistics() : average_after(0), sigma_after(0),
00045 average(0), variance(0), probability(0)
00046 {
00047 }
00048 };
00049
00050
00051 osl::rating::
00052 FeatureSet::FeatureSet()
00053 : capture_group(-1), checkmate_if_capture_group(-1), sendoff_group(-1)
00054 {
00055 }
00056
00057 osl::rating::
00058 FeatureSet::~FeatureSet()
00059 {
00060 #ifdef RATING_STAT
00061 showStatistics(std::cerr);
00062 #endif
00063 }
00064
00065 const osl::rating::range_t osl::rating::
00066 FeatureSet::makeRange(size_t group) const
00067 {
00068 int first = 0;
00069 for (size_t i=0; i<groups.size(); ++i) {
00070 if (i == group)
00071 return std::make_pair(first, first+groups[i].size());
00072 first += groups[i].size();
00073 }
00074 assert(0);
00075 abort();
00076 }
00077
00078 void osl::rating::
00079 FeatureSet::addFinished()
00080 {
00081 assert(normal_groups.size() == groups.size());
00082 weights.resize(features.size(), 1.0);
00083 weightslog10.resize(features.size(), 1);
00084 assert(weights.size() == features.size());
00085 ranges.resize(groups.size());
00086 for (size_t i=0; i<groups.size(); ++i)
00087 ranges[i] = makeRange(i);
00088 variance_match.resize(groups.size());
00089 variance_all.resize(groups.size());
00090 frequency.resize(groups.size());
00091 statistics.resize(groups.size());
00092 }
00093
00094 void osl::rating::
00095 FeatureSet::add(Feature *f)
00096 {
00097 add(new Group(f));
00098 }
00099
00100 void osl::rating::
00101 FeatureSet::addCommon(Group *g)
00102 {
00103 features.reserve(features.size()+g->size());
00104 for (size_t i=0; i<g->size(); ++i) {
00105 features.push_back(&(*g)[i]);
00106 }
00107 groups.push_back(g);
00108 effective_in_check.push_back(g->effectiveInCheck());
00109 }
00110
00111 void osl::rating::
00112 FeatureSet::add(Group *g)
00113 {
00114 normal_groups.push_back(true);
00115 addCommon(g);
00116 }
00117
00118 void osl::rating::
00119 FeatureSet::add(CaptureGroup *g)
00120 {
00121 capture_group = normal_groups.size();
00122 normal_groups.push_back(false);
00123 addCommon(g);
00124 }
00125
00126 void osl::rating::
00127 FeatureSet::add(SendOffGroup *g)
00128 {
00129 sendoff_group = normal_groups.size();
00130 normal_groups.push_back(false);
00131 addCommon(g);
00132 }
00133
00134 void osl::rating::
00135 FeatureSet::add(CheckmateIfCaptureGroup *g)
00136 {
00137 checkmate_if_capture_group = normal_groups.size();
00138 normal_groups.push_back(false);
00139 addCommon(g);
00140 }
00141
00142 bool osl::rating::
00143 FeatureSet::tryLoad(const std::string& input_directory)
00144 {
00145 bool result = true;
00146 for (size_t i=0; i<groups.size(); ++i) {
00147 const bool success = groups[i].load(input_directory, ranges[i], weights);
00148 if (! success && result)
00149 std::cerr << "warning: rating load failed " << groups[i].group_name << " " << i
00150 << " in " << input_directory << "\n";
00151 result &= success;
00152 }
00153 for (size_t i=0; i<features.size(); ++i)
00154 weightslog10[i] = static_cast<int>(400*log10(weights[i]));
00155 #ifndef RATING_STAT
00156 std::string filename = input_directory + "/statistics.txt";
00157 std::ifstream is(filename.c_str());
00158 typedef std::map<std::string,Statistics> map_t;
00159 map_t table;
00160 std::string name;
00161 double a, s, p, dummy;
00162 while (is >> name >> a >> s >> dummy >> dummy >> p) {
00163 Statistics& stat = table[name];
00164 stat.average = a;
00165 stat.variance = s*s;
00166 stat.probability = p;
00167 }
00168 for (size_t i=0; i<groups.size(); ++i) {
00169 double a = 0.0, v = 0.0;
00170 for (size_t j=i+1; j<groups.size(); ++j) {
00171 map_t::iterator q = table.find(groups[j].group_name);
00172 if (q == table.end()) {
00173 result = false;
00174 break;
00175 }
00176 a += q->second.probability * q->second.average;
00177 v += q->second.probability * q->second.variance;
00178 }
00179 statistics[i] = table[groups[i].group_name];
00180 statistics[i].average_after = static_cast<int>(a);
00181 statistics[i].sigma_after = static_cast<int>(sqrt(v)*3);
00182 # ifdef VERBOSE_RATING
00183 std::cerr << groups[i].group_name
00184 << " " << statistics[i].average_after
00185 << " " << statistics[i].sigma_after << "\n";
00186 # endif
00187 }
00188 #endif
00189 return result;
00190 }
00191
00192 void osl::rating::
00193 FeatureSet::setWeight(size_t feature_id, const double& value)
00194 {
00195 weights[feature_id] = value;
00196 weightslog10[feature_id] = static_cast<int>(400*log10(value));
00197 }
00198
00199 void osl::rating::
00200 FeatureSet::generateRating(const NumEffectState& state, const RatingEnv& env,
00201 int limit, RatedMoveVector& out, bool in_pv_or_all) const
00202 {
00203 #if (defined RATING_STAT) || (defined RATING_STAT2)
00204 in_pv_or_all = true;
00205 #endif
00206 MoveVector moves;
00207 const bool in_check = state.inCheck();
00208
00209 if (in_check)
00210 GenerateEscapeKing::generate(state, moves);
00211 else
00212 GenerateAllMoves::generate(state.turn(), state, moves);
00213
00214 for (size_t i=0; i<moves.size(); ++i) {
00215 if (moves[i].ptype() == KING) {
00216 if (state.hasEffectAt(alt(state.turn()), moves[i].to()))
00217 continue;
00218 } else {
00219 if (! in_check && env.my_pin.any() && ! moves[i].isDrop()
00220 && move_classifier::PlayerMoveAdaptor<move_classifier::KingOpenMove>::isMember(state, moves[i]))
00221 continue;
00222 }
00223
00224 if (in_pv_or_all)
00225 out.push_back(makeRate(state, in_check, env, moves[i]));
00226 else {
00227 RatedMove r = makeRateWithCut(state, in_check, env, limit, moves[i]);
00228 if (r.rating() > MinRating)
00229 out.push_back(r);
00230 }
00231 }
00232 out.sort();
00233 }
00234
00235
00236 static const osl::CArray2d<int, 8, 20> order_to_depth = {{
00237 186, 213, 243, 247, 249, 255, 252, 258, 263, 269, 267, 279, 295, 295, 295, 295, 295, 295, 295, 295,
00238 191, 245, 283, 300, 313, 315, 319, 323, 326, 339, 321, 347, 334, 346, 328, 368, 328, 328, 328, 328,
00239 183, 250, 304, 328, 346, 352, 373, 366, 365, 379, 396, 379, 392, 416, 420, 374, 423, 378, 395, 399,
00240 184, 253, 312, 346, 358, 378, 389, 407, 409, 403, 404, 421, 432, 395, 421, 444, 444, 461, 411, 408,
00241 190, 256, 319, 350, 373, 397, 397, 403, 420, 431, 415, 450, 424, 416, 436, 447, 456, 439, 429, 428,
00242 197, 262, 324, 357, 374, 390, 407, 423, 415, 425, 436, 444, 458, 455, 439, 474, 451, 466, 464, 457,
00243 202, 268, 332, 360, 381, 386, 416, 416, 418, 433, 447, 446, 452, 462, 479, 468, 467, 486, 483, 459,
00244 205, 270, 330, 361, 383, 394, 410, 418, 427, 438, 438, 452, 446, 445, 447, 463, 475, 472, 483, 485,
00245 }};
00246 static const osl::CArray2d<int, 8, 20> order_to_width = {{
00247 262, 445, 584, 685, 788, 890, 982,1067,1120,1148, 1137,1156,1182,1231,1259, 1343,1352,1359,1359,1359,
00248 265, 456, 577, 665, 745, 809, 874, 938, 997,1061, 1088,1154,1179,1231,1259, 1343,1352,1359,1359,1359,
00249 260, 467, 596, 680, 751, 807, 872, 908, 951,1003, 1054,1072,1117,1168,1198, 1188,1267,1259,1311,1344,
00250 261, 467, 599, 688, 747, 810, 861, 914, 948, 975, 1008,1055,1092,1084,1142, 1189,1214,1254,1231,1258,
00251 264, 463, 595, 679, 746, 808, 844, 885, 933, 973, 987,1049,1048,1068,1115, 1151,1184,1191,1209,1233,
00252 268, 459, 588, 673, 732, 788, 840, 887, 910, 950, 989,1022,1059,1078,1088, 1144,1144,1180,1201,1216,
00253 271, 459, 587, 664, 727, 771, 835, 866, 899, 942, 984,1006,1037,1069,1105, 1114,1134,1173,1188,1186,
00254 272, 458, 581, 661, 725, 773, 824, 863, 902, 940, 966,1005,1023,1047,1074, 1113,1145,1163,1193,1214,
00255 }};
00256
00257 const int sc_width = 100, sc_length = 18, sc_start = -400;
00258 static const osl::CArray2d<int, 8, sc_length> score_to_depth = {{
00259 263, 271, 274, 270, 278, 253, 235, 201, 171, 151, 111, 95, 83, 76, 78, 65, 71, 61,
00260 330, 334, 328, 316, 312, 304, 284, 256, 218, 188, 159, 136, 113, 103, 92, 87, 82, 71,
00261 377, 374, 376, 368, 356, 337, 311, 278, 246, 203, 175, 146, 131, 118, 107, 96, 81, 65,
00262 415, 424, 406, 396, 376, 345, 315, 276, 243, 211, 179, 155, 138, 121, 110, 91, 80, 62,
00263 423, 422, 433, 423, 405, 381, 341, 313, 276, 243, 210, 182, 158, 142, 123, 104, 85, 73,
00264 442, 451, 448, 437, 417, 395, 364, 333, 297, 267, 234, 202, 178, 158, 133, 107, 91, 76,
00265 446, 447, 455, 439, 427, 402, 373, 339, 307, 274, 242, 212, 188, 162, 133, 111, 92, 75,
00266 467, 468, 469, 453, 433, 412, 389, 365, 334, 301, 268, 236, 205, 177, 153, 131, 116, 101,
00267 }};
00268 static const osl::CArray2d<int, 8, sc_length> score_to_width = {{
00269 978, 880, 786, 676, 586, 475, 383, 302, 239, 208, 167, 153, 134, 127, 126, 100, 100, 82,
00270 1020, 935, 836, 730, 634, 549, 472, 412, 351, 312, 269, 232, 190, 167, 143, 127, 112, 95,
00271 1095, 998, 910, 810, 715, 623, 543, 471, 407, 338, 291, 246, 216, 189, 160, 140, 115, 90,
00272 1106,1031, 929, 829, 730, 635, 551, 469, 402, 341, 290, 249, 217, 186, 159, 127, 108, 85,
00273 1185,1092, 1011, 913, 811, 717, 617, 538, 459, 391, 331, 285, 242, 210, 176, 143, 114, 96,
00274 1224,1150, 1058, 957, 853, 755, 658, 573, 493, 424, 363, 308, 262, 223, 181, 142, 116, 96,
00275 1224,1134, 1057, 953, 857, 759, 666, 579, 501, 432, 373, 315, 267, 220, 178, 141, 115, 93,
00276 1296,1201, 1115,1009, 904, 807, 717, 638, 563, 492, 425, 363, 305, 254, 210, 172, 145, 123,
00277 }};
00278
00279 const int rsc_length = 15;
00280 static const osl::CArray2d<int, 8, rsc_length> relative_score_to_depth = {{
00281 193, 220, 235, 249, 256, 263, 268, 274, 279, 284, 283, 279, 292, 267, 272,
00282 220, 243, 263, 273, 287, 300, 306, 308, 317, 325, 328, 339, 319, 336, 323,
00283 215, 242, 267, 287, 302, 314, 329, 340, 347, 360, 367, 364, 349, 387, 374,
00284 209, 243, 267, 293, 317, 332, 347, 360, 372, 383, 387, 387, 395, 398, 405,
00285 216, 244, 276, 303, 322, 344, 360, 374, 378, 397, 405, 414, 408, 400, 424,
00286 220, 251, 278, 307, 331, 355, 365, 381, 398, 406, 418, 423, 414, 433, 403,
00287 226, 254, 284, 311, 336, 354, 378, 390, 408, 418, 420, 448, 414, 446, 408,
00288 219, 250, 283, 310, 333, 356, 377, 391, 403, 417, 426, 426, 440, 445, 452,
00289 }};
00290 static const osl::CArray2d<int, 8, rsc_length> relative_score_to_width = {{
00291 214, 285, 357, 442, 520, 596, 669, 742, 816, 881, 928, 972,1045,1079,1143,
00292 237, 302, 374, 442, 519, 595, 662, 731, 799, 870, 925, 994,1031,1112,1159,
00293 230, 294, 367, 442, 517, 595, 675, 746, 815, 884, 951,1012,1060,1149,1185,
00294 224, 292, 361, 441, 524, 602, 682, 758, 833, 904, 964,1028,1105,1164,1223,
00295 231, 295, 369, 449, 525, 611, 692, 771, 839, 922, 985,1041,1094,1150,1239,
00296 235, 301, 370, 450, 532, 616, 690, 769, 851, 920, 991,1054,1100,1194,1217,
00297 240, 300, 373, 448, 527, 607, 693, 768, 845, 919, 981,1066,1094,1191,1218,
00298 233, 294, 364, 435, 511, 591, 674, 753, 832, 917, 993,1065,1157,1224,1300,
00299 }};
00300
00301 inline int make_prob(int score, int order, int limit, int highest, int progress8, bool in_pv_or_all)
00302 {
00303 const int order_index = std::min((int)order/4, 19);
00304 int result = limit+1;
00305 if (order_to_width[progress8][order_index] <= limit) {
00306 result = (order == 0) ? 100 : order_to_depth[progress8][order_index];
00307 }
00308 score = std::max(sc_start, score);
00309 highest = std::max(sc_start, highest);
00310 const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
00311 if (limit > 600 && score_to_width[progress8][score_index] <= limit) {
00312 result = std::min(result, score_to_depth[progress8][score_index]);
00313 }
00314 if (limit > 700 && order > 0 && in_pv_or_all) {
00315 const int rscore_index = std::min((highest - score)/100, rsc_length-1);
00316 assert(rscore_index >= 0);
00317 if (relative_score_to_width[progress8][rscore_index] <= limit)
00318 result = std::min(result, relative_score_to_depth[progress8][rscore_index]);
00319 }
00320 return result;
00321 }
00322
00323 #ifdef RATING_STAT2
00324 namespace osl
00325 {
00326 namespace
00327 {
00328 CArray2d<CArray<stat::Average,8>,14,40> data;
00329 CArray2d<CArray<double,8>,14,80> selected_all;
00330 void add_stat(int limit, int rating, bool added, int progress8)
00331 {
00332 limit = std::min(limit, 999);
00333 limit -= 300;
00334 limit = std::max(limit, 0);
00335 rating = std::max(-999,rating);
00336 rating = std::min(999,rating);
00337 data[limit/50][(rating+1000)/50][progress8].add(added);
00338 if (added)
00339 selected_all[limit/50][(rating+1000)/25][progress8] += 1.0;
00340 }
00341 struct Reporter
00342 {
00343 ~Reporter()
00344 {
00345 std::cerr << "limit " << 0*50+300 << " - " << (data.size1()-1)*50+300 << "\n";
00346 for (int p=0; p<8; ++p)
00347 {
00348 std::cerr << "progress8 " << p << "\n ";
00349 for (size_t j=0; j<data.size1(); ++j)
00350 {
00351 size_t i=0;
00352 for (; i<data.size2(); ++i)
00353 if (data[j][i][p].getAverage() > 0.05)
00354 break;
00355 std::cerr << (boost::format("%+4d, ") % static_cast<int>(i)*50-1000);
00356 }
00357 std::cerr << "\n";
00358 }
00359 std::cerr << "limit " << 0*50+300 << " - " << (selected_all.size1()-1)*50+300 << "\n";
00360 CArray<double, 3> prob = {{ 0.01, 0.03, 0.05 }};
00361 for (size_t pp=0; pp<prob.size(); ++pp) {
00362 std::cerr << "prob " << prob[pp] << "\n";
00363 for (int p=0; p<8; ++p)
00364 {
00365 std::cerr << "progress8 " << p << "\n ";
00366 for (size_t j=0; j<selected_all.size1(); ++j)
00367 {
00368 double sum = 0;
00369 for (size_t i=0; i<selected_all.size2(); ++i)
00370 sum += selected_all[j][i][p];
00371 size_t i=0
00372 for (double so_far = 0; i<selected_all.size2(); ++i) {
00373 so_far += selected_all[j][i][p];
00374 if (so_far > prob[pp]*sum)
00375 break;
00376 }
00377 std::cerr << (boost::format("%+4d, ") % static_cast<int>(i)*25-1000);
00378 }
00379 std::cerr << "\n";
00380 }
00381 }
00382 }
00383 } _reporter;
00384 }
00385 }
00386 #endif
00387
00388 void osl::rating::
00389 FeatureSet::generateLogProb(const NumEffectState& state, const RatingEnv& env,
00390 int limit, MoveLogProbVector& out, bool in_pv_or_all) const
00391 {
00392 RatedMoveVector score;
00393 generateRating(state, env, limit, score, in_pv_or_all);
00394 if (score.empty())
00395 return;
00396
00397 const int highest = score[0].rating();
00398 const int progress8 = env.progress.value()/2;
00399 for (size_t i=0; i<score.size(); ++i) {
00400 const int log_prob = make_prob(score[i].rating(), i, limit, highest, progress8, in_pv_or_all);
00401 #ifdef RATING_STAT2
00402 add_stat(limit, score[i].rating(), log_prob <= limit, progress8);
00403 #endif
00404 out.push_back(MoveLogProb(score[i].move(), log_prob));
00405 }
00406 }
00407
00408 const int max_score = 999, min_score = 0;
00409 static const osl::CArray<int, 10> score_to_depth_takeback = {{
00410 223, 204, 208, 190, 159, 137, 124, 110, 100, 89
00411 }};
00412 static const osl::CArray<int, 10> score_to_depth_seeplus = {{
00413 356, 337, 296, 262, 230, 200, 171, 148, 132, 120,
00414 }};
00415 static const osl::CArray<int, 10> score_to_depth_kingescape = {{
00416 203, 201, 199, 188, 181, 169, 159, 147, 136, 122,
00417 }};
00418
00419 int osl::rating::
00420 FeatureSet::logProbTakeBack(const NumEffectState& state, const RatingEnv& env, Move move) const
00421 {
00422 const bool in_check = state.inCheck();
00423 const int score = makeRate(state, in_check, env, move).rating();
00424 if (score >= 1000) {
00425 const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
00426 return score_to_depth[env.progress.value()/2][score_index];
00427 }
00428 return score_to_depth_takeback[std::max(min_score, std::min(max_score, score))/100];
00429 }
00430 int osl::rating::
00431 FeatureSet::logProbSeePlus(const NumEffectState& state, const RatingEnv& env,
00432 Move move) const
00433 {
00434 const bool in_check = state.inCheck();
00435 const int score = makeRate(state, in_check, env, move).rating();
00436 if (score >= 1000) {
00437 const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
00438 return score_to_depth[env.progress.value()/2][score_index];
00439 }
00440 return score_to_depth_seeplus[std::max(min_score, std::min(max_score, score))/100];
00441 }
00442 int osl::rating::
00443 FeatureSet::logProbKingEscape(const NumEffectState& state, const RatingEnv& env,
00444 Move move) const
00445 {
00446 const bool in_check = state.inCheck();
00447 const int score = makeRate(state, in_check, env, move).rating();
00448 if (score >= 1000) {
00449 const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
00450 return score_to_depth[env.progress.value()/2][score_index];
00451 }
00452 const int prob = score_to_depth_kingescape[std::max(min_score, std::min(max_score, score))/100];
00453 assert(prob > 0);
00454 return prob;
00455 }
00456
00457 int osl::rating::
00458 FeatureSet::rating(const NumEffectState& state,
00459 const RatingEnv& env, Move move, size_t group_id) const
00460 {
00461 int found = groups[group_id].findMatch(state, move, env);
00462 if (found < 0) {
00463 #ifdef RATING_STAT
00464 const int progress8 = env.progress.value()/2;
00465 frequency[group_id][progress8].add(0);
00466 variance_all[group_id].add(0);
00467 #endif
00468 return 0;
00469 }
00470 found += ranges[group_id].first;
00471 #ifdef RATING_STAT
00472 const int progress8 = env.progress.value()/2;
00473 frequency[group_id][progress8].add(1);
00474 variance_match[group_id][progress8].add(weightslog10[found]);
00475 variance_all[group_id].add(weightslog10[found]);
00476 #endif
00477 return weightslog10[found];
00478 }
00479
00480 const osl::rating::RatedMove osl::rating::
00481 FeatureSet::makeRate(const NumEffectState& state, bool in_check,
00482 const RatingEnv& env, Move move) const
00483 {
00484 int sum = 0;
00485 for (size_t j=0; j<groups.size(); ++j) {
00486 if (! normal_groups[j])
00487 continue;
00488 if (in_check && ! effectiveInCheck(j))
00489 continue;
00490 sum += rating(state, env, move, j);
00491 }
00492 int capture = 0;
00493 if (capture_group >= 0)
00494 capture = rating(state, env, move, capture_group);
00495 int checkmate_if_capture = 0;
00496 if (checkmate_if_capture_group >= 0)
00497 checkmate_if_capture = rating(state, env, move, checkmate_if_capture_group);
00498 sum += checkmate_if_capture;
00499 int sendoff = 0;
00500 if (sendoff_group >= 0)
00501 sendoff = rating(state, env, move, sendoff_group);
00502 sum += sendoff;
00503
00504 if (checkmate_if_capture > 0)
00505 capture = std::max(0, capture);
00506 else if (sendoff > 0 && capture < 0)
00507 capture /= 2;
00508 const int optimistic = sum + std::max(0, capture);
00509 sum += capture;
00510
00511 return RatedMove(move, sum, optimistic);
00512 }
00513
00514
00515
00516 #if 1
00517
00518 static const osl::CArray2d<int,8,16> threshold = {{
00519 0, 0, 0, 0, 0, 0,
00520 100, 100, 50, 0, 0, -75,-100,-150,-200,-200,
00521
00522 0, 0, 0, 0, 0, 0,
00523 125, 125, 125, 25, 25, -50, -50,-100,-125,-225,
00524
00525 0, 0, 0, 0, 0, 0,
00526 100, 75, 100, 25, 0, -25, -50,-100,-125,-175,
00527
00528 0, 0, 0, 0, 0, 0,
00529 75, 50, 75, 0, -25, -25, -75,-100,-125,-200,
00530
00531 0, 0, 0, 0, 0, 0,
00532 125, 125, 150, 50, 50, 50, -25, 0, -50,-200,
00533
00534 0, 0, 0, 0, 0, 0,
00535 175, 200, 200, 75, 75, 75, 0, 0,-175,-300,
00536
00537 0, 0, 0, 0, 0, 0,
00538 175, 175, 200, 50, 75, 75, 25, 0,-100,-250,
00539
00540 0, 0, 0, 0, 0, 0,
00541 225, 200, 225, 75, 100, 75, 50, 0, 0,-250,
00542 }};
00543 #endif
00544 #if 0
00545 static const osl::CArray2d<int,8,16> threshold = {{
00546
00547 0, 0, 0, 0, 0, 0,
00548 100,100,100,0,0,-100,-100,-200,-200,-200,
00549
00550 0, 0, 0, 0, 0, 0,
00551 100,100,100,0,0,-100,-100,-100,-100,-200,
00552
00553 0, 0, 0, 0, 0, 0,
00554 100,100,100,0,0,0,-100,-100,-100,-200
00555
00556 0, 0, 0, 0, 0, 0,
00557 100,100,100,0,0,0,-100,-100,-100,-200
00558
00559 0, 0, 0, 0, 0, 0,
00560 200,200,200,100,100,100,0,0,0,-100
00561
00562 0, 0, 0, 0, 0, 0,
00563 300,300,300,100,100,100,100,0,-200,-300
00564
00565 0, 0, 0, 0, 0, 0,
00566 300,300,300,100,100,100,100,0,0,-200
00567
00568 0, 0, 0, 0, 0, 0,
00569 300,300,300,100,200,200,100,0,0,-200
00570 }};
00571 #endif
00572 const osl::rating::RatedMove osl::rating::
00573 FeatureSet::makeRateWithCut(const NumEffectState& state,
00574 bool in_check,
00575 const RatingEnv& env,
00576 int limit, Move move) const
00577 {
00578 if (limit >= 800)
00579 return makeRate(state, in_check, env, move);
00580
00581 limit /= 50;
00582 int sum = 0;
00583 int capture = 0;
00584 int checkmate_if_capture = 0;
00585 const int progress8 = env.progress.value()/2;
00586 for (size_t j=0; j<groups.size(); ++j) {
00587 if (in_check && ! effectiveInCheck(j))
00588 continue;
00589 const int r = rating(state, env, move, j);
00590 sum += r;
00591 if ((int)j == capture_group) {
00592 capture = r;
00593 }
00594 else if ((int)j == checkmate_if_capture_group) {
00595 checkmate_if_capture = r;
00596 if (checkmate_if_capture > 0 && capture < 0) {
00597 sum -= capture;
00598 capture = 0;
00599 }
00600 }
00601
00602 if (j % 8 == 7) {
00603 int sigma = statistics[j].sigma_after;
00604 if (sum + statistics[j].average_after + sigma < threshold[progress8][limit]) {
00605 return RatedMove(move, MinRating, MinRating);
00606 }
00607 }
00608 }
00609
00610 const int optimistic = sum + std::max(0, capture);
00611 return RatedMove(move, sum, optimistic);
00612 }
00613
00614 const std::string osl::rating::
00615 FeatureSet::annotate(const NumEffectState& state,
00616 const RatingEnv& env, Move move) const
00617 {
00618 const bool in_check = state.inCheck();
00619 std::vector<std::pair<int, std::string> > values;
00620 for (size_t j=0; j<groups.size(); ++j) {
00621 if (in_check && ! effectiveInCheck(j))
00622 continue;
00623 int found = groups[j].findMatch(state, move, env);
00624 if (found < 0)
00625 continue;
00626 found += ranges[j].first;
00627 values.push_back(std::make_pair(weightslog10[found], groups[j].group_name));
00628 }
00629 std::sort(values.begin(), values.end());
00630 std::reverse(values.begin(), values.end());
00631 std::ostringstream ss;
00632 for (size_t i=0; i<values.size(); ++i) {
00633 if (i)
00634 ss << " ";
00635 ss << values[i].second << " " << values[i].first;
00636 }
00637 return ss.str();
00638 }
00639
00640 #ifndef MINIMAL
00641 void osl::rating::
00642 FeatureSet::showGroup(std::ostream& os, size_t group_id) const
00643 {
00644 os << std::setprecision(3);
00645 group(group_id).show(os, 12, range(group_id), weights);
00646 }
00647
00648 void osl::rating::
00649 FeatureSet::save(const std::string& output_directory, size_t group_id) const
00650 {
00651 group(group_id).saveResult(output_directory, range(group_id), weights);
00652 }
00653
00654 void osl::rating::
00655 FeatureSet::showStatistics(std::ostream& os) const
00656 {
00657 os << std::setprecision(3);
00658 for (size_t i=0; i<groups.size(); ++i) {
00659 os << groups[i].group_name << "\t";
00660 for (int p=0; p<8; ++p) {
00661 os << " " << variance_match[i][p].average()
00662 << " " << sqrt(variance_match[i][p].variance())
00663 << " " << frequency[i][p].average() << " ";
00664 }
00665 os << "\t" << variance_all[i].average()
00666 << "\t" << sqrt(variance_all[i].variance())
00667 << "\n";
00668 }
00669 }
00670 #endif
00671
00672 std::string osl::rating::FeatureSet::defaultDirectory()
00673 {
00674 return OslConfig::home()+"/data/rating";
00675 }
00676
00677
00678
00679 osl::rating::
00680 StandardFeatureSet::StandardFeatureSet(bool allow_load_failure)
00681 {
00682 add(new CaptureGroup());
00683 add(new SquareYGroup());
00684 add(new RelativeKingXGroup(true));
00685 add(new SquareXGroup());
00686 add(new TakeBackGroup());
00687 add(new RelativeKingYGroup(true));
00688 add(new FromEffectGroup());
00689 add(new PatternGroup(U));
00690 add(new RelativeKingXGroup(false));
00691 add(new PatternGroup(D));
00692
00693 add(new PatternLongGroup(0));
00694 add(new CheckGroup());
00695 add(new BlockGroup());
00696 add(new PtypeAttackedGroup());
00697
00698 add(new PatternGroup(U,U));
00699 add(new ImmediateAddSupportGroup());
00700 add(new PatternGroup(DR));
00701 add(new RelativeKingYGroup(false));
00702 add(new DefenseKing8Group());
00703 add(new PatternGroup(L));
00704 add(new PatternGroup(UL));
00705
00706 add(new ToSupportedGroup());
00707
00708 add(new PatternGroup(UR));
00709 add(new PatternBlockGroup(ROOK));
00710 add(new AttackKing8Group());
00711 add(new PatternGroup(R));
00712 add(new PatternGroup(DL));
00713
00714 add(new PatternGroup(R,R));
00715 add(new PatternLongGroup(3));
00716 add(new PatternGroup(UUL));
00717 add(new PatternGroup(UUR));
00718 add(new PatternGroup(L,L));
00719
00720 add(new PatternLongGroup(2));
00721 add(new OpenGroup());
00722 add(new PatternBlockGroup(LANCE));
00723 add(new ChaseGroup());
00724 add(new PatternLongGroup(1));
00725 add(new PatternLongGroup2(1));
00726 add(new PatternBlockGroup(BISHOP));
00727 add(new PatternGroup(UR,R));
00728 add(new PatternLongGroup2(0));
00729 add(new PatternGroup(UL,L));
00730
00731 add(new ImmediateEscapeGroup());
00732 add(new PatternLongGroup2(3));
00733 add(new PatternLongGroup2(2));
00734 add(new KaranariGroup());
00735
00736 add(new BigramAttackGroup(true, true));
00737 add(new BigramAttackGroup(false, true));
00738 add(new BigramAttackGroup(true, false));
00739 add(new BigramAttackGroup(false, false));
00740
00741 add(new DropCapturedGroup());
00742 add(new ContinueCaptureGroup());
00743 add(new PawnAttackGroup());
00744 add(new ThreatmateGroup());
00745
00746 add(new BadLanceGroup());
00747 add(new CheckmateIfCaptureGroup());
00748 add(new RookDefense());
00749 add(new SendOffGroup());
00750
00751 add(new PinGroup());
00752 add(new KingEscapeGroup());
00753 add(new EscapePinGroup());
00754
00755 addFinished();
00756 bool success = tryLoad(defaultDirectory());
00757 if (! allow_load_failure && ! success) {
00758 std::cerr << "error: unable to load rating from " << defaultDirectory();
00759 throw std::runtime_error("load failed " + OslConfig::home()+defaultDirectory());
00760 }
00761 }
00762
00763
00764 const osl::rating::StandardFeatureSet& osl::rating::
00765 StandardFeatureSet::instance()
00766 {
00767 static osl::rating::StandardFeatureSet common_instance;
00768 return common_instance;
00769 }
00770
00771 bool osl::rating::StandardFeatureSet::healthCheck()
00772 {
00773 std::cerr << "loading " << defaultDirectory() << ' ';
00774 try {
00775 instance();
00776 std::cerr << "success\n";
00777 }
00778 catch (std::exception& e)
00779 {
00780 std::cerr << e.what() << "\n";
00781 return false;
00782 }
00783 catch (...) {
00784 std::cerr << "unknown exception\n";
00785 return false;
00786 }
00787 return true;
00788 }
00789
00790 osl::rating::
00791 CaptureSet::CaptureSet(bool allow_load_failure)
00792 {
00793 add(new CaptureGroup());
00794 add(new ShadowEffectGroup());
00795
00796 addFinished();
00797 bool success = tryLoad(defaultDirectory());
00798 if (! allow_load_failure && ! success) {
00799 std::cerr << "error: unable to load rating from " << defaultDirectory();
00800 throw std::runtime_error("load failed " + defaultDirectory());
00801 }
00802 }
00803
00804
00805
00806
00807
00808
00809