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 
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
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<>
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
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: