00001 #include "osl/record/record.h"
00002 #include "osl/book/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 book
00012 {
00013
00014 struct oposition_sort
00015 {
00016 bool operator()(const OSquare& l, const OSquare& r)
00017 {
00018
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 }
00342 }
00343
00344
00345
00346
00347
00348