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 Position& pos)
00012 {
00013 return pos.isPieceStand() ? 0 : pos.x() << 4 | pos.y();
00014 }
00015
00016 osl::Position osl::record::
00017 OPiece::bits2Position(const int bit_position)
00018 {
00019 if ((bit_position & 0xff) == 0)
00020 return Position::STAND();
00021 else
00022 return Position((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
00035 if (l.getPosition() == Position::STAND() || r.getPosition() == Position::STAND())
00036 {
00037 if (l.getPosition() == Position::STAND() && r.getPosition() != Position::STAND())
00038 return true;
00039 else if (l.getPosition() != Position::STAND() && r.getPosition() == Position::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.getPosition().x() < r.getPosition().x())
00051 return true;
00052 else if (l.getPosition().x() > r.getPosition().x())
00053 return false;
00054 else
00055 {
00056 if (l.getPosition().y() <= r.getPosition().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 pieces.push_back(OPiece(state.getPieceOf(i)));
00074 }
00075 std::sort(pieces.begin(), pieces.end(), opiece_sort());
00076 turn = state.getTurn();
00077 }
00078
00079 osl::SimpleState osl::record::
00080 CompactBoard::getState() const
00081 {
00082 assert(pieces.size() == 40);
00083
00084 SimpleState state;
00085 state.init();
00086
00087 BOOST_FOREACH(const OPiece& p, pieces) {
00088 state.setPiece(p.getOwner(), p.getPosition(), 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 assert(c.pieces.size() == 40);
00105
00106 for (unsigned int i = 0; i < c.pieces.size(); i++)
00107 {
00108 writeInt(os, static_cast<int>(c.pieces[i]));
00109 }
00110 writeInt(os, static_cast<int>(c.turn));
00111 return os;
00112 }
00113
00114 std::istream& osl::record::
00115 operator>>(std::istream& is, CompactBoard& c)
00116 {
00117 assert(c.pieces.size() == 0);
00118
00119 for (unsigned int i = 0; i < 40; i++)
00120 {
00121 c.pieces.push_back(OPiece(readInt(is)));
00122 }
00123 c.turn = static_cast<Player>(readInt(is));
00124 return is;
00125 }
00126 #ifndef MINIMAL
00127 std::string osl::record::
00128 CompactBoard::toBase64() const
00129 {
00130 const static size_t ninteger = 41;
00131 const static size_t integer_size = 32;
00132 const static size_t size = ninteger*integer_size;
00133
00134 std::stringstream ss;
00135 ss << *this;
00136
00137 ss.clear();
00138 ss.seekg(0, std::ios::beg);
00139
00140 boost::dynamic_bitset<> bits(size);
00141
00142 for (size_t i = 0; i < ninteger; ++i)
00143 {
00144 const unsigned int tmp = static_cast<unsigned int>(readInt(ss));
00145 const boost::dynamic_bitset<> mask(size, static_cast<unsigned long>(tmp));
00146 bits = (bits << integer_size) | mask;
00147 }
00148
00149 return misc::base64Encode(bits);
00150 }
00151
00152 const osl::record::CompactBoard osl::record::
00153 CompactBoard::fromBase64(const std::string& str)
00154 {
00155 const boost::dynamic_bitset<> bits = misc::base64Decode(str);
00156 std::stringstream ss;
00157 assert(bits.size()%32 == 0);
00158 const boost::dynamic_bitset<> mask(bits.size(), 4294967295ul);
00159 for (size_t i=0; i<bits.size()/32; ++i)
00160 {
00161 const unsigned long tmp = ((bits >> ((bits.size()/32-1-i)*32)) & mask).to_ulong();
00162 writeInt(ss, static_cast<int>(tmp));
00163 }
00164
00165 ss.clear();
00166 ss.seekg(0, std::ios::beg);
00167
00168 CompactBoard cb;
00169 ss >> cb;
00170 return cb;
00171 }
00172 #endif
00173
00174
00175
00176
00177
00178
00179