All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
openingBook.cc
Go to the documentation of this file.
2 #include "osl/record/record.h"
4 #include <boost/random/mersenne_twister.hpp>
5 #include <boost/random/uniform_int.hpp>
6 #include <boost/foreach.hpp>
7 #include <algorithm>
8 #include <iostream>
9 #include <stdexcept>
10 
11 #ifndef MINIMAL
13 WinCountBook::WinCountBook(const char *filename)
14  : ifs(filename, std::ios_base::binary)
15 {
16  if (! ifs)
17  {
18  const char *message = "WinCountBook: open failed ";
19  std::cerr << message << filename << std::endl;
20  throw std::runtime_error(std::string(message) + filename);
21  }
22  nStates=readInt();
23 }
24 
27 {
28 }
29 
32 {
33  int ret=0;
34  CArray<char,4> cs;
35  ifs.read(&cs[0],4);
36  for (int i=0;i<4;i++) {
37  ret = (ret<<8)|(cs[i]&255);
38  }
39  return ret;
40 }
41 
43 WinCountBook::seek(int offset)
44 {
45  ifs.seekg(offset,std::ios::beg);
46 }
47 
48 osl::vector<osl::record::opening::OBMove> osl::record::opening::
49 WinCountBook::getMoves(int stateIndex)
50 {
51  assert(stateIndex >= 0);
52  seek(4+16*stateIndex+8);
53  int nMoves=readInt();
54  int moveIndex=readInt();
55  seek(4+16*nStates+8*moveIndex);
56  vector<OBMove> moves;
57  moves.reserve(nMoves);
58  for(int i=0;i<nMoves;i++)
59  {
61  int stateIndex=readInt();
62  moves.push_back(OBMove(move,stateIndex));
63  }
64  return moves;
65 }
66 
69 {
70  seek(4+16*stateIndex);
71  return readInt();
72 }
73 
76 {
77  seek(4+16*stateIndex+4);
78  return readInt();
79 }
80 
81 std::ostream& osl::record::opening::operator<<(std::ostream& os, const WMove& w)
82 {
86  return os;
87 }
88 #endif
89 
90 std::istream& osl::record::opening::operator>>(std::istream& is, WMove& w)
91 {
92  w.move = OMove(osl::record::readInt(is)).operator Move();
95  return is;
96 }
97 
99 WeightedBook::WeightedBook(const char *filename)
100  : ifs(filename, std::ios_base::binary)
101 {
102  if (! ifs)
103  {
104  const char *message = "WeightedBook: open failed ";
105  std::cerr << message << filename << std::endl;
106  throw std::runtime_error(std::string(message) + filename);
107  }
108 #ifndef NDEBUG
109  int version =
110 #endif
111  readInt(ifs);
112  assert(version == 1);
116 }
117 
120 {
121 }
122 
125 {
126  ifs.seekg(offset,std::ios::beg);
127 }
128 
130 WeightedBook::getMoves(int stateIndex, const bool visit_zero)
131 {
132  assert(stateIndex >= 0);
133  seek(HEADER_SIZE + STATE_SIZE * stateIndex);
134  int moveIndex=readInt(ifs);
135  int nWMoves=readInt(ifs);
136  seek(HEADER_SIZE + STATE_SIZE * nStates + MOVE_SIZE * moveIndex);
137  vector<WMove> moves;
138  moves.reserve(nWMoves);
139  for(int i=0;i<nWMoves;i++)
140  {
141  WMove wm;
142  ifs >> wm;
143  if (!visit_zero && wm.getWeight() == 0) continue;
144  moves.push_back(wm);
145  }
146  return moves;
147 }
148 
151 {
152  seek(HEADER_SIZE + STATE_SIZE * nStates + MOVE_SIZE * nMoves
153  + BOARD_SIZE * stateIndex);
154  CompactBoard board;
155  ifs >> board;
156  return board;
157 }
158 
159 osl::SimpleState osl::record::opening::
160 WeightedBook::getBoard(int stateIndex)
161 {
162  const CompactBoard board = getCompactBoard(stateIndex);
163  return board.getState();
164 }
165 
168 {
169  seek(HEADER_SIZE + STATE_SIZE * stateIndex);
170  readInt(ifs);
171  readInt(ifs);
172  readInt(ifs);
173  return readInt(ifs);
174 }
175 
178 {
179  seek(HEADER_SIZE + STATE_SIZE * stateIndex);
180  readInt(ifs);
181  readInt(ifs);
182  return readInt(ifs);
183 }
184 
187 {
188 #ifndef NDEBUG
189  {
190  SimpleState state(HIRATE);
191  SimpleState start = getBoard(startState);
192  assert(state == start);
193  }
194 #endif
195  vector<char> visited(nStates);
196  std::fill(visited.begin(), visited.end(), false);
197 
198  vector<int> stateToCheck;
199  stateToCheck.push_back(startState);
200  visited[startState] = true;
201 
202  while (!stateToCheck.empty())
203  {
204  const int index = stateToCheck.back();
205  stateToCheck.pop_back();
206  SimpleState state = getBoard(index);
207  vector<record::opening::WMove> moves = getMoves(index);
208  BOOST_FOREACH(WMove move, moves)
209  {
210  NumEffectState newState(state);
211  newState.makeMove(move.getMove());
212  const int nextIndex = move.getStateIndex();
213 
214  SimpleState stateInFile = getBoard(nextIndex);
215  assert(newState == stateInFile);
216  if (!visited[nextIndex])
217  {
218  stateToCheck.push_back(nextIndex);
219  visited[nextIndex] = true;
220  }
221  }
222  }
223 }
224 
226 WeightedBook::getStateIndex(const SimpleState& state_to_look_for,
227  const bool visit_zero,
228  const Player player)
229 {
230  int ret = -1;
231  const CompactBoard board_to_look_for(state_to_look_for);
232 
233  const CompactBoard start_state = getCompactBoard(getStartState());
234  if (start_state == board_to_look_for)
235  {
236  ret = getStartState();
237  return ret;
238  }
239 
240  vector<char> states(getTotalState(), false); // mark states that have been visited.
241  vector<int> stateToVisit;
242  stateToVisit.push_back(getStartState());
243 
244  while (!stateToVisit.empty())
245  {
246  const int stateIndex = stateToVisit.back();
247  stateToVisit.pop_back();
248  states[stateIndex] = true;
249 
251  if (visit_zero)
252  moves = getMoves(stateIndex);
253  else
254  {
255  const CompactBoard stateIndexCB = getCompactBoard(stateIndex);
256  const Player turn = stateIndexCB.turn();
257  const bool zero_include = turn == player ? false : true;
258  moves = getMoves(stateIndex, zero_include);
259  }
260  BOOST_FOREACH(WMove move, moves)
261  {
262  const int nextIndex = move.getStateIndex();
263  if (! states[nextIndex])
264  {
265  const CompactBoard state = getCompactBoard(nextIndex);
266  if (state == board_to_look_for)
267  {
268  ret = nextIndex;
269  return ret;
270  }
271 
272  stateToVisit.push_back(nextIndex);
273  }
274  } // each wmove
275  } // while loop
276 
277  return ret;
278 }
279 
281 WeightedBook::getStateIndex(const osl::vector<osl::Move>& moves)
282 {
283  int state_index = getStartState();
284  BOOST_FOREACH(Move move, moves)
285  {
286  const WMoveContainer wmoves = getMoves(state_index);
287  WMoveContainer::const_iterator it = wmoves.begin();
288  for (; it != wmoves.end(); ++it)
289  if (it->getMove() == move) break;
290  if (it != wmoves.end())
291  {
292  state_index = it->getStateIndex(); // next state to visit
293  continue;
294  }
295  return -1; // not found
296  }
297  return state_index;
298 }
299 
300 
301 std::vector<int> osl::record::opening::
302 WeightedBook::getParents(const int target_state_index)
303 {
304  std::vector<int> ret;
305 
306  if (getStartState() == target_state_index)
307  return ret;
308 
309  vector<char> states(getTotalState(), false); // mark states that have been visited.
310  vector<int> stateToVisit;
311  stateToVisit.push_back(getStartState());
312 
313  while (!stateToVisit.empty())
314  {
315  const int stateIndex = stateToVisit.back();
316  stateToVisit.pop_back();
317  states[stateIndex] = true;
318 
319  const WMoveContainer moves = getMoves(stateIndex);
320  BOOST_FOREACH(WMove move, moves)
321  {
322  const int nextIndex = move.getStateIndex();
323 
324  if (nextIndex == target_state_index)
325  ret.push_back(stateIndex);
326 
327  if (! states[nextIndex])
328  stateToVisit.push_back(nextIndex);
329  } // each wmove
330  } // while loop
331 
332  return ret;
333 }
334 
335 // ;;; Local Variables:
336 // ;;; mode:c++
337 // ;;; c-basic-offset:2
338 // ;;; End: