miniBoard.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
miniBoard.cc
Go to the documentation of this file.
1 #include "osl/record/record.h"
2 #include "osl/record/miniBoard.h"
3 #include "osl/misc/base64.h"
4 #include <boost/dynamic_bitset.hpp>
5 #include <iostream>
6 #include <algorithm>
7 #include <sstream>
8
9 namespace osl
10 {
11 namespace record
12 {
13
14 struct oposition_sort
15 {
16 bool operator()(const OSquare& l, const OSquare& r)
17 {
18 // need to special case pieces on stand
19 if (l.getSquare() == Square::STAND() || r.getSquare() == Square::STAND())
20 {
21 if (l.getSquare() == Square::STAND() && r.getSquare() != Square::STAND())
22 return true;
23 else if (l.getSquare() != Square::STAND() && r.getSquare() == Square::STAND())
24 return false;
25 else
26 {
27 if (l.getOwner() != r.getOwner())
28 return l.getOwner() == WHITE;
29 return true;
30 }
31 }
32 else
33 {
34 if (l.getSquare().x() < r.getSquare().x())
35 return true;
36 else if (l.getSquare().x() > r.getSquare().x())
37 return false;
38 else
39 {
40 if (l.getSquare().y() <= r.getSquare().y())
41 return true;
42 else
43 return false;
44 }
45 }
46 }
47 };
48
49 const size_t MiniBoard::total_bits = 400;
50 const size_t OSquare::total_bits = 9;
51 const size_t OPSquare::total_bits = 10;
52
53 MiniBoard::MiniBoard(const SimpleState& state)
54 {
55 pawn_pieces.reserve(18);
56 lance_pieces.reserve(4);
57 knight_pieces.reserve(4);
58 silver_pieces.reserve(4);
59 bishop_pieces.reserve(2);
60 rook_pieces.reserve(2);
61 gold_pieces.reserve(4);
62
63 for (int i = 0; i < 40; ++i)
64 {
65 if(!state.usedMask().test(i)) continue;
66 const Piece p = state.pieceOf(i);
67 switch (unpromote(p.ptype()))
68 {
69 case PAWN:
70 pawn_pieces.push_back(OPSquare(p));
71 break;
72 case LANCE:
73 lance_pieces.push_back(OPSquare(p));
74 break;
75 case KNIGHT:
76 knight_pieces.push_back(OPSquare(p));
77 break;
78 case SILVER:
79 silver_pieces.push_back(OPSquare(p));
80 break;
81 case BISHOP:
82 bishop_pieces.push_back(OPSquare(p));
83 break;
84 case ROOK:
85 rook_pieces.push_back(OPSquare(p));
86 break;
87 case GOLD:
88 gold_pieces.push_back(OSquare(p));
89 break;
90 case KING:
91 if (p.owner() == BLACK)
92 king_pieces[0] = static_cast<char>(OPiece::position2Bits(p.square()));
93 else
94 king_pieces[1] = static_cast<char>(OPiece::position2Bits(p.square()));
95 break;
96 default:
97 assert(false);
98 }
99 }
100 turn = state.turn();
101
102 std::sort(pawn_pieces.begin(), pawn_pieces.end(), oposition_sort());
103 std::sort(lance_pieces.begin(), lance_pieces.end(), oposition_sort());
104 std::sort(knight_pieces.begin(), knight_pieces.end(), oposition_sort());
105 std::sort(silver_pieces.begin(), silver_pieces.end(), oposition_sort());
106 std::sort(bishop_pieces.begin(), bishop_pieces.end(), oposition_sort());
107 std::sort(rook_pieces.begin(), rook_pieces.end(), oposition_sort());
108 std::sort(gold_pieces.begin(), gold_pieces.end(), oposition_sort());
109 }
110
111 SimpleState
112 MiniBoard::getState() const
113 {
114 SimpleState state;
115 state.init();
116
117 for (PawnArray::const_iterator p = pawn_pieces.begin();
118 p != pawn_pieces.end(); ++p)
119 {
120 Ptype ptype = PAWN;
121 if (p->isPromoted())
122 ptype = promote(ptype);
123 state.setPiece(p->getOwner(), p->getSquare(), ptype);
124 }
125 for (LanceArray::const_iterator p = lance_pieces.begin();
126 p != lance_pieces.end(); ++p)
127 {
128 Ptype ptype = LANCE;
129 if (p->isPromoted())
130 ptype = promote(ptype);
131 state.setPiece(p->getOwner(), p->getSquare(), ptype);
132 }
133 for (KnightArray::const_iterator p = knight_pieces.begin();
134 p != knight_pieces.end(); ++p)
135 {
136 Ptype ptype = KNIGHT;
137 if (p->isPromoted())
138 ptype = promote(ptype);
139 state.setPiece(p->getOwner(), p->getSquare(), ptype);
140 }
141 for (SilverArray::const_iterator p = silver_pieces.begin();
142 p != silver_pieces.end(); ++p)
143 {
144 Ptype ptype = SILVER;
145 if (p->isPromoted())
146 ptype = promote(ptype);
147 state.setPiece(p->getOwner(), p->getSquare(), ptype);
148 }
149 for (BishopArray::const_iterator p = bishop_pieces.begin();
150 p != bishop_pieces.end(); ++p)
151 {
152 Ptype ptype = BISHOP;
153 if (p->isPromoted())
154 ptype = promote(ptype);
155 state.setPiece(p->getOwner(), p->getSquare(), ptype);
156 }
157 for (RookArray::const_iterator p = rook_pieces.begin();
158 p != rook_pieces.end(); ++p)
159 {
160 Ptype ptype = ROOK;
161 if (p->isPromoted())
162 ptype = promote(ptype);
163 state.setPiece(p->getOwner(), p->getSquare(), ptype);
164 }
165 for (GoldArray::const_iterator p = gold_pieces.begin();
166 p != gold_pieces.end(); ++p)
167 {
168 state.setPiece(p->getOwner(), p->getSquare(), GOLD);
169 }
170 state.setPiece(BLACK, OPiece::bits2Square(king_pieces[0]), KING);
171 state.setPiece(WHITE, OPiece::bits2Square(king_pieces[1]), KING);
172 state.setTurn(turn);
173
174 return state;
175 }
176
177 boost::dynamic_bitset<>
178 MiniBoard::toBits() const
179 {
180 boost::dynamic_bitset<> bits(total_bits);
181
182 for (PawnArray::const_iterator p = pawn_pieces.begin();
183 p != pawn_pieces.end(); ++p)
184 {
185 const int value = static_cast<int>(*p);
186 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
187 bits = bits << OPSquare::total_bits | mask;
188 }
189 for (LanceArray::const_iterator p = lance_pieces.begin();
190 p != lance_pieces.end(); ++p)
191 {
192 const int value = static_cast<int>(*p);
193 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
194 bits = bits << OPSquare::total_bits | mask;
195 }
196 for (KnightArray::const_iterator p = knight_pieces.begin();
197 p != knight_pieces.end(); ++p)
198 {
199 const int value = static_cast<int>(*p);
200 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
201 bits = bits << OPSquare::total_bits | mask;
202 }
203 for (SilverArray::const_iterator p = silver_pieces.begin();
204 p != silver_pieces.end(); ++p)
205 {
206 const int value = static_cast<int>(*p);
207 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
208 bits = bits << OPSquare::total_bits | mask;
209 }
210 for (BishopArray::const_iterator p = bishop_pieces.begin();
211 p != bishop_pieces.end(); ++p)
212 {
213 const int value = static_cast<int>(*p);
214 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
215 bits = bits << OPSquare::total_bits | mask;
216 }
217 for (RookArray::const_iterator p = rook_pieces.begin();
218 p != rook_pieces.end(); ++p)
219 {
220 const int value = static_cast<int>(*p);
221 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
222 bits = bits << OPSquare::total_bits | mask;
223 }
224 for (GoldArray::const_iterator p = gold_pieces.begin();
225 p != gold_pieces.end(); ++p)
226 {
227 const int value = static_cast<int>(*p);
228 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
229 bits = bits << OSquare::total_bits | mask;
230 }
231 for (KingArray::const_iterator p = king_pieces.begin();
232 p != king_pieces.end(); ++p)
233 {
234 const char value = static_cast<char>(*p);
235 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
236 bits = bits << 8 | mask;
237 }
238
239 unsigned long value = 0;
240 if (turn == BLACK)
241 value = 0;
242 else
243 value = 1;
244 const boost::dynamic_bitset<> mask(total_bits, static_cast<unsigned long>(value));
245 bits = bits << 8 | mask;
246
247 return bits;
248 }
249
250 std::string
251 MiniBoard::toBase64() const
252 {
253 const boost::dynamic_bitset<> bits = toBits();
254 return misc::base64Encode(bits);
255 }
256
257 int fromBase64(const std::string& base64, MiniBoard& mb)
258 {
259 const boost::dynamic_bitset<> bits = misc::base64Decode(base64);
260 if (bits.size() == 0)
261 return 1;
262 assert(bits.size() == MiniBoard::total_bits);
263
264 for (int i=0; i<18; ++i)
265 {
266 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
267 const unsigned long value =
268 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+1))
269 & mask).to_ulong();
270 const OPSquare p(static_cast<int>(value));
271 mb.pawn_pieces.push_back(p);
272 }
273 for (int i=0; i<4; ++i)
274 {
275 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
276 const unsigned long value =
277 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+19))
278 & mask).to_ulong();
279 const OPSquare p(static_cast<int>(value));
280 mb.lance_pieces.push_back(p);
281 }
282 for (int i=0; i<4; ++i)
283 {
284 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
285 const unsigned long value =
286 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+23))
287 & mask).to_ulong();
288 const OPSquare p(static_cast<int>(value));
289 mb.knight_pieces.push_back(p);
290 }
291 for (int i=0; i<4; ++i)
292 {
293 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
294 const unsigned long value =
295 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+27))
296 & mask).to_ulong();
297 const OPSquare p(static_cast<int>(value));
298 mb.silver_pieces.push_back(p);
299 }
300 for (int i=0; i<2; ++i)
301 {
302 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
303 const unsigned long value =
304 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+31))
305 & mask).to_ulong();
306 const OPSquare p(static_cast<int>(value));
307 mb.bishop_pieces.push_back(p);
308 }
309 for (int i=0; i<2; ++i)
310 {
311 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 1023ul);
312 const unsigned long value =
313 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*(i+33))
314 & mask).to_ulong();
315 const OPSquare p(static_cast<int>(value));
316 mb.rook_pieces.push_back(p);
317 }
318 for (int i=0; i<4; ++i)
319 {
320 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 511ul);
321 const unsigned long value =
322 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*34 - OSquare::total_bits*(i+1)) & mask).to_ulong();
323 const OSquare p(static_cast<int>(value));
324 mb.gold_pieces.push_back(p);
325 }
326 for (int i=0; i<2; ++i)
327 {
328 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 255ul);
329 const unsigned long value =
330 (bits >> (MiniBoard::total_bits - OPSquare::total_bits*34 - OSquare::total_bits*4 - 8*(i+1)) & mask).to_ulong();
331 mb.king_pieces[i] = static_cast<char>(value);
332 }
333 const boost::dynamic_bitset<> mask(MiniBoard::total_bits, 255ul);
334 const unsigned long value = (bits & mask).to_ulong();
335 if ((value&1) == 0)
336 mb.turn = BLACK;
337 else
338 mb.turn = WHITE;
339 return 0;
340 }
341 } // namespace record
342 } // namespace osl
343
344 /* ------------------------------------------------------------------------- */
345 // ;;; Local Variables:
346 // ;;; mode:c++
347 // ;;; c-basic-offset:2
348 // ;;; End: