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 OPosition& l, const OPosition& r)
00017 {
00018
00019 if (l.getPosition() == Position::STAND() || r.getPosition() == Position::STAND())
00020 {
00021 if (l.getPosition() == Position::STAND() && r.getPosition() != Position::STAND())
00022 return true;
00023 else if (l.getPosition() != Position::STAND() && r.getPosition() == Position::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.getPosition().x() < r.getPosition().x())
00035 return true;
00036 else if (l.getPosition().x() > r.getPosition().x())
00037 return false;
00038 else
00039 {
00040 if (l.getPosition().y() <= r.getPosition().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 OPosition::total_bits = 9;
00051 const size_t OPPosition::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 const Piece p = state.getPieceOf(i);
00066 switch (unpromote(p.ptype()))
00067 {
00068 case PAWN:
00069 pawn_pieces.push_back(OPPosition(p));
00070 break;
00071 case LANCE:
00072 lance_pieces.push_back(OPPosition(p));
00073 break;
00074 case KNIGHT:
00075 knight_pieces.push_back(OPPosition(p));
00076 break;
00077 case SILVER:
00078 silver_pieces.push_back(OPPosition(p));
00079 break;
00080 case BISHOP:
00081 bishop_pieces.push_back(OPPosition(p));
00082 break;
00083 case ROOK:
00084 rook_pieces.push_back(OPPosition(p));
00085 break;
00086 case GOLD:
00087 gold_pieces.push_back(OPosition(p));
00088 break;
00089 case KING:
00090 if (p.owner() == BLACK)
00091 king_pieces[0] = static_cast<char>(OPiece::position2Bits(p.position()));
00092 else
00093 king_pieces[1] = static_cast<char>(OPiece::position2Bits(p.position()));
00094 break;
00095 default:
00096 assert(false);
00097 }
00098 }
00099 turn = state.getTurn();
00100
00101 std::sort(pawn_pieces.begin(), pawn_pieces.end(), oposition_sort());
00102 std::sort(lance_pieces.begin(), lance_pieces.end(), oposition_sort());
00103 std::sort(knight_pieces.begin(), knight_pieces.end(), oposition_sort());
00104 std::sort(silver_pieces.begin(), silver_pieces.end(), oposition_sort());
00105 std::sort(bishop_pieces.begin(), bishop_pieces.end(), oposition_sort());
00106 std::sort(rook_pieces.begin(), rook_pieces.end(), oposition_sort());
00107 std::sort(gold_pieces.begin(), gold_pieces.end(), oposition_sort());
00108 }
00109
00110 SimpleState
00111 MiniBoard::getState() const
00112 {
00113 SimpleState state;
00114 state.init();
00115
00116 for (PawnArray::const_iterator p = pawn_pieces.begin();
00117 p != pawn_pieces.end(); ++p)
00118 {
00119 Ptype ptype = PAWN;
00120 if (p->isPromoted())
00121 ptype = promote(ptype);
00122 state.setPiece(p->getOwner(), p->getPosition(), ptype);
00123 }
00124 for (LanceArray::const_iterator p = lance_pieces.begin();
00125 p != lance_pieces.end(); ++p)
00126 {
00127 Ptype ptype = LANCE;
00128 if (p->isPromoted())
00129 ptype = promote(ptype);
00130 state.setPiece(p->getOwner(), p->getPosition(), ptype);
00131 }
00132 for (KnightArray::const_iterator p = knight_pieces.begin();
00133 p != knight_pieces.end(); ++p)
00134 {
00135 Ptype ptype = KNIGHT;
00136 if (p->isPromoted())
00137 ptype = promote(ptype);
00138 state.setPiece(p->getOwner(), p->getPosition(), ptype);
00139 }
00140 for (SilverArray::const_iterator p = silver_pieces.begin();
00141 p != silver_pieces.end(); ++p)
00142 {
00143 Ptype ptype = SILVER;
00144 if (p->isPromoted())
00145 ptype = promote(ptype);
00146 state.setPiece(p->getOwner(), p->getPosition(), ptype);
00147 }
00148 for (BishopArray::const_iterator p = bishop_pieces.begin();
00149 p != bishop_pieces.end(); ++p)
00150 {
00151 Ptype ptype = BISHOP;
00152 if (p->isPromoted())
00153 ptype = promote(ptype);
00154 state.setPiece(p->getOwner(), p->getPosition(), ptype);
00155 }
00156 for (RookArray::const_iterator p = rook_pieces.begin();
00157 p != rook_pieces.end(); ++p)
00158 {
00159 Ptype ptype = ROOK;
00160 if (p->isPromoted())
00161 ptype = promote(ptype);
00162 state.setPiece(p->getOwner(), p->getPosition(), ptype);
00163 }
00164 for (GoldArray::const_iterator p = gold_pieces.begin();
00165 p != gold_pieces.end(); ++p)
00166 {
00167 state.setPiece(p->getOwner(), p->getPosition(), GOLD);
00168 }
00169 state.setPiece(BLACK, OPiece::bits2Position(king_pieces[0]), KING);
00170 state.setPiece(WHITE, OPiece::bits2Position(king_pieces[1]), KING);
00171 state.setTurn(turn);
00172
00173 return state;
00174 }
00175
00176 boost::dynamic_bitset<>
00177 MiniBoard::toBits() const
00178 {
00179 boost::dynamic_bitset<> bits(total_bits);
00180
00181 for (PawnArray::const_iterator p = pawn_pieces.begin();
00182 p != pawn_pieces.end(); ++p)
00183 {
00184 const int value = static_cast<int>(*p);
00185 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00186 bits = bits << OPPosition::total_bits | mask;
00187 }
00188 for (LanceArray::const_iterator p = lance_pieces.begin();
00189 p != lance_pieces.end(); ++p)
00190 {
00191 const int value = static_cast<int>(*p);
00192 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00193 bits = bits << OPPosition::total_bits | mask;
00194 }
00195 for (KnightArray::const_iterator p = knight_pieces.begin();
00196 p != knight_pieces.end(); ++p)
00197 {
00198 const int value = static_cast<int>(*p);
00199 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00200 bits = bits << OPPosition::total_bits | mask;
00201 }
00202 for (SilverArray::const_iterator p = silver_pieces.begin();
00203 p != silver_pieces.end(); ++p)
00204 {
00205 const int value = static_cast<int>(*p);
00206 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00207 bits = bits << OPPosition::total_bits | mask;
00208 }
00209 for (BishopArray::const_iterator p = bishop_pieces.begin();
00210 p != bishop_pieces.end(); ++p)
00211 {
00212 const int value = static_cast<int>(*p);
00213 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00214 bits = bits << OPPosition::total_bits | mask;
00215 }
00216 for (RookArray::const_iterator p = rook_pieces.begin();
00217 p != rook_pieces.end(); ++p)
00218 {
00219 const int value = static_cast<int>(*p);
00220 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00221 bits = bits << OPPosition::total_bits | mask;
00222 }
00223 for (GoldArray::const_iterator p = gold_pieces.begin();
00224 p != gold_pieces.end(); ++p)
00225 {
00226 const int value = static_cast<int>(*p);
00227 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00228 bits = bits << OPosition::total_bits | mask;
00229 }
00230 for (KingArray::const_iterator p = king_pieces.begin();
00231 p != king_pieces.end(); ++p)
00232 {
00233 const char value = static_cast<char>(*p);
00234 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00235 bits = bits << 8 | mask;
00236 }
00237
00238 unsigned long value = 0;
00239 if (turn == BLACK)
00240 value = 0;
00241 else
00242 value = 1;
00243 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
00244 bits = bits << 8 | mask;
00245
00246 return bits;
00247 }
00248
00249 std::string
00250 MiniBoard::toBase64() const
00251 {
00252 const boost::dynamic_bitset<> bits = toBits();
00253 return misc::base64Encode(bits);
00254 }
00255
00256 int fromBase64(const std::string& base64, MiniBoard& mb)
00257 {
00258 const boost::dynamic_bitset<> bits = misc::base64Decode(base64);
00259 if (bits.size() == 0)
00260 return 1;
00261 assert(bits.size() == MiniBoard::total_bits);
00262
00263 for (int i=0; i<18; ++i)
00264 {
00265 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00266 const unsigned long value =
00267 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*(i+1))
00268 & mask).to_ulong();
00269 const OPPosition p(static_cast<int>(value));
00270 mb.pawn_pieces.push_back(p);
00271 }
00272 for (int i=0; i<4; ++i)
00273 {
00274 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00275 const unsigned long value =
00276 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*(i+19))
00277 & mask).to_ulong();
00278 const OPPosition p(static_cast<int>(value));
00279 mb.lance_pieces.push_back(p);
00280 }
00281 for (int i=0; i<4; ++i)
00282 {
00283 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00284 const unsigned long value =
00285 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*(i+23))
00286 & mask).to_ulong();
00287 const OPPosition p(static_cast<int>(value));
00288 mb.knight_pieces.push_back(p);
00289 }
00290 for (int i=0; i<4; ++i)
00291 {
00292 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00293 const unsigned long value =
00294 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*(i+27))
00295 & mask).to_ulong();
00296 const OPPosition p(static_cast<int>(value));
00297 mb.silver_pieces.push_back(p);
00298 }
00299 for (int i=0; i<2; ++i)
00300 {
00301 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00302 const unsigned long value =
00303 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*(i+31))
00304 & mask).to_ulong();
00305 const OPPosition p(static_cast<int>(value));
00306 mb.bishop_pieces.push_back(p);
00307 }
00308 for (int i=0; i<2; ++i)
00309 {
00310 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
00311 const unsigned long value =
00312 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*(i+33))
00313 & mask).to_ulong();
00314 const OPPosition p(static_cast<int>(value));
00315 mb.rook_pieces.push_back(p);
00316 }
00317 for (int i=0; i<4; ++i)
00318 {
00319 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 511ul);
00320 const unsigned long value =
00321 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*34 - OPosition::total_bits*(i+1)) & mask).to_ulong();
00322 const OPosition p(static_cast<int>(value));
00323 mb.gold_pieces.push_back(p);
00324 }
00325 for (int i=0; i<2; ++i)
00326 {
00327 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 255ul);
00328 const unsigned long value =
00329 (bits >> (MiniBoard::total_bits - OPPosition::total_bits*34 - OPosition::total_bits*4 - 8*(i+1)) & mask).to_ulong();
00330 mb.king_pieces[i] = static_cast<char>(value);
00331 }
00332 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 255ul);
00333 const unsigned long value = (bits & mask).to_ulong();
00334 if ((value&1) == 0)
00335 mb.turn = BLACK;
00336 else
00337 mb.turn = WHITE;
00338 return 0;
00339 }
00340 }
00341 }
00342
00343
00344
00345
00346
00347