My Project
bits/pieceStand.h
Go to the documentation of this file.
1 /* pieceStand.h
2  */
3 #ifndef OSL_PIECESTAND_H
4 #define OSL_PIECESTAND_H
5 #include "osl/basic_type.h"
6 #include "osl/container.h"
7 #include <iosfwd>
8 #include <cassert>
9 namespace osl
10 {
11  class SimpleState;
37  class PieceStand
38  {
39  public:
41  static const CArray<Ptype,7> order;
42  static const unsigned int carryMask = 0x48822224;
43  private:
46  mutable unsigned int flags;
47  public:
48  explicit PieceStand(unsigned int value=0) : flags(value)
49  {
50  }
51  explicit PieceStand(Player, const SimpleState&);
52  PieceStand(int pawnCount, int lanceCount,
53  int knightCount, int silverCount,
54  int goldCount, int bishopCount,
55  int rookCount, int kingCount)
56  : flags(0)
57  {
58  add(PAWN, pawnCount);
59  add(LANCE, lanceCount);
60  add(KNIGHT, knightCount);
61  add(SILVER, silverCount);
62  add(GOLD, goldCount);
63  add(BISHOP, bishopCount);
64  add(ROOK, rookCount);
65  add(KING, kingCount);
66  }
67 
68  void add(Ptype type, unsigned int num=1)
69  {
70  assert(isBasic(type));
71  assert(num == (num & mask[type]));
72  flags += (num << (shift[type]));
73  assert(testCarries() == 0); // overflow 検出
74  }
75  void sub(Ptype type, unsigned int num=1)
76  {
77  assert(isBasic(type));
78  assert(num == (num & mask[type]));
79  assert(get(type) >= num);
80  flags -= (num << (shift[type]));
81  }
82 
87  void tryAdd(Ptype type);
88  bool canAdd(Ptype type) const;
92  void trySub(Ptype type)
93  {
94  if (get(type))
95  sub(type);
96  }
97 
101  bool atMostOneKind() const;
102 
108  void addAtmostOnePiece(PieceStand const& ps){
109 #ifndef NDEBUG
110  const PieceStand copy(*this);
111 #endif
112  assert(! ps.testCarries());
113  assert(ps.atMostOneKind());
114  flags += ps.getFlags();
115  assert(carryUnchangedAfterAdd(copy, ps));
116  }
117 
118  void subAtmostOnePiece(PieceStand const& ps){
119 #ifndef NDEBUG
120  const PieceStand copy(*this);
121 #endif
122  assert(! ps.testCarries());
123  assert(ps.atMostOneKind());
124  flags -= ps.getFlags();
125  assert(carryUnchangedAfterSub(copy, ps));
126  }
127  private:
128  bool carryUnchangedAfterAdd(const PieceStand& original, const PieceStand& other) const;
129  bool carryUnchangedAfterSub(const PieceStand& original, const PieceStand& other) const;
130  public:
131  unsigned int get(Ptype type) const
132  {
133  return (flags >> (shift[type])) & mask[type];
134  }
135  void carriesOff() const { flags &= (~carryMask); }
136  void carriesOn() const { flags |= carryMask; }
137  unsigned int testCarries() const { return (flags & carryMask); }
138  bool isSuperiorOrEqualTo(PieceStand other) const
139  {
140  carriesOn();
141  other.carriesOff();
142  const bool result = (((flags - other.flags) & carryMask) == carryMask);
143  carriesOff();
144  return result;
145  }
150  template <Player P>
151  bool hasMoreThan(PieceStand other) const
152  {
153  if (P == BLACK)
154  return isSuperiorOrEqualTo(other);
155  else
156  return other.isSuperiorOrEqualTo(*this);
157  }
158  bool hasMoreThan(Player P, PieceStand other) const
159  {
160  if (P == BLACK)
161  return hasMoreThan<BLACK>(other);
162  else
163  return hasMoreThan<WHITE>(other);
164  }
165  unsigned int getFlags() const { return flags; }
167  bool any() const { return flags; }
171  const PieceStand max(PieceStand other) const
172  {
173  // other以上の数持っているptypeに対応するcarryが1になる.
174  const unsigned int mask0 = ((flags|carryMask)-other.flags) & carryMask;
175  // ROOK BISHOP KING用のMASKを作る
176  unsigned int my_mask = mask0-((mask0&0x40000024)>>2);
177  // GOLD SILVER KNIGHT LANCE用のMASKを作る
178  my_mask -= (mask0&0x08022200)>>3;
179  // PAWN用のMASKのみ残す
180  my_mask -= (mask0&0x00800000)>>5;
181  // my_mask が1のptypeの数は自分から,0のptypeはotherのところの値を
182  return PieceStand((flags&my_mask)|(other.flags&~my_mask));
183  }
187  const PieceStand max2(PieceStand other) const
188  {
189  // other以上の数持っているptypeに対応するcarryが1になる.
190  const unsigned int diff0=((flags|carryMask)-other.flags);
191  const unsigned int mask0=diff0&carryMask;
192 
193  // ROOK BISHOP KING GOLD SILVER KNIGHT LANCE用のMASKを作る
194  const unsigned int mask02=(mask0&0x40000024u)+(mask0&0x48022224u);
195  unsigned int my_mask=mask0-(mask02>>3);
196 
197  // PAWN用のMASKのみ残す
198  my_mask -= (mask0&0x00800000)>>5;
199  // my_mask が1のptypeの数は自分から,0のptypeはotherのところの値を
200  return PieceStand((other.flags+(diff0&my_mask))&~carryMask);
201  }
202 
203  const PieceStand nextStand(Player pl, Move move) const
204  {
205  assert(move.isNormal());
206  PieceStand result = *this;
207  if (move.player() == pl)
208  {
209  if (const Ptype ptype = move.capturePtype())
210  {
211  result.add(unpromote(ptype));
212  }
213  else if (move.isDrop())
214  {
215  const Ptype ptype = move.ptype();
216  assert(get(ptype));
217  result.sub(ptype);
218  }
219  }
220  return result;
221  }
222  const PieceStand nextStand(Move move) const
223  {
224  return nextStand(move.player(), move);
225  }
226  const PieceStand previousStand(Player pl, Move move) const
227  {
228  assert(move.isNormal());
229  PieceStand result = *this;
230  if (move.player() == pl)
231  {
232  if (const Ptype ptype = move.capturePtype())
233  {
234  const Ptype before = unpromote(ptype);
235  assert(get(before));
236  result.sub(before);
237  }
238  else if (move.isDrop())
239  {
240  const Ptype ptype = move.ptype();
241  result.add(ptype);
242  }
243  }
244  return result;
245  }
246  const PieceStand previousStand(Move move) const
247  {
248  return previousStand(move.player(), move);
249  }
250  };
251 
252  inline bool operator==(PieceStand l, PieceStand r)
253  {
254  assert(! l.testCarries());
255  assert(! r.testCarries());
256  return l.getFlags() == r.getFlags();
257  }
258  inline bool operator!=(PieceStand l, PieceStand r)
259  {
260  return ! (l == r);
261  }
262  inline bool operator<(PieceStand l, PieceStand r)
263  {
264  assert(! l.testCarries());
265  assert(! r.testCarries());
266  return l.getFlags() < r.getFlags();
267  }
268  std::ostream& operator<<(std::ostream&, PieceStand l);
269 
271  {
275  static std::ostream& writeNumbers(std::ostream&, const PieceStand& stand);
276  static std::istream& readNumbers(std::istream&, PieceStand& stand);
277  };
278 } // namespace osl
279 
280 #endif /* OSL_PIECESTAND_H */
281 // ;;; Local Variables:
282 // ;;; mode:c++
283 // ;;; c-basic-offset:2
284 // ;;; End:
osl::PieceStand::trySub
void trySub(Ptype type)
1枚以上持っていれば減らす
Definition: bits/pieceStand.h:92
osl::PieceStand::mask
static const CArray< unsigned char, PTYPE_MAX+1 > mask
Definition: bits/pieceStand.h:45
osl::PieceStand::subAtmostOnePiece
void subAtmostOnePiece(PieceStand const &ps)
Definition: bits/pieceStand.h:118
osl::PieceStand::getFlags
unsigned int getFlags() const
Definition: bits/pieceStand.h:165
osl::PieceStand::max2
const PieceStand max2(PieceStand other) const
種類毎に this と other の持駒の多い方を取る (max のalternative)
Definition: bits/pieceStand.h:187
osl::PieceStand::isSuperiorOrEqualTo
bool isSuperiorOrEqualTo(PieceStand other) const
Definition: bits/pieceStand.h:138
osl::Move
圧縮していない moveの表現 .
Definition: basic_type.h:1052
basic_type.h
osl::PieceStand::carryUnchangedAfterSub
bool carryUnchangedAfterSub(const PieceStand &original, const PieceStand &other) const
Definition: pieceStand.cc:69
osl::PieceStand::PieceStand
PieceStand(unsigned int value=0)
Definition: bits/pieceStand.h:48
osl::PieceStandIO::readNumbers
static std::istream & readNumbers(std::istream &, PieceStand &stand)
Definition: pieceStand.cc:97
osl::PieceStand::sub
void sub(Ptype type, unsigned int num=1)
Definition: bits/pieceStand.h:75
osl::SimpleState
Definition: simpleState.h:35
osl::PieceStand::carryMask
static const unsigned int carryMask
Definition: bits/pieceStand.h:42
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:84
osl::LANCE
@ LANCE
Definition: basic_type.h:96
osl::PieceStand::PieceStand
PieceStand(int pawnCount, int lanceCount, int knightCount, int silverCount, int goldCount, int bishopCount, int rookCount, int kingCount)
Definition: bits/pieceStand.h:52
osl::PieceStand::addAtmostOnePiece
void addAtmostOnePiece(PieceStand const &ps)
pieceStand同士の加算,減算.
Definition: bits/pieceStand.h:108
osl::GOLD
@ GOLD
Definition: basic_type.h:94
osl::operator<<
std::ostream & operator<<(std::ostream &os, Player player)
Definition: basic_type.cc:14
osl::PieceStand::nextStand
const PieceStand nextStand(Player pl, Move move) const
Definition: bits/pieceStand.h:203
osl::KING
@ KING
Definition: basic_type.h:93
osl::BISHOP
@ BISHOP
Definition: basic_type.h:99
osl::Move::capturePtype
Ptype capturePtype() const
Definition: basic_type.h:1180
container.h
osl::PieceStand::nextStand
const PieceStand nextStand(Move move) const
Definition: bits/pieceStand.h:222
osl::Move::isDrop
bool isDrop() const
Definition: basic_type.h:1150
osl::PAWN
@ PAWN
Definition: basic_type.h:95
osl::PieceStand::carriesOn
void carriesOn() const
Definition: bits/pieceStand.h:136
osl::isBasic
bool isBasic(Ptype ptype)
ptypeが基本型(promoteしていない)かのチェック
Definition: basic_type.h:128
osl::PieceStand
片方の手番の持駒の枚数を記録するクラス.
Definition: bits/pieceStand.h:38
osl::PieceStand::testCarries
unsigned int testCarries() const
Definition: bits/pieceStand.h:137
osl::PieceStand::carryUnchangedAfterAdd
bool carryUnchangedAfterAdd(const PieceStand &original, const PieceStand &other) const
Definition: pieceStand.cc:60
osl::Move::isNormal
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
osl::PieceStand::add
void add(Ptype type, unsigned int num=1)
Definition: bits/pieceStand.h:68
osl::PieceStand::order
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
Definition: bits/pieceStand.h:41
osl::PieceStand::previousStand
const PieceStand previousStand(Player pl, Move move) const
Definition: bits/pieceStand.h:226
osl::PieceStand::hasMoreThan
bool hasMoreThan(Player P, PieceStand other) const
Definition: bits/pieceStand.h:158
osl::ROOK
@ ROOK
Definition: basic_type.h:100
osl::operator<
bool operator<(Offset l, Offset r)
Definition: basic_type.h:520
osl::operator==
bool operator==(Square l, Square r)
Definition: basic_type.h:758
osl::Move::ptype
Ptype ptype() const
Definition: basic_type.h:1155
osl::BLACK
@ BLACK
Definition: basic_type.h:9
osl::SILVER
@ SILVER
Definition: basic_type.h:98
osl::Player
Player
Definition: basic_type.h:8
osl::operator!=
bool operator!=(Offset l, Offset r)
Definition: basic_type.h:516
osl::PieceStand::shift
static const CArray< unsigned char, PTYPE_MAX+1 > shift
Definition: bits/pieceStand.h:44
osl::PieceStand::any
bool any() const
どれかの駒を一枚でも持っている
Definition: bits/pieceStand.h:167
osl::CArray< Ptype, 7 >
osl::PieceStand::canAdd
bool canAdd(Ptype type) const
Definition: pieceStand.cc:39
osl::PieceStand::hasMoreThan
bool hasMoreThan(PieceStand other) const
this と other が BLACK の持駒と考えた時に, this の方が同じか沢山持っていれば真.
Definition: bits/pieceStand.h:151
osl::PieceStandIO
Definition: bits/pieceStand.h:271
osl::PieceStand::carriesOff
void carriesOff() const
Definition: bits/pieceStand.h:135
osl::PieceStand::get
unsigned int get(Ptype type) const
Definition: bits/pieceStand.h:131
osl::PieceStand::previousStand
const PieceStand previousStand(Move move) const
Definition: bits/pieceStand.h:246
osl::PieceStand::tryAdd
void tryAdd(Ptype type)
加算可能なら加える.
Definition: pieceStand.cc:47
osl::PieceStand::atMostOneKind
bool atMostOneKind() const
一種類の駒しかない
Definition: pieceStand.cc:53
osl::PieceStand::flags
unsigned int flags
Definition: bits/pieceStand.h:46
osl::Move::player
Player player() const
Definition: basic_type.h:1195
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition: basic_type.h:157
osl
Definition: additionalEffect.h:6
osl::PieceStand::max
const PieceStand max(PieceStand other) const
種類毎に this と other の持駒の多い方を取る
Definition: bits/pieceStand.h:171
osl::KNIGHT
@ KNIGHT
Definition: basic_type.h:97
osl::PieceStandIO::writeNumbers
static std::ostream & writeNumbers(std::ostream &, const PieceStand &stand)
持駒の数を空白区切で出力する.
Definition: pieceStand.cc:89