All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
weightTracer.cc
Go to the documentation of this file.
1 /* weightTracer.cc
2  */
6 #include "osl/record/csa.h"
7 #include "osl/stl/vector.h"
8 #include "osl/misc/random.h"
9 #include "osl/misc/ctime.h"
10 #include <boost/utility.hpp>
11 #include <iostream>
12 #include <ctime>
13 
16  const int weight_coef_for_the_initial_move,
17  const int weight_coef)
18  : book(b), state_index(b.getStartState()), start_index(b.getStartState()),
19  turn(BLACK),
20  weight_coef_for_the_initial_move(weight_coef_for_the_initial_move),
21  weight_coef(weight_coef)
22 {
23  verbose = v;
24 }
25 
28  : OpeningBookTracer(copy),
29  book(copy.book), state_index(copy.state_index),
30  start_index(copy.start_index), turn(copy.turn),
31  state_stack(copy.state_stack),
32  weight_coef_for_the_initial_move(copy.weight_coef_for_the_initial_move),
33  weight_coef(copy.weight_coef)
34 {
35 }
36 
39 {
40  return new WeightTracer(*this);
41 }
42 
45 {
46  if (verbose) {
47  std::cerr << "WeightTracer "
48  << " Move: " << record::csa::show(move) << " ";
49  const time_t now = time(0);
50  char ctime_buf[64];
51  std::cerr << ctime_r(&now, ctime_buf)
52  << std::endl;
53  }
54 
55  state_stack.push(state_index);
56  assert(move.player() == turn);
57  turn = alt(turn);
58 
59  if (! isOutOfBook())
60  {
61  const vector<record::opening::WMove>& moves = book.getMoves(state_index);
62  for (size_t i=0; i<moves.size(); i++)
63  {
64  if(moves[i].getMove() == move)
65  {
66  state_index = moves[i].getStateIndex();
67  if (verbose)
68  std::cerr << "book: "
69  << state_stack.top() << "->" << state_index << "\n";
70  return;
71  }
72  }
73  if (verbose)
74  std::cerr << "book: end" << "\n";
75  }
76  state_index = -1;
77 }
78 
81 {
82  state_index = state_stack.top();
83  state_stack.pop();
84  turn = alt(turn);
85  if (verbose)
86  std::cerr << "WeightTracer " << this << " pop: " << turn << std::endl;
87 }
88 
91 {
92  return state_index < 0;
93 }
94 
96 WeightTracer::selectMoveAtRandom(const std::vector<osl::record::opening::WMove>& moves) const
97 {
98  if (verbose)
99  std::cerr << "book " << moves.size() << " candidates\n" << std::endl;
100 
101  int max_weight_index = 0;
102  int max_weight = 0;
103  int sum = 0;
104  for (size_t i=0; i<moves.size(); ++i) {
105  sum += moves[i].getWeight();
106  if (max_weight < moves[i].getWeight()) {
107  max_weight = moves[i].getWeight();
108  max_weight_index = i;
109  }
110  }
111 
112  const int random_value = time_seeded_random() % sum;
113  if (verbose)
114  std::cerr << "random number: " << random_value << std::endl;
115 
116  int maxIndex = -1;
117  int weight = 0;
118  for (size_t index = 0; index < moves.size(); index++)
119  {
120  weight += moves[index].getWeight();
121  if (random_value <= weight)
122  {
123  maxIndex = index;
124  break;
125  }
126  }
127 
128  if (maxIndex >= 0) {
129  if (verbose) {
130  const int weight = moves[maxIndex].getWeight();
131  std::cerr << "book "
132  << 100.0*weight/sum << '%';
133  if (weight != max_weight)
134  std::cerr << " (c.f. " << 100.0*max_weight/sum
135  << " " << record::csa::show(moves[max_weight_index].getMove())
136  << ")";
137  std::cerr << std::endl;
138  }
139  return moves[maxIndex].getMove();
140  }
141  return Move::INVALID();
142 }
143 
146 {
147  const vector<record::opening::WMove> raw_moves = book.getMoves(state_index);
148  vector<record::opening::WMove> moves;
149 
150  int max_weight = 0;
151  for (size_t i=0; i<raw_moves.size(); ++i) {
152  if (max_weight < raw_moves[i].getWeight()) {
153  max_weight = raw_moves[i].getWeight();
154  }
155  }
156  int sum = 0;
157  const int coef = ((state_index == start_index) ?
158  weight_coef_for_the_initial_move : weight_coef);
159  for (size_t i=0; i<raw_moves.size(); ++i) {
160  if (raw_moves[i].getWeight()*coef < max_weight)
161  continue;
162  moves.push_back(raw_moves[i]);
163  sum += raw_moves[i].getWeight();
164  }
165 
166  if (sum == 0)
167  return Move::INVALID();
168 
169  return selectMoveAtRandom(moves);
170 }
171 
172 
175 {
176  return new DeterminateWeightTracer(*this);
177 }
178 
181 {
182  vector<record::opening::WMove> moves = book.getMoves(state_index);
183  const int original_size = moves.size();
184  std::sort(moves.begin(), moves.end(), osl::record::opening::WMoveSort());
185 
186  /*
187  * Select top_n moves.
188  * - WMoves with the same weight are included in the result.
189  * The size of the result vector might be greater than topn.
190  * - Zero-weighed WMoves are exluded. The size of the result vector
191  * might be less than topn.
192  */
193  int top = topn;
194  vector<record::opening::WMove>::iterator it = moves.begin();
195  for (/*none*/; it != moves.end() && top > 0; ++it) {
196  if (it->getWeight() == 0)
197  break;
198 
199  if (it->getWeight() != boost::next(it)->getWeight())
200  top -= 1;
201  }
202  moves.erase(it, moves.end());
203 
204  if (verbose) {
205  std::cerr << "book: there remain " << moves.size() << " candidates of "
206  << original_size << " moves\n";
207  }
208 
209  if (moves.empty())
210  return Move::INVALID();
211 
212  return selectMoveAtRandom(moves);
213 }
214 
215 /* ------------------------------------------------------------------------- */
216 // ;;; Local Variables:
217 // ;;; mode:c++
218 // ;;; c-basic-offset:2
219 // ;;; End: