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 <iostream>
00010 #include <ctime>
00011
00012 osl::game_playing::
00013 WeightTracer::WeightTracer(WeightedBook& b, bool v)
00014 : book(b), state_index(b.getStartState()), start_index(b.getStartState()),
00015 turn(BLACK), verbose(v)
00016 {
00017 }
00018
00019 osl::game_playing::
00020 WeightTracer::WeightTracer(const WeightTracer& copy)
00021 : OpeningBookTracer(copy),
00022 book(copy.book), state_index(copy.state_index),
00023 start_index(copy.start_index), turn(copy.turn),
00024 verbose(copy.verbose), state_stack(copy.state_stack)
00025 {
00026 }
00027
00028 osl::game_playing::OpeningBookTracer* osl::game_playing::
00029 WeightTracer::clone() const
00030 {
00031 return new WeightTracer(*this);
00032 }
00033
00034 void osl::game_playing::
00035 WeightTracer::update(Move move)
00036 {
00037 if (verbose) {
00038 std::cerr << "WeightTracer "
00039 << " Move: " << record::csa::show(move) << " ";
00040 const time_t now = time(0);
00041 char ctime_buf[64];
00042 std::cerr << ctime_r(&now, ctime_buf) << std::endl;
00043 }
00044
00045 state_stack.push(state_index);
00046 assert(move.player() == turn);
00047 changeTurn(turn);
00048
00049 if (! isOutOfBook())
00050 {
00051 const vector<record::opening::WMove>& moves = book.getMoves(state_index);
00052 for (size_t i=0; i<moves.size(); i++)
00053 {
00054 if(moves[i].getMove() == move)
00055 {
00056 state_index = moves[i].getStateIndex();
00057 if (verbose)
00058 std::cerr << "book: "
00059 << state_stack.top() << "->" << state_index << "\n";
00060 return;
00061 }
00062 }
00063 if (verbose)
00064 std::cerr << "book: end" << "\n";
00065 }
00066 state_index = -1;
00067 }
00068
00069 void osl::game_playing::
00070 WeightTracer::popMove()
00071 {
00072 state_index = state_stack.top();
00073 state_stack.pop();
00074 changeTurn(turn);
00075 if (verbose)
00076 std::cerr << "WeightTracer " << this << " pop: " << turn << std::endl;
00077 }
00078
00079 bool osl::game_playing::
00080 WeightTracer::isOutOfBook() const
00081 {
00082 return state_index < 0;
00083 }
00084
00085 const osl::Move osl::game_playing::
00086 WeightTracer::selectMove() const
00087 {
00088 int maxIndex = -1;
00089 vector<record::opening::WMove> raw_moves = book.getMoves(state_index);
00090 vector<record::opening::WMove> moves;
00091
00092 int max_weight_index = 0;
00093 int max_weight = 0;
00094 for (size_t i=0; i<raw_moves.size(); ++i) {
00095 if (max_weight < raw_moves[i].getWeight()) {
00096 max_weight = raw_moves[i].getWeight();
00097 max_weight_index = i;
00098 }
00099 }
00100 int sum = 0;
00101 const int coef = (state_index == start_index) ? 16 : 10;
00102 for (size_t i=0; i<raw_moves.size(); ++i) {
00103 if (raw_moves[i].getWeight()*coef < max_weight)
00104 continue;
00105 moves.push_back(raw_moves[i]);
00106 sum += raw_moves[i].getWeight();
00107 }
00108
00109 if (sum == 0)
00110 return Move::INVALID();
00111
00112 int random_value = time_seeded_random() % sum;
00113 int weight = 0;
00114
00115 if (verbose)
00116 std::cerr << "random number: " << random_value << std::endl;
00117
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 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(raw_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
00145 osl::game_playing::OpeningBookTracer* osl::game_playing::
00146 DeterminateWeightTracer::clone() const
00147 {
00148 return new DeterminateWeightTracer(*this);
00149 }
00150
00151 const osl::Move osl::game_playing::
00152 DeterminateWeightTracer::selectMove() const
00153 {
00154 const vector<record::opening::WMove> moves = book.getMoves(state_index);
00155
00156 int max_weight_index = 0;
00157 int max_weight = 0;
00158 for (size_t i=0; i<moves.size(); ++i) {
00159 if (max_weight < moves[i].getWeight()) {
00160 max_weight = moves[i].getWeight();
00161 max_weight_index = i;
00162 }
00163 }
00164
00165 if (max_weight == 0)
00166 return Move::INVALID();
00167
00168 if (verbose) {
00169 int sum = 0;
00170 for (size_t i=0; i<moves.size(); ++i)
00171 sum += moves[i].getWeight();
00172 if (sum > 0) {
00173 int weight = moves[max_weight_index].getWeight();
00174 std::cerr << "book "
00175 << 100.0*weight/sum << '%' << std::endl;
00176 }
00177 else {
00178 assert(false);
00179 }
00180 }
00181
00182 return moves[max_weight_index].getMove();
00183 }
00184
00185
00186
00187
00188
00189