compactBoard.cc
Go to the documentation of this file.
00001 #include "osl/record/record.h"
00002 #include "osl/record/compactBoard.h"
00003 #include "osl/misc/base64.h"
00004 #include <boost/dynamic_bitset.hpp>
00005 #include <boost/foreach.hpp>
00006 #include <iostream>
00007 #include <algorithm>
00008 #include <sstream>
00009 
00010 int osl::record::
00011 OPiece::position2Bits(const Square& pos)
00012 {
00013   return pos.isPieceStand() ? 0 : pos.x() << 4 | pos.y(); // 8 bits
00014 }
00015 
00016 osl::Square osl::record::
00017 OPiece::bits2Square(const int bit_position)
00018 {
00019   if ((bit_position & 0xff) == 0)
00020     return Square::STAND();
00021   else
00022     return Square((bit_position >> 4) & 0xf, bit_position & 0xf);
00023 }
00024 
00025 namespace osl
00026 {
00027   namespace record
00028   {
00029 
00030     struct opiece_sort
00031     { 
00032       bool operator()(const OPiece& l, const OPiece& r)
00033       {
00034         // need to special case pieces on stand
00035         if (l.getSquare() == Square::STAND() || r.getSquare() == Square::STAND())
00036           {
00037             if (l.getSquare() == Square::STAND() && r.getSquare() != Square::STAND())
00038               return true;
00039             else if (l.getSquare() != Square::STAND() && r.getSquare() == Square::STAND())
00040               return false;
00041             else
00042               {
00043                 if (l.getOwner() != r.getOwner())
00044                   return l.getOwner() == WHITE;
00045                 return l.getPtype() < r.getPtype();
00046               }
00047           }
00048         else
00049           {
00050             if (l.getSquare().x() < r.getSquare().x())
00051               return true;
00052             else if (l.getSquare().x() > r.getSquare().x())
00053               return false;
00054             else
00055               {
00056                 if (l.getSquare().y() <= r.getSquare().y())
00057                   return true;
00058                 else
00059                   return false;
00060               }
00061           }
00062       }
00063     };
00064   }
00065 }
00066 
00067 osl::record::
00068 CompactBoard::CompactBoard(const SimpleState& state)
00069 {
00070   pieces.reserve(40);
00071   for (int i = 0; i < 40; i++)
00072   {
00073     if(state.usedMask().test(i))
00074       pieces.push_back(OPiece(state.pieceOf(i)));
00075   }
00076   std::sort(pieces.begin(), pieces.end(), opiece_sort());
00077   player_to_move = state.turn();
00078 }
00079 
00080 osl::SimpleState osl::record::
00081 CompactBoard::getState() const
00082 {
00083 
00084   SimpleState state;
00085   state.init();
00086 
00087   BOOST_FOREACH(const OPiece& p, pieces) {
00088     state.setPiece(p.getOwner(), p.getSquare(), p.getPtype());
00089   }
00090   state.setTurn(turn());
00091   state.initPawnMask();
00092   return state;
00093 }
00094 
00095 bool osl::record::
00096 operator==(const CompactBoard& lhs, const CompactBoard& rhs)
00097 {
00098   return (lhs.turn() == rhs.turn()) && (lhs.pieces == rhs.pieces);
00099 }
00100 
00101 std::ostream& osl::record::
00102 operator<<(std::ostream& os, const CompactBoard& c)
00103 {
00104 
00105   for (unsigned int i = 0; i < c.pieces.size(); i++)
00106   {
00107     writeInt(os, static_cast<int>(c.pieces[i]));
00108   }
00109   writeInt(os, static_cast<int>(c.turn()));
00110   return os;
00111 }
00112 
00113 std::istream& osl::record::
00114 operator>>(std::istream& is, CompactBoard& c)
00115 {
00116   assert(c.pieces.size() == 0);
00117 
00118   for (unsigned int i = 0; i < 40; i++)
00119   {
00120     c.pieces.push_back(OPiece(readInt(is)));
00121   }
00122   c.player_to_move = static_cast<Player>(readInt(is));
00123   return is;
00124 }
00125 #ifndef MINIMAL
00126 std::string osl::record::
00127 CompactBoard::toBase64() const
00128 {
00129   const static size_t ninteger = 41;
00130   const static size_t integer_size = 32;
00131   const static size_t size = ninteger*integer_size;
00132 
00133   std::stringstream ss;
00134   ss << *this;
00135 
00136   ss.clear();
00137   ss.seekg(0, std::ios::beg);
00138 
00139   boost::dynamic_bitset<> bits(size);
00140 
00141   for (size_t i = 0; i < ninteger; ++i)
00142   {
00143     const unsigned int tmp = static_cast<unsigned int>(readInt(ss));
00144     const boost::dynamic_bitset<> mask(size, static_cast<unsigned long>(tmp));
00145     bits = (bits << integer_size) | mask;
00146   }
00147 
00148   return misc::base64Encode(bits);
00149 }
00150 
00151 const osl::record::CompactBoard osl::record::
00152 CompactBoard::fromBase64(const std::string& str)
00153 {
00154   const boost::dynamic_bitset<> bits = misc::base64Decode(str);
00155   std::stringstream ss;
00156   assert(bits.size()%32 == 0);
00157   const boost::dynamic_bitset<> mask(bits.size(), 4294967295ul);
00158   for (size_t i=0; i<bits.size()/32; ++i)
00159   {
00160     const unsigned long tmp = ((bits >> ((bits.size()/32-1-i)*32)) & mask).to_ulong();
00161     writeInt(ss, static_cast<int>(tmp));
00162   }
00163       
00164   ss.clear();
00165   ss.seekg(0, std::ios::beg);
00166 
00167   CompactBoard cb;
00168   ss >> cb;
00169   return cb;
00170 }
00171 #endif
00172 
00173 
00174 /* ------------------------------------------------------------------------- */
00175 // ;;; Local Variables:
00176 // ;;; mode:c++
00177 // ;;; c-basic-offset:2
00178 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines