openingBook.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
openingBook.cc
Go to the documentation of this file.
1 #include "osl/record/opening/openingBook.h"
2 #include "osl/record/record.h"
3 #include "osl/record/compactBoard.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
12 osl::record::opening::
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
25 osl::record::opening::
26 WinCountBook::~WinCountBook()
27 {
28 }
29
30 int osl::record::opening::
31 WinCountBook::readInt()
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
42 void osl::record::opening::
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 {
60 Move move=Move::makeDirect(readInt());
61 int stateIndex=readInt();
62 moves.push_back(OBMove(move,stateIndex));
63 }
64 return moves;
65 }
66
67 int osl::record::opening::
68 WinCountBook::getWinCount(int stateIndex)
69 {
70 seek(4+16*stateIndex);
71 return readInt();
72 }
73
74 int osl::record::opening::
75 WinCountBook::getLoseCount(int stateIndex)
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 {
83 osl::record::writeInt(os, osl::record::opening::OMove(w.getMove()));
84 osl::record::writeInt(os, w.getStateIndex());
85 osl::record::writeInt(os, w.getWeight());
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();
93 w.stateIndex = osl::record::readInt(is);
94 w.weight = osl::record::readInt(is);
95 return is;
96 }
97
98 osl::record::opening::
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);
113 nStates = osl::record::readInt(ifs);
114 nMoves = osl::record::readInt(ifs);
115 startState = osl::record::readInt(ifs);
116 }
117
118 osl::record::opening::
119 WeightedBook::~WeightedBook()
120 {
121 }
122
123 void osl::record::opening::
124 WeightedBook::seek(int offset)
125 {
126 ifs.seekg(offset,std::ios::beg);
127 }
128
129 osl::record::opening::WeightedBook::WMoveContainer osl::record::opening::
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
149 osl::record::CompactBoard osl::record::opening::
150 WeightedBook::getCompactBoard(int stateIndex)
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
166 int osl::record::opening::
167 WeightedBook::getWhiteWinCount(int stateIndex)
168 {
169 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
170 readInt(ifs);
171 readInt(ifs);
172 readInt(ifs);
173 return readInt(ifs);
174 }
175
176 int osl::record::opening::
177 WeightedBook::getBlackWinCount(int stateIndex)
178 {
179 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
180 readInt(ifs);
181 readInt(ifs);
182 return readInt(ifs);
183 }
184
185 void osl::record::opening::
186 WeightedBook::validate()
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
225 int osl::record::opening::
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
250 WMoveContainer moves;
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
280 int osl::record::opening::
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: