Go to the documentation of this file.00001 #include "osl/record/opening/openingBook.h"
00002 #include "osl/record/record.h"
00003 #include "osl/record/compactBoard.h"
00004 #include <boost/random/mersenne_twister.hpp>
00005 #include <boost/random/uniform_int.hpp>
00006 #include <boost/foreach.hpp>
00007 #include <algorithm>
00008 #include <iostream>
00009 #include <stdexcept>
00010
00011 #ifndef MINIMAL
00012 osl::record::opening::
00013 WinCountBook::WinCountBook(const char *filename)
00014 : ifs(filename, std::ios_base::binary)
00015 {
00016 if (! ifs)
00017 {
00018 const char *message = "WinCountBook: open failed ";
00019 std::cerr << message << filename << std::endl;
00020 throw std::runtime_error(std::string(message) + filename);
00021 }
00022 nStates=readInt();
00023 }
00024
00025 osl::record::opening::
00026 WinCountBook::~WinCountBook()
00027 {
00028 }
00029
00030 int osl::record::opening::
00031 WinCountBook::readInt()
00032 {
00033 int ret=0;
00034 CArray<char,4> cs;
00035 ifs.read(&cs[0],4);
00036 for (int i=0;i<4;i++) {
00037 ret = (ret<<8)|(cs[i]&255);
00038 }
00039 return ret;
00040 }
00041
00042 void osl::record::opening::
00043 WinCountBook::seek(int offset)
00044 {
00045 ifs.seekg(offset,std::ios::beg);
00046 }
00047
00048 osl::vector<osl::record::opening::OBMove> osl::record::opening::
00049 WinCountBook::getMoves(int stateIndex)
00050 {
00051 assert(stateIndex >= 0);
00052 seek(4+16*stateIndex+8);
00053 int nMoves=readInt();
00054 int moveIndex=readInt();
00055 seek(4+16*nStates+8*moveIndex);
00056 vector<OBMove> moves;
00057 moves.reserve(nMoves);
00058 for(int i=0;i<nMoves;i++)
00059 {
00060 Move move=Move::makeDirect(readInt());
00061 int stateIndex=readInt();
00062 moves.push_back(OBMove(move,stateIndex));
00063 }
00064 return moves;
00065 }
00066
00067 int osl::record::opening::
00068 WinCountBook::getWinCount(int stateIndex)
00069 {
00070 seek(4+16*stateIndex);
00071 return readInt();
00072 }
00073
00074 int osl::record::opening::
00075 WinCountBook::getLoseCount(int stateIndex)
00076 {
00077 seek(4+16*stateIndex+4);
00078 return readInt();
00079 }
00080
00081 std::ostream& osl::record::opening::operator<<(std::ostream& os, const WMove& w)
00082 {
00083 osl::record::writeInt(os, osl::record::opening::OMove(w.getMove()));
00084 osl::record::writeInt(os, w.getStateIndex());
00085 osl::record::writeInt(os, w.getWeight());
00086 return os;
00087 }
00088 #endif
00089
00090 std::istream& osl::record::opening::operator>>(std::istream& is, WMove& w)
00091 {
00092 w.move = OMove(osl::record::readInt(is)).operator Move();
00093 w.stateIndex = osl::record::readInt(is);
00094 w.weight = osl::record::readInt(is);
00095 return is;
00096 }
00097
00098 osl::record::opening::
00099 WeightedBook::WeightedBook(const char *filename)
00100 : ifs(filename, std::ios_base::binary)
00101 {
00102 if (! ifs)
00103 {
00104 const char *message = "WeightedBook: open failed ";
00105 std::cerr << message << filename << std::endl;
00106 throw std::runtime_error(std::string(message) + filename);
00107 }
00108 #ifndef NDEBUG
00109 int version =
00110 #endif
00111 readInt(ifs);
00112 assert(version == 1);
00113 nStates = osl::record::readInt(ifs);
00114 nMoves = osl::record::readInt(ifs);
00115 startState = osl::record::readInt(ifs);
00116 }
00117
00118 osl::record::opening::
00119 WeightedBook::~WeightedBook()
00120 {
00121 }
00122
00123 void osl::record::opening::
00124 WeightedBook::seek(int offset)
00125 {
00126 ifs.seekg(offset,std::ios::beg);
00127 }
00128
00129 osl::record::opening::WeightedBook::WMoveContainer osl::record::opening::
00130 WeightedBook::getMoves(int stateIndex, const bool visit_zero)
00131 {
00132 assert(stateIndex >= 0);
00133 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
00134 int moveIndex=readInt(ifs);
00135 int nWMoves=readInt(ifs);
00136 seek(HEADER_SIZE + STATE_SIZE * nStates + MOVE_SIZE * moveIndex);
00137 vector<WMove> moves;
00138 moves.reserve(nWMoves);
00139 for(int i=0;i<nWMoves;i++)
00140 {
00141 WMove wm;
00142 ifs >> wm;
00143 if (!visit_zero && wm.getWeight() == 0) continue;
00144 moves.push_back(wm);
00145 }
00146 return moves;
00147 }
00148
00149 osl::record::CompactBoard osl::record::opening::
00150 WeightedBook::getCompactBoard(int stateIndex)
00151 {
00152 seek(HEADER_SIZE + STATE_SIZE * nStates + MOVE_SIZE * nMoves
00153 + BOARD_SIZE * stateIndex);
00154 CompactBoard board;
00155 ifs >> board;
00156 return board;
00157 }
00158
00159 osl::SimpleState osl::record::opening::
00160 WeightedBook::getBoard(int stateIndex)
00161 {
00162 const CompactBoard board = getCompactBoard(stateIndex);
00163 return board.getState();
00164 }
00165
00166 int osl::record::opening::
00167 WeightedBook::getWhiteWinCount(int stateIndex)
00168 {
00169 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
00170 readInt(ifs);
00171 readInt(ifs);
00172 readInt(ifs);
00173 return readInt(ifs);
00174 }
00175
00176 int osl::record::opening::
00177 WeightedBook::getBlackWinCount(int stateIndex)
00178 {
00179 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
00180 readInt(ifs);
00181 readInt(ifs);
00182 return readInt(ifs);
00183 }
00184
00185 void osl::record::opening::
00186 WeightedBook::validate()
00187 {
00188 #ifndef NDEBUG
00189 {
00190 SimpleState state(HIRATE);
00191 SimpleState start = getBoard(startState);
00192 assert(state == start);
00193 }
00194 #endif
00195 vector<char> visited(nStates);
00196 std::fill(visited.begin(), visited.end(), false);
00197
00198 vector<int> stateToCheck;
00199 stateToCheck.push_back(startState);
00200 visited[startState] = true;
00201
00202 while (!stateToCheck.empty())
00203 {
00204 const int index = stateToCheck.back();
00205 stateToCheck.pop_back();
00206 SimpleState state = getBoard(index);
00207 vector<record::opening::WMove> moves = getMoves(index);
00208 BOOST_FOREACH(WMove move, moves)
00209 {
00210 NumEffectState newState(state);
00211 newState.makeMove(move.getMove());
00212 const int nextIndex = move.getStateIndex();
00213
00214 SimpleState stateInFile = getBoard(nextIndex);
00215 assert(newState == stateInFile);
00216 if (!visited[nextIndex])
00217 {
00218 stateToCheck.push_back(nextIndex);
00219 visited[nextIndex] = true;
00220 }
00221 }
00222 }
00223 }
00224
00225 int osl::record::opening::
00226 WeightedBook::getStateIndex(const SimpleState& state_to_look_for,
00227 const bool visit_zero,
00228 const Player player)
00229 {
00230 int ret = -1;
00231 const CompactBoard board_to_look_for(state_to_look_for);
00232
00233 const CompactBoard start_state = getCompactBoard(getStartState());
00234 if (start_state == board_to_look_for)
00235 {
00236 ret = getStartState();
00237 return ret;
00238 }
00239
00240 vector<char> states(getTotalState(), false);
00241 vector<int> stateToVisit;
00242 stateToVisit.push_back(getStartState());
00243
00244 while (!stateToVisit.empty())
00245 {
00246 const int stateIndex = stateToVisit.back();
00247 stateToVisit.pop_back();
00248 states[stateIndex] = true;
00249
00250 WMoveContainer moves;
00251 if (visit_zero)
00252 moves = getMoves(stateIndex);
00253 else
00254 {
00255 const CompactBoard stateIndexCB = getCompactBoard(stateIndex);
00256 const Player turn = stateIndexCB.turn();
00257 const bool zero_include = turn == player ? false : true;
00258 moves = getMoves(stateIndex, zero_include);
00259 }
00260 BOOST_FOREACH(WMove move, moves)
00261 {
00262 const int nextIndex = move.getStateIndex();
00263 if (! states[nextIndex])
00264 {
00265 const CompactBoard state = getCompactBoard(nextIndex);
00266 if (state == board_to_look_for)
00267 {
00268 ret = nextIndex;
00269 return ret;
00270 }
00271
00272 stateToVisit.push_back(nextIndex);
00273 }
00274 }
00275 }
00276
00277 return ret;
00278 }
00279
00280 int osl::record::opening::
00281 WeightedBook::getStateIndex(const osl::vector<osl::Move>& moves)
00282 {
00283 int state_index = getStartState();
00284 BOOST_FOREACH(Move move, moves)
00285 {
00286 const WMoveContainer wmoves = getMoves(state_index);
00287 WMoveContainer::const_iterator it = wmoves.begin();
00288 for (; it != wmoves.end(); ++it)
00289 if (it->getMove() == move) break;
00290 if (it != wmoves.end())
00291 {
00292 state_index = it->getStateIndex();
00293 continue;
00294 }
00295 return -1;
00296 }
00297 return state_index;
00298 }
00299
00300
00301 std::vector<int> osl::record::opening::
00302 WeightedBook::getParents(const int target_state_index)
00303 {
00304 std::vector<int> ret;
00305
00306 if (getStartState() == target_state_index)
00307 return ret;
00308
00309 vector<char> states(getTotalState(), false);
00310 vector<int> stateToVisit;
00311 stateToVisit.push_back(getStartState());
00312
00313 while (!stateToVisit.empty())
00314 {
00315 const int stateIndex = stateToVisit.back();
00316 stateToVisit.pop_back();
00317 states[stateIndex] = true;
00318
00319 const WMoveContainer moves = getMoves(stateIndex);
00320 BOOST_FOREACH(WMove move, moves)
00321 {
00322 const int nextIndex = move.getStateIndex();
00323
00324 if (nextIndex == target_state_index)
00325 ret.push_back(stateIndex);
00326
00327 if (! states[nextIndex])
00328 stateToVisit.push_back(nextIndex);
00329 }
00330 }
00331
00332 return ret;
00333 }
00334
00335
00336
00337
00338