Go to the documentation of this file.00001
00002
00003 #include "osl/game_playing/weightTracer.h"
00004 #include "osl/game_playing/openingBookTracer.h"
00005 #include "osl/record/opening/openingBook.h"
00006 #include "osl/record/csa.h"
00007 #include "osl/stl/vector.h"
00008 #include "osl/misc/random.h"
00009 #include "osl/misc/ctime.h"
00010 #include <boost/utility.hpp>
00011 #include <iostream>
00012 #include <ctime>
00013
00014 osl::game_playing::
00015 WeightTracer::WeightTracer(WeightedBook& b, bool v,
00016 const int weight_coef_for_the_initial_move,
00017 const int weight_coef)
00018 : book(b), state_index(b.getStartState()), start_index(b.getStartState()),
00019 turn(BLACK),
00020 weight_coef_for_the_initial_move(weight_coef_for_the_initial_move),
00021 weight_coef(weight_coef)
00022 {
00023 verbose = v;
00024 }
00025
00026 osl::game_playing::
00027 WeightTracer::WeightTracer(const WeightTracer& copy)
00028 : OpeningBookTracer(copy),
00029 book(copy.book), state_index(copy.state_index),
00030 start_index(copy.start_index), turn(copy.turn),
00031 state_stack(copy.state_stack),
00032 weight_coef_for_the_initial_move(copy.weight_coef_for_the_initial_move),
00033 weight_coef(copy.weight_coef)
00034 {
00035 }
00036
00037 osl::game_playing::OpeningBookTracer* osl::game_playing::
00038 WeightTracer::clone() const
00039 {
00040 return new WeightTracer(*this);
00041 }
00042
00043 void osl::game_playing::
00044 WeightTracer::update(Move move)
00045 {
00046 if (verbose) {
00047 std::cerr << "WeightTracer "
00048 << " Move: " << record::csa::show(move) << " ";
00049 const time_t now = time(0);
00050 char ctime_buf[64];
00051 std::cerr << ctime_r(&now, ctime_buf)
00052 << std::endl;
00053 }
00054
00055 state_stack.push(state_index);
00056 assert(move.player() == turn);
00057 turn = alt(turn);
00058
00059 if (! isOutOfBook())
00060 {
00061 const vector<record::opening::WMove>& moves = book.getMoves(state_index);
00062 for (size_t i=0; i<moves.size(); i++)
00063 {
00064 if(moves[i].getMove() == move)
00065 {
00066 state_index = moves[i].getStateIndex();
00067 if (verbose)
00068 std::cerr << "book: "
00069 << state_stack.top() << "->" << state_index << "\n";
00070 return;
00071 }
00072 }
00073 if (verbose)
00074 std::cerr << "book: end" << "\n";
00075 }
00076 state_index = -1;
00077 }
00078
00079 void osl::game_playing::
00080 WeightTracer::popMove()
00081 {
00082 state_index = state_stack.top();
00083 state_stack.pop();
00084 turn = alt(turn);
00085 if (verbose)
00086 std::cerr << "WeightTracer " << this << " pop: " << turn << std::endl;
00087 }
00088
00089 bool osl::game_playing::
00090 WeightTracer::isOutOfBook() const
00091 {
00092 return state_index < 0;
00093 }
00094
00095 const osl::Move osl::game_playing::
00096 WeightTracer::selectMoveAtRandom(const std::vector<osl::record::opening::WMove>& moves) const
00097 {
00098 if (verbose)
00099 std::cerr << "book " << moves.size() << " candidates\n" << std::endl;
00100
00101 int max_weight_index = 0;
00102 int max_weight = 0;
00103 int sum = 0;
00104 for (size_t i=0; i<moves.size(); ++i) {
00105 sum += moves[i].getWeight();
00106 if (max_weight < moves[i].getWeight()) {
00107 max_weight = moves[i].getWeight();
00108 max_weight_index = i;
00109 }
00110 }
00111
00112 const int random_value = time_seeded_random() % sum;
00113 if (verbose)
00114 std::cerr << "random number: " << random_value << std::endl;
00115
00116 int maxIndex = -1;
00117 int weight = 0;
00118 for (size_t index = 0; index < moves.size(); index++)
00119 {
00120 weight += moves[index].getWeight();
00121 if (random_value <= weight)
00122 {
00123 maxIndex = index;
00124 break;
00125 }
00126 }
00127
00128 if (maxIndex >= 0) {
00129 if (verbose) {
00130 const int weight = moves[maxIndex].getWeight();
00131 std::cerr << "book "
00132 << 100.0*weight/sum << '%';
00133 if (weight != max_weight)
00134 std::cerr << " (c.f. " << 100.0*max_weight/sum
00135 << " " << record::csa::show(moves[max_weight_index].getMove())
00136 << ")";
00137 std::cerr << std::endl;
00138 }
00139 return moves[maxIndex].getMove();
00140 }
00141 return Move::INVALID();
00142 }
00143
00144 const osl::Move osl::game_playing::
00145 WeightTracer::selectMove() const
00146 {
00147 const vector<record::opening::WMove> raw_moves = book.getMoves(state_index);
00148 vector<record::opening::WMove> moves;
00149
00150 int max_weight = 0;
00151 for (size_t i=0; i<raw_moves.size(); ++i) {
00152 if (max_weight < raw_moves[i].getWeight()) {
00153 max_weight = raw_moves[i].getWeight();
00154 }
00155 }
00156 int sum = 0;
00157 const int coef = ((state_index == start_index) ?
00158 weight_coef_for_the_initial_move : weight_coef);
00159 for (size_t i=0; i<raw_moves.size(); ++i) {
00160 if (raw_moves[i].getWeight()*coef < max_weight)
00161 continue;
00162 moves.push_back(raw_moves[i]);
00163 sum += raw_moves[i].getWeight();
00164 }
00165
00166 if (sum == 0)
00167 return Move::INVALID();
00168
00169 return selectMoveAtRandom(moves);
00170 }
00171
00172
00173 osl::game_playing::OpeningBookTracer* osl::game_playing::
00174 DeterminateWeightTracer::clone() const
00175 {
00176 return new DeterminateWeightTracer(*this);
00177 }
00178
00179 const osl::Move osl::game_playing::
00180 DeterminateWeightTracer::selectMove() const
00181 {
00182 vector<record::opening::WMove> moves = book.getMoves(state_index);
00183 const int original_size = moves.size();
00184 std::sort(moves.begin(), moves.end(), osl::record::opening::WMoveSort());
00185
00186
00187
00188
00189
00190
00191
00192
00193 int top = topn;
00194 vector<record::opening::WMove>::iterator it = moves.begin();
00195 for (; it != moves.end() && top > 0; ++it) {
00196 if (it->getWeight() == 0)
00197 break;
00198
00199 if (it->getWeight() != boost::next(it)->getWeight())
00200 top -= 1;
00201 }
00202 moves.erase(it, moves.end());
00203
00204 if (verbose) {
00205 std::cerr << "book: there remain " << moves.size() << " candidates of "
00206 << original_size << " moves\n";
00207 }
00208
00209 if (moves.empty())
00210 return Move::INVALID();
00211
00212 return selectMoveAtRandom(moves);
00213 }
00214
00215
00216
00217
00218
00219