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