openingBook.cc
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); // mark states that have been visited.
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     } // each wmove
00275   } // while loop
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(); // next state to visit
00293       continue;
00294     }
00295     return -1; // not found
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); // mark states that have been visited.
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     } // each wmove
00330   } // while loop
00331 
00332   return ret;
00333 }
00334 
00335 // ;;; Local Variables:
00336 // ;;; mode:c++
00337 // ;;; c-basic-offset:2
00338 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines