00001 #include "osl/record/opening/openingBook.h"
00002 #include "osl/record/record.h"
00003 #include "osl/record/compactBoard.h"
00004 #include "osl/apply_move/applyMove.h"
00005 #include <boost/random/mersenne_twister.hpp>
00006 #include <boost/random/uniform_int.hpp>
00007 #include <algorithm>
00008 #include <iostream>
00009 #include <stdexcept>
00010
00011 osl::record::opening::
00012 WinCountBook::WinCountBook(const char *filename)
00013 : ifs(filename)
00014 {
00015 if (! ifs)
00016 {
00017 const char *message = "WinCountBook: open failed ";
00018 std::cerr << message << filename << std::endl;
00019 throw std::runtime_error(std::string(message) + filename);
00020 }
00021 nStates=readInt();
00022 }
00023
00024 osl::record::opening::
00025 WinCountBook::~WinCountBook()
00026 {
00027 }
00028
00029 int osl::record::opening::
00030 WinCountBook::readInt()
00031 {
00032 int ret=0;
00033 CArray<char,4> cs;
00034 ifs.read(&cs[0],4);
00035 for (int i=0;i<4;i++) {
00036 ret = (ret<<8)|(cs[i]&255);
00037 }
00038 return ret;
00039 }
00040
00041 void osl::record::opening::
00042 WinCountBook::seek(int offset)
00043 {
00044 ifs.seekg(offset,std::ios::beg);
00045 }
00046
00047 osl::vector<osl::record::opening::OBMove> osl::record::opening::
00048 WinCountBook::getMoves(int stateIndex)
00049 {
00050 assert(stateIndex >= 0);
00051 seek(4+16*stateIndex+8);
00052 int nMoves=readInt();
00053 int moveIndex=readInt();
00054 seek(4+16*nStates+8*moveIndex);
00055 vector<OBMove> moves;
00056 moves.reserve(nMoves);
00057 for(int i=0;i<nMoves;i++)
00058 {
00059 Move move=Move::makeDirect(readInt());
00060 int stateIndex=readInt();
00061 moves.push_back(OBMove(move,stateIndex));
00062 }
00063 return moves;
00064 }
00065
00066 int osl::record::opening::
00067 WinCountBook::getWinCount(int stateIndex)
00068 {
00069 seek(4+16*stateIndex);
00070 return readInt();
00071 }
00072
00073 int osl::record::opening::
00074 WinCountBook::getLoseCount(int stateIndex)
00075 {
00076 seek(4+16*stateIndex+4);
00077 return readInt();
00078 }
00079
00080 std::ostream& osl::record::opening::operator<<(std::ostream& os, const WMove& w)
00081 {
00082 osl::record::writeInt(os, osl::record::opening::OMove(w.getMove()));
00083 osl::record::writeInt(os, w.getStateIndex());
00084 osl::record::writeInt(os, w.getWeight());
00085 return os;
00086 }
00087
00088 std::istream& osl::record::opening::operator>>(std::istream& is, WMove& w)
00089 {
00090 w.move = OMove(osl::record::readInt(is)).operator Move();
00091 w.stateIndex = osl::record::readInt(is);
00092 w.weight = osl::record::readInt(is);
00093 return is;
00094 }
00095
00096
00097 osl::record::opening::
00098 WeightedBook::WeightedBook(const char *filename)
00099 : ifs(filename)
00100 {
00101 if (! ifs)
00102 {
00103 const char *message = "WeightedBook: open failed ";
00104 std::cerr << message << filename << std::endl;
00105 throw std::runtime_error(std::string(message) + filename);
00106 }
00107 #ifndef NDEBUG
00108 int version =
00109 #endif
00110 readInt(ifs);
00111 assert(version == 1);
00112 nStates = osl::record::readInt(ifs);
00113 nMoves = osl::record::readInt(ifs);
00114 startState = osl::record::readInt(ifs);
00115 }
00116
00117 osl::record::opening::
00118 WeightedBook::~WeightedBook()
00119 {
00120 }
00121
00122 void osl::record::opening::
00123 WeightedBook::seek(int offset)
00124 {
00125 ifs.seekg(offset,std::ios::beg);
00126 }
00127
00128 osl::vector<osl::record::opening::WMove> osl::record::opening::
00129 WeightedBook::getMoves(int stateIndex)
00130 {
00131 assert(stateIndex >= 0);
00132 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
00133 int moveIndex=readInt(ifs);
00134 int nWMoves=readInt(ifs);
00135 seek(HEADER_SIZE + STATE_SIZE * nStates + MOVE_SIZE * moveIndex);
00136 vector<WMove> moves;
00137 moves.reserve(nWMoves);
00138 for(int i=0;i<nWMoves;i++)
00139 {
00140 WMove wm;
00141 ifs >> wm;
00142 moves.push_back(wm);
00143 }
00144 return moves;
00145 }
00146
00147 osl::SimpleState osl::record::opening::
00148 WeightedBook::getBoard(int stateIndex)
00149 {
00150 seek(HEADER_SIZE + STATE_SIZE * nStates + MOVE_SIZE * nMoves
00151 + BOARD_SIZE * stateIndex);
00152 CompactBoard board;
00153 ifs >> board;
00154 return board.getState();
00155 }
00156
00157 int osl::record::opening::
00158 WeightedBook::getWhiteWinCount(int stateIndex)
00159 {
00160 seek(HEADER_SIZE + STATE_SIZE * stateIndex);
00161 readInt(ifs);
00162 readInt(ifs);
00163 return readInt(ifs);
00164 }
00165
00166 int osl::record::opening::
00167 WeightedBook::getBlackWinCount(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 void osl::record::opening::
00177 WeightedBook::validate()
00178 {
00179 {
00180 osl::SimpleState state(osl::HIRATE);
00181 osl::SimpleState start = getBoard(startState);
00182 assert(state == start);
00183 }
00184
00185 bool visited[nStates];
00186 for (int i = 0; i < nStates; i++)
00187 {
00188 visited[i] = false;
00189 }
00190
00191 osl::vector<int> stateToCheck;
00192 stateToCheck.push_back(startState);
00193 visited[startState] = true;
00194
00195 while (!stateToCheck.empty())
00196 {
00197 const int index = stateToCheck.back();
00198 stateToCheck.pop_back();
00199 osl::SimpleState state = getBoard(index);
00200 osl::vector<osl::record::opening::WMove> moves = getMoves(index);
00201 for (size_t i = 0; i < moves.size(); i++)
00202 {
00203 osl::SimpleState newState(state);
00204 osl::ApplyMoveOfTurn::doMove(newState, moves[i].getMove());
00205 const int nextIndex = moves[i].getStateIndex();
00206
00207 osl::SimpleState stateInFile = getBoard(nextIndex);
00208 assert(newState == stateInFile);
00209 if (!visited[nextIndex])
00210 {
00211 stateToCheck.push_back(nextIndex);
00212 visited[nextIndex] = true;
00213 }
00214 }
00215 }
00216 }
00217
00218
00219
00220
00221