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>
9namespace osl
10{
11 class SimpleState;
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
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
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); }
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
253 {
254 assert(! l.testCarries());
255 assert(! r.testCarries());
256 return l.getFlags() == r.getFlags();
257 }
259 {
260 return ! (l == r);
261 }
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:
圧縮していない moveの表現 .
Ptype ptype() const
Player player() const
bool isDrop() const
Ptype capturePtype() const
bool isNormal() const
INVALID でも PASS でもない.
片方の手番の持駒の枚数を記録するクラス.
static const CArray< unsigned char, PTYPE_MAX+1 > shift
bool hasMoreThan(Player P, PieceStand other) const
void add(Ptype type, unsigned int num=1)
static const unsigned int carryMask
unsigned int testCarries() const
const PieceStand nextStand(Player pl, Move move) const
void tryAdd(Ptype type)
加算可能なら加える.
Definition pieceStand.cc:47
static const CArray< unsigned char, PTYPE_MAX+1 > mask
void trySub(Ptype type)
1枚以上持っていれば減らす
void subAtmostOnePiece(PieceStand const &ps)
bool isSuperiorOrEqualTo(PieceStand other) const
void carriesOn() const
const PieceStand max(PieceStand other) const
種類毎に this と other の持駒の多い方を取る
bool any() const
どれかの駒を一枚でも持っている
bool canAdd(Ptype type) const
Definition pieceStand.cc:39
bool hasMoreThan(PieceStand other) const
this と other が BLACK の持駒と考えた時に, this の方が同じか沢山持っていれば真.
void carriesOff() const
PieceStand(unsigned int value=0)
unsigned int flags
const PieceStand previousStand(Move move) const
bool carryUnchangedAfterSub(const PieceStand &original, const PieceStand &other) const
Definition pieceStand.cc:69
const PieceStand previousStand(Player pl, Move move) const
bool carryUnchangedAfterAdd(const PieceStand &original, const PieceStand &other) const
Definition pieceStand.cc:60
bool atMostOneKind() const
一種類の駒しかない
Definition pieceStand.cc:53
const PieceStand nextStand(Move move) const
unsigned int getFlags() const
unsigned int get(Ptype type) const
void addAtmostOnePiece(PieceStand const &ps)
pieceStand同士の加算,減算.
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
void sub(Ptype type, unsigned int num=1)
const PieceStand max2(PieceStand other) const
種類毎に this と other の持駒の多い方を取る (max のalternative)
PieceStand(int pawnCount, int lanceCount, int knightCount, int silverCount, int goldCount, int bishopCount, int rookCount, int kingCount)
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
@ ROOK
Definition basic_type.h:100
@ BISHOP
Definition basic_type.h:99
@ PAWN
Definition basic_type.h:95
@ KING
Definition basic_type.h:93
@ KNIGHT
Definition basic_type.h:97
@ SILVER
Definition basic_type.h:98
@ GOLD
Definition basic_type.h:94
@ LANCE
Definition basic_type.h:96
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition basic_type.h:157
bool operator<(Offset l, Offset r)
Definition basic_type.h:520
bool operator!=(Offset l, Offset r)
Definition basic_type.h:516
Player
Definition basic_type.h:8
@ BLACK
Definition basic_type.h:9
bool isBasic(Ptype ptype)
ptypeが基本型(promoteしていない)かのチェック
Definition basic_type.h:128
std::ostream & operator<<(std::ostream &os, Player player)
Definition basic_type.cc:14
bool operator==(Square l, Square r)
Definition basic_type.h:758
static std::ostream & writeNumbers(std::ostream &, const PieceStand &stand)
持駒の数を空白区切で出力する.
Definition pieceStand.cc:89
static std::istream & readNumbers(std::istream &, PieceStand &stand)
Definition pieceStand.cc:97