miniBoard.cc
Go to the documentation of this file.
00001 #include "osl/record/record.h"
00002 #include "osl/record/miniBoard.h"
00003 #include "osl/misc/base64.h"
00004 #include <boost/dynamic_bitset.hpp>
00005 #include <iostream>
00006 #include <algorithm>
00007 #include <sstream>
00008 
00009 namespace osl
00010 {
00011   namespace record
00012   {
00013 
00014     struct oposition_sort
00015     { 
00016       bool operator()(const OSquare& l, const OSquare& r)
00017       {
00018         // need to special case pieces on stand
00019         if (l.getSquare() == Square::STAND() || r.getSquare() == Square::STAND())
00020         {
00021           if (l.getSquare() == Square::STAND() && r.getSquare() != Square::STAND())
00022             return true;
00023           else if (l.getSquare() != Square::STAND() && r.getSquare() == Square::STAND())
00024             return false;
00025           else
00026             {
00027               if (l.getOwner() != r.getOwner())
00028                 return l.getOwner() == WHITE;
00029               return true;
00030             }
00031         }
00032         else
00033         {
00034           if (l.getSquare().x() < r.getSquare().x())
00035             return true;
00036           else if (l.getSquare().x() > r.getSquare().x())
00037             return false;
00038           else
00039             {
00040               if (l.getSquare().y() <= r.getSquare().y())
00041                 return true;
00042               else
00043                 return false;
00044             }
00045         }
00046       }
00047     };
00048 
00049     const size_t MiniBoard::total_bits  = 400; 
00050     const size_t OSquare::total_bits  =   9;
00051     const size_t OPSquare::total_bits =  10;
00052 
00053     MiniBoard::MiniBoard(const SimpleState& state)
00054     {
00055       pawn_pieces.reserve(18);
00056       lance_pieces.reserve(4);
00057       knight_pieces.reserve(4);
00058       silver_pieces.reserve(4);
00059       bishop_pieces.reserve(2);
00060       rook_pieces.reserve(2);
00061       gold_pieces.reserve(4);
00062 
00063       for (int i = 0; i < 40; ++i)
00064       {
00065         if(!state.usedMask().test(i)) continue;
00066         const Piece p = state.pieceOf(i);
00067         switch (unpromote(p.ptype()))
00068         {
00069         case PAWN:
00070           pawn_pieces.push_back(OPSquare(p));
00071           break;
00072         case LANCE:
00073           lance_pieces.push_back(OPSquare(p));
00074           break;
00075         case KNIGHT:
00076           knight_pieces.push_back(OPSquare(p));
00077           break;
00078         case SILVER:
00079           silver_pieces.push_back(OPSquare(p));
00080           break;
00081         case BISHOP:
00082           bishop_pieces.push_back(OPSquare(p));
00083           break;
00084         case ROOK:
00085           rook_pieces.push_back(OPSquare(p));
00086           break;
00087         case GOLD:
00088           gold_pieces.push_back(OSquare(p));
00089           break;
00090         case KING:
00091           if (p.owner() == BLACK)
00092             king_pieces[0] = static_cast<char>(OPiece::position2Bits(p.square()));
00093           else
00094             king_pieces[1] = static_cast<char>(OPiece::position2Bits(p.square()));
00095           break;
00096         default:
00097           assert(false);
00098         }
00099       }
00100       turn = state.turn();
00101 
00102       std::sort(pawn_pieces.begin(),   pawn_pieces.end(),   oposition_sort());
00103       std::sort(lance_pieces.begin(),  lance_pieces.end(),  oposition_sort());
00104       std::sort(knight_pieces.begin(), knight_pieces.end(), oposition_sort());
00105       std::sort(silver_pieces.begin(), silver_pieces.end(), oposition_sort());
00106       std::sort(bishop_pieces.begin(), bishop_pieces.end(), oposition_sort());
00107       std::sort(rook_pieces.begin(),   rook_pieces.end(),   oposition_sort());
00108       std::sort(gold_pieces.begin(),   gold_pieces.end(),   oposition_sort());
00109     }
00110 
00111     SimpleState
00112     MiniBoard::getState() const
00113     {
00114       SimpleState state;
00115       state.init();
00116 
00117       for (PawnArray::const_iterator p = pawn_pieces.begin();
00118            p != pawn_pieces.end(); ++p)
00119       {
00120         Ptype ptype = PAWN;
00121         if (p->isPromoted())
00122           ptype = promote(ptype);
00123         state.setPiece(p->getOwner(), p->getSquare(), ptype);
00124       }
00125       for (LanceArray::const_iterator p = lance_pieces.begin();
00126            p != lance_pieces.end(); ++p)
00127       {
00128         Ptype ptype = LANCE;
00129         if (p->isPromoted())
00130           ptype = promote(ptype);
00131         state.setPiece(p->getOwner(), p->getSquare(), ptype);
00132       }
00133       for (KnightArray::const_iterator p = knight_pieces.begin();
00134            p != knight_pieces.end(); ++p)
00135       {
00136         Ptype ptype = KNIGHT;
00137         if (p->isPromoted())
00138           ptype = promote(ptype);
00139         state.setPiece(p->getOwner(), p->getSquare(), ptype);
00140       }
00141       for (SilverArray::const_iterator p = silver_pieces.begin();
00142            p != silver_pieces.end(); ++p)
00143       {
00144         Ptype ptype = SILVER;
00145         if (p->isPromoted())
00146           ptype = promote(ptype);
00147         state.setPiece(p->getOwner(), p->getSquare(), ptype);
00148       }
00149       for (BishopArray::const_iterator p = bishop_pieces.begin();
00150            p != bishop_pieces.end(); ++p)
00151       {
00152         Ptype ptype = BISHOP;
00153         if (p->isPromoted())
00154           ptype = promote(ptype);
00155         state.setPiece(p->getOwner(), p->getSquare(), ptype);
00156       }
00157       for (RookArray::const_iterator p = rook_pieces.begin();
00158            p != rook_pieces.end(); ++p)
00159       {
00160         Ptype ptype = ROOK;
00161         if (p->isPromoted())
00162           ptype = promote(ptype);
00163         state.setPiece(p->getOwner(), p->getSquare(), ptype);
00164       }
00165       for (GoldArray::const_iterator p = gold_pieces.begin();
00166            p != gold_pieces.end(); ++p)
00167       {
00168         state.setPiece(p->getOwner(), p->getSquare(), GOLD);
00169       }
00170       state.setPiece(BLACK, OPiece::bits2Square(king_pieces[0]), KING);
00171       state.setPiece(WHITE, OPiece::bits2Square(king_pieces[1]), KING);
00172       state.setTurn(turn);
00173 
00174       return state;
00175     }
00176 
00177     boost::dynamic_bitset<> 
00178     MiniBoard::toBits() const
00179     {
00180       boost::dynamic_bitset<> bits(total_bits);
00181 
00182       for (PawnArray::const_iterator p = pawn_pieces.begin();
00183            p != pawn_pieces.end(); ++p)
00184       {
00185         const int value = static_cast<int>(*p);
00186         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00187         bits = bits << OPSquare::total_bits | mask;
00188       }
00189       for (LanceArray::const_iterator p = lance_pieces.begin();
00190            p != lance_pieces.end(); ++p)
00191       {
00192         const int value = static_cast<int>(*p);
00193         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00194         bits = bits << OPSquare::total_bits | mask;
00195       }
00196       for (KnightArray::const_iterator p = knight_pieces.begin();
00197            p != knight_pieces.end(); ++p)
00198       {
00199         const int value = static_cast<int>(*p);
00200         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00201         bits = bits << OPSquare::total_bits | mask;
00202       }
00203       for (SilverArray::const_iterator p = silver_pieces.begin();
00204            p != silver_pieces.end(); ++p)
00205       {
00206         const int value = static_cast<int>(*p);
00207         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00208         bits = bits << OPSquare::total_bits | mask;
00209       }
00210       for (BishopArray::const_iterator p = bishop_pieces.begin();
00211            p != bishop_pieces.end(); ++p)
00212       {
00213         const int value = static_cast<int>(*p);
00214         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00215         bits = bits << OPSquare::total_bits | mask;
00216       }
00217       for (RookArray::const_iterator p = rook_pieces.begin();
00218            p != rook_pieces.end(); ++p)
00219       {
00220         const int value = static_cast<int>(*p);
00221         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00222         bits = bits << OPSquare::total_bits | mask;
00223       }
00224       for (GoldArray::const_iterator p = gold_pieces.begin();
00225            p != gold_pieces.end(); ++p)
00226       {
00227         const int value = static_cast<int>(*p);
00228         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00229         bits = bits << OSquare::total_bits | mask;
00230       }
00231       for (KingArray::const_iterator p = king_pieces.begin();
00232            p != king_pieces.end(); ++p)
00233       {
00234         const char value = static_cast<char>(*p);
00235         const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00236         bits = bits << 8 | mask;
00237       }
00238       
00239       unsigned long value = 0;
00240       if (turn == BLACK)
00241         value = 0;
00242       else
00243         value = 1;
00244       const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00245       bits = bits << 8 | mask;
00246 
00247       return bits;
00248     }
00249 
00250     std::string 
00251     MiniBoard::toBase64() const
00252     {
00253       const boost::dynamic_bitset<> bits = toBits();
00254       return misc::base64Encode(bits);
00255     }
00256 
00257     int fromBase64(const std::string& base64, MiniBoard& mb)
00258     {
00259       const boost::dynamic_bitset<> bits = misc::base64Decode(base64);
00260       if (bits.size() == 0)
00261         return 1;
00262       assert(bits.size() == MiniBoard::total_bits);
00263 
00264       for (int i=0; i<18; ++i)
00265       {
00266         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00267         const unsigned long value = 
00268           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+1)) 
00269            & mask).to_ulong();
00270         const OPSquare p(static_cast<int>(value));
00271         mb.pawn_pieces.push_back(p);
00272       }
00273       for (int i=0; i<4; ++i)
00274       {
00275         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00276         const unsigned long value = 
00277           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+19)) 
00278            & mask).to_ulong();
00279         const OPSquare p(static_cast<int>(value));
00280         mb.lance_pieces.push_back(p);
00281       }
00282       for (int i=0; i<4; ++i)
00283       {
00284         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00285         const unsigned long value = 
00286           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+23)) 
00287            & mask).to_ulong();
00288         const OPSquare p(static_cast<int>(value));
00289         mb.knight_pieces.push_back(p);
00290       }
00291       for (int i=0; i<4; ++i)
00292       {
00293         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00294         const unsigned long value = 
00295           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+27)) 
00296            & mask).to_ulong();
00297         const OPSquare p(static_cast<int>(value));
00298         mb.silver_pieces.push_back(p);
00299       }
00300       for (int i=0; i<2; ++i)
00301       {
00302         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00303         const unsigned long value = 
00304           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+31)) 
00305            & mask).to_ulong();
00306         const OPSquare p(static_cast<int>(value));
00307         mb.bishop_pieces.push_back(p);
00308       }
00309       for (int i=0; i<2; ++i)
00310       {
00311         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00312         const unsigned long value = 
00313           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+33)) 
00314            & mask).to_ulong();
00315         const OPSquare p(static_cast<int>(value));
00316         mb.rook_pieces.push_back(p);
00317       }
00318       for (int i=0; i<4; ++i)
00319       {
00320         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 511ul);
00321         const unsigned long value = 
00322           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*34 - OSquare::total_bits*(i+1)) & mask).to_ulong();
00323         const OSquare p(static_cast<int>(value));
00324         mb.gold_pieces.push_back(p);
00325       }
00326       for (int i=0; i<2; ++i)
00327       {
00328         const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 255ul);
00329         const unsigned long value = 
00330           (bits >> (MiniBoard::total_bits - OPSquare::total_bits*34 - OSquare::total_bits*4 - 8*(i+1)) & mask).to_ulong();
00331         mb.king_pieces[i] = static_cast<char>(value);
00332       }
00333       const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 255ul);
00334       const unsigned long value = (bits & mask).to_ulong();
00335       if ((value&1) == 0)
00336         mb.turn = BLACK;
00337       else
00338         mb.turn = WHITE;
00339       return 0;
00340     }
00341   } // namespace record
00342 } // namespace osl
00343 
00344 /* ------------------------------------------------------------------------- */
00345 // ;;; Local Variables:
00346 // ;;; mode:c++
00347 // ;;; c-basic-offset:2
00348 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines