00001
00002
00003 #include "osl/rating/group.h"
00004 #include "osl/rating/feature/karanari.h"
00005 #include "osl/rating/feature/pinAttack.h"
00006 #include <boost/filesystem/path.hpp>
00007 #include <boost/filesystem/operations.hpp>
00008 #include <iostream>
00009 #include <fstream>
00010 #include <sstream>
00011 #include <iomanip>
00012 #include <cstdio>
00013 #include <cmath>
00014
00015 osl::rating::Group::Group(const std::string& name)
00016 : group_name(name)
00017 {
00018 }
00019
00020 osl::rating::Group::~Group()
00021 {
00022 }
00023
00024 int osl::rating::Group::findMatch(const NumEffectState& state, Move m, const RatingEnv& env) const
00025 {
00026 for (size_t j=0; j<size(); ++j) {
00027 if ((*this)[j].match(state, m, env))
00028 return j;
00029 }
00030 return -1;
00031 }
00032
00033 void osl::rating::Group::saveResult(const std::string& directory, const range_t& range,
00034 const std::vector<double>& weights) const
00035 {
00036 {
00037 boost::filesystem::path dir(directory);
00038 boost::filesystem::create_directory(dir);
00039 }
00040
00041 std::string filename = directory + "/" + group_name + ".txt";
00042 std::ofstream os(filename.c_str());
00043 for (int i=range.first; i<range.second; ++i)
00044 os << std::setprecision(8) << weights[i] << "\n";
00045 }
00046
00047 bool osl::rating::Group::load(const std::string& directory, const range_t& range,
00048 std::vector<double>& weights) const
00049 {
00050 std::string filename = directory + "/" + group_name + ".txt";
00051 FILE *fp = fopen(filename.c_str(), "r");
00052 if (! fp)
00053 return false;
00054 for (int i=range.first; i<range.second; ++i) {
00055 if (fscanf(fp, "%lf", &weights[i]) != 1)
00056 return false;
00057 }
00058 fclose(fp);
00059 return true;
00060 }
00061
00062 void osl::rating::Group::show(std::ostream& os, int name_width, const range_t& range,
00063 const std::vector<double>& weights) const
00064 {
00065 #ifndef MINIMAL
00066 for (size_t f=0; f<size(); ++f) {
00067 os << std::setw(name_width)
00068 << (*this)[f].name()
00069 << " " << 400*log10(weights[f+range.first]) << "\n";
00070 }
00071 #endif
00072 }
00073
00074 void osl::rating::Group::showAll(std::ostream& os, int name_width, const range_t& range,
00075 const std::vector<double>& weights) const
00076 {
00077 #ifndef MINIMAL
00078 showMinMax(os, name_width, range, weights);
00079 for (size_t i=0; i<size(); ++i) {
00080 os << " " << (*this)[i].name() << " " << 400*log10(weights[i+range.first]);
00081 }
00082 os << "\n";
00083 #endif
00084 }
00085 void osl::rating::Group::showMinMax(std::ostream& os, int name_width, const range_t& range,
00086 const std::vector<double>& weights) const
00087 {
00088 #ifndef MINIMAL
00089 double min = 10000000000.0, max = -min;
00090 for (size_t i=0; i<size(); ++i) {
00091 min = std::min(min, 400*log10(weights[i+range.first]));
00092 max = std::max(max, 400*log10(weights[i+range.first]));
00093 }
00094 os << std::setw(name_width)
00095 << group_name
00096 << " [" << min << " -- " << max << "] ";
00097 #endif
00098 }
00099
00100 void osl::rating::Group::showTopN(std::ostream& os, int name_width, const range_t& range,
00101 const std::vector<double>& weights, int n) const
00102 {
00103 #ifndef MINIMAL
00104 if ((int)weights.size() <= n*2)
00105 return showAll(os, name_width, range, weights);
00106 showMinMax(os, name_width, range, weights);
00107 std::vector<double> w;
00108 w.reserve(size());
00109 for (int i=range.first; i<range.second; ++i)
00110 w.push_back(weights[i]);
00111 std::sort(w.begin(), w.end());
00112 for (int i=0; i<n; ++i) {
00113 double value = w[size()-1-i];
00114 int j=range.first;
00115 for (; j<range.second; ++j)
00116 if (weights[j] == value)
00117 break;
00118 os << " " << (*this)[j-range.first].name() << " " << 400*log10(value);
00119 }
00120 os << " ... ";
00121 for (int i=0; i<n; ++i) {
00122 double value = w[n-1-i];
00123 int j=range.first;
00124 for (; j<range.second; ++j)
00125 if (weights[j] == value)
00126 break;
00127 os << " " << (*this)[j-range.first].name() << " " << 400*log10(value);
00128 }
00129 os << "\n";
00130 #endif
00131 }
00132
00133 osl::rating::
00134 ChaseGroup::ChaseGroup() : Group("Chase")
00135 {
00136 for (int o=0; o<4; ++o) {
00137 for (int t=PTYPE_PIECE_MIN; t<=PTYPE_MAX; ++t) {
00138 Ptype target = static_cast<Ptype>(t);
00139 for (int s=PTYPE_PIECE_MIN; s<=PTYPE_MAX; ++s) {
00140 Ptype self = static_cast<Ptype>(s);
00141 push_back(new Chase(self, target, false, static_cast<Chase::OpponentType>(o)));
00142 if (isBasic(self))
00143 push_back(new Chase(self, target, true, static_cast<Chase::OpponentType>(o)));
00144 }
00145 }
00146 }
00147 }
00148
00149 int osl::rating::
00150 ChaseGroup::findMatch(const NumEffectState& state, Move move, const RatingEnv& env) const
00151 {
00152 Move last_move = env.history.lastMove();
00153 if (! last_move.isNormal())
00154 return -1;
00155 if (! state.hasEffectIf(move.ptypeO(), move.to(), last_move.to()))
00156 return -1;
00157 int base = 0;
00158 const int unit = (PTYPE_MAX+1 - PTYPE_PIECE_MIN)*(PTYPE_MAX+1-PTYPE_PIECE_MIN+PTYPE_MAX+1-PTYPE_BASIC_MIN);
00159 if (last_move.capturePtype() == PTYPE_EMPTY) {
00160 if (last_move.isDrop()) {
00161 base = unit;
00162 } else {
00163 if (state.hasEffectAt(state.turn(), last_move.from()))
00164 base = unit*2;
00165 else
00166 base = unit*3;
00167 }
00168 }
00169 Ptype self = move.ptype();
00170 Ptype target = last_move.ptype();
00171 int index = base + (target - PTYPE_PIECE_MIN)*(PTYPE_MAX+1-PTYPE_PIECE_MIN+PTYPE_MAX+1-PTYPE_BASIC_MIN);
00172 if (isBasic(self)) {
00173 index += (PTYPE_BASIC_MIN - PTYPE_PIECE_MIN);
00174 index += (self - PTYPE_BASIC_MIN)*2;
00175 index += move.isDrop();
00176 } else {
00177 index += (self - PTYPE_PIECE_MIN);
00178 }
00179 assert((*this)[index].match(state, move, env));
00180 return index;
00181 }
00182
00183 osl::rating::KaranariGroup::KaranariGroup() : Group("Karanari")
00184 {
00185 push_back(new Karanari(false, true));
00186 push_back(new Karanari(false, false));
00187 push_back(new Karanari(true, true));
00188 push_back(new Karanari(true, false));
00189 }
00190
00191 int osl::rating::
00192 KaranariGroup::findMatch(const NumEffectState& state, Move move, const RatingEnv&) const
00193 {
00194 return Karanari::index(state, move);
00195 }
00196
00197 osl::rating::
00198 ImmediateAddSupportGroup::ImmediateAddSupportGroup()
00199 : Group("ImmediateAddSupport")
00200 {
00201 for (int s=PTYPE_PIECE_MIN; s<=PTYPE_MAX; ++s) {
00202 for (int a=PTYPE_PIECE_MIN; a<=PTYPE_MAX; ++a) {
00203 for (int p=0; p<8; ++p)
00204 push_back(new ImmediateAddSupport(static_cast<Ptype>(s), static_cast<Ptype>(a)));
00205 }
00206 }
00207 }
00208
00209
00210
00211
00212
00213