bits/pieceStand.h
Go to the documentation of this file.
/* pieceStand.h
*/
#ifndef OSL_PIECESTAND_H
#define OSL_PIECESTAND_H
#include "osl/basic_type.h"
#include "osl/container.h"
#include <iosfwd>
#include <cassert>
namespace osl
{
class SimpleState;
class PieceStand
{
public:
static const CArray<Ptype,7> order;
static const unsigned int carryMask = 0x48822224;
private:
static const CArray<unsigned char,PTYPE_MAX+1> shift;
static const CArray<unsigned char,PTYPE_MAX+1> mask;
mutable unsigned int flags;
public:
explicit PieceStand(unsigned int value=0) : flags(value)
{
}
explicit PieceStand(Player, const SimpleState&);
PieceStand(int pawnCount, int lanceCount,
int knightCount, int silverCount,
int goldCount, int bishopCount,
int rookCount, int kingCount)
: flags(0)
{
add(PAWN, pawnCount);
add(LANCE, lanceCount);
add(KNIGHT, knightCount);
add(SILVER, silverCount);
add(GOLD, goldCount);
add(BISHOP, bishopCount);
add(ROOK, rookCount);
add(KING, kingCount);
}
void add(Ptype type, unsigned int num=1)
{
assert(isBasic(type));
assert(num == (num & mask[type]));
flags += (num << (shift[type]));
assert(testCarries() == 0); // overflow 検出
}
void sub(Ptype type, unsigned int num=1)
{
assert(isBasic(type));
assert(num == (num & mask[type]));
assert(get(type) >= num);
flags -= (num << (shift[type]));
}
void tryAdd(Ptype type);
bool canAdd(Ptype type) const;
void trySub(Ptype type)
{
if (get(type))
sub(type);
}
bool atMostOneKind() const;
void addAtmostOnePiece(PieceStand const& ps){
#ifndef NDEBUG
const PieceStand copy(*this);
#endif
assert(! ps.testCarries());
assert(ps.atMostOneKind());
flags += ps.getFlags();
assert(carryUnchangedAfterAdd(copy, ps));
}
void subAtmostOnePiece(PieceStand const& ps){
#ifndef NDEBUG
const PieceStand copy(*this);
#endif
assert(! ps.testCarries());
assert(ps.atMostOneKind());
flags -= ps.getFlags();
assert(carryUnchangedAfterSub(copy, ps));
}
private:
bool carryUnchangedAfterAdd(const PieceStand& original, const PieceStand& other) const;
bool carryUnchangedAfterSub(const PieceStand& original, const PieceStand& other) const;
public:
unsigned int get(Ptype type) const
{
return (flags >> (shift[type])) & mask[type];
}
void carriesOff() const { flags &= (~carryMask); }
void carriesOn() const { flags |= carryMask; }
unsigned int testCarries() const { return (flags & carryMask); }
bool isSuperiorOrEqualTo(PieceStand other) const
{
carriesOn();
other.carriesOff();
const bool result = (((flags - other.flags) & carryMask) == carryMask);
carriesOff();
return result;
}
template <Player P>
bool hasMoreThan(PieceStand other) const
{
if (P == BLACK)
return isSuperiorOrEqualTo(other);
else
return other.isSuperiorOrEqualTo(*this);
}
bool hasMoreThan(Player P, PieceStand other) const
{
if (P == BLACK)
return hasMoreThan<BLACK>(other);
else
return hasMoreThan<WHITE>(other);
}
unsigned int getFlags() const { return flags; }
bool any() const { return flags; }
const PieceStand max(PieceStand other) const
{
// other以上の数持っているptypeに対応するcarryが1になる．
const unsigned int mask0 = ((flags|carryMask)-other.flags) & carryMask;
// ROOK BISHOP KING用のMASKを作る
unsigned int my_mask = mask0-((mask0&0x40000024)>>2);
// GOLD SILVER KNIGHT LANCE用のMASKを作る
my_mask -= (mask0&0x08022200)>>3;
// PAWN用のMASKのみ残す
my_mask -= (mask0&0x00800000)>>5;
// my_mask が1のptypeの数は自分から，0のptypeはotherのところの値を
return PieceStand((flags&my_mask)|(other.flags&~my_mask));
}
const PieceStand max2(PieceStand other) const
{
// other以上の数持っているptypeに対応するcarryが1になる．
const unsigned int diff0=((flags|carryMask)-other.flags);
const unsigned int mask0=diff0&carryMask;
// ROOK BISHOP KING GOLD SILVER KNIGHT LANCE用のMASKを作る
const unsigned int mask02=(mask0&0x40000024u)+(mask0&0x48022224u);
unsigned int my_mask=mask0-(mask02>>3);
// PAWN用のMASKのみ残す
my_mask -= (mask0&0x00800000)>>5;
// my_mask が1のptypeの数は自分から，0のptypeはotherのところの値を
return PieceStand((other.flags+(diff0&my_mask))&~carryMask);
}
const PieceStand nextStand(Player pl, Move move) const
{
assert(move.isNormal());
PieceStand result = *this;
if (move.player() == pl)
{
if (const Ptype ptype = move.capturePtype())
{
result.add(unpromote(ptype));
}
else if (move.isDrop())
{
const Ptype ptype = move.ptype();
assert(get(ptype));
result.sub(ptype);
}
}
return result;
}
const PieceStand nextStand(Move move) const
{
return nextStand(move.player(), move);
}
const PieceStand previousStand(Player pl, Move move) const
{
assert(move.isNormal());
PieceStand result = *this;
if (move.player() == pl)
{
if (const Ptype ptype = move.capturePtype())
{
const Ptype before = unpromote(ptype);
assert(get(before));
result.sub(before);
}
else if (move.isDrop())
{
const Ptype ptype = move.ptype();
result.add(ptype);
}
}
return result;
}
const PieceStand previousStand(Move move) const
{
return previousStand(move.player(), move);
}
};
inline bool operator==(PieceStand l, PieceStand r)
{
assert(! l.testCarries());
assert(! r.testCarries());
return l.getFlags() == r.getFlags();
}
inline bool operator!=(PieceStand l, PieceStand r)
{
return ! (l == r);
}
inline bool operator<(PieceStand l, PieceStand r)
{
assert(! l.testCarries());
assert(! r.testCarries());
return l.getFlags() < r.getFlags();
}
std::ostream& operator<<(std::ostream&, PieceStand l);
struct PieceStandIO
{
static std::ostream& writeNumbers(std::ostream&, const PieceStand& stand);
static std::istream& readNumbers(std::istream&, PieceStand& stand);
};
} // namespace osl
#endif /* OSL_PIECESTAND_H */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
basic_type.h
osl::CArray
Definition container.h:20
osl::Move
圧縮していない moveの表現 .
Definition basic_type.h:1052
osl::Move::ptype
Ptype ptype() const
Definition basic_type.h:1155
osl::Move::player
Player player() const
Definition basic_type.h:1195
osl::Move::isDrop
bool isDrop() const
Definition basic_type.h:1150
osl::Move::capturePtype
Ptype capturePtype() const
Definition basic_type.h:1180
osl::Move::isNormal
bool isNormal() const
INVALID でも PASS でもない.
Definition basic_type.h:1088
osl::PieceStand
片方の手番の持駒の枚数を記録するクラス.
Definition bits/pieceStand.h:38
osl::PieceStand::shift
static const CArray< unsigned char, PTYPE_MAX+1 > shift
Definition bits/pieceStand.h:44
osl::PieceStand::hasMoreThan
bool hasMoreThan(Player P, PieceStand other) const
Definition bits/pieceStand.h:158
osl::PieceStand::add
void add(Ptype type, unsigned int num=1)
Definition bits/pieceStand.h:68
osl::PieceStand::carryMask
static const unsigned int carryMask
Definition bits/pieceStand.h:42
osl::PieceStand::testCarries
unsigned int testCarries() const
Definition bits/pieceStand.h:137
osl::PieceStand::nextStand
const PieceStand nextStand(Player pl, Move move) const
Definition bits/pieceStand.h:203
osl::PieceStand::tryAdd
void tryAdd(Ptype type)
加算可能なら加える.
Definition pieceStand.cc:47
osl::PieceStand::mask
static const CArray< unsigned char, PTYPE_MAX+1 > mask
Definition bits/pieceStand.h:45
osl::PieceStand::trySub
void trySub(Ptype type)
1枚以上持っていれば減らす
Definition bits/pieceStand.h:92
osl::PieceStand::subAtmostOnePiece
void subAtmostOnePiece(PieceStand const &ps)
Definition bits/pieceStand.h:118
osl::PieceStand::isSuperiorOrEqualTo
bool isSuperiorOrEqualTo(PieceStand other) const
Definition bits/pieceStand.h:138
osl::PieceStand::carriesOn
void carriesOn() const
Definition bits/pieceStand.h:136
osl::PieceStand::max
const PieceStand max(PieceStand other) const
種類毎に this と other の持駒の多い方を取る
Definition bits/pieceStand.h:171
osl::PieceStand::any
bool any() const
どれかの駒を一枚でも持っている
Definition bits/pieceStand.h:167
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::PieceStand::carriesOff
void carriesOff() const
Definition bits/pieceStand.h:135
osl::PieceStand::PieceStand
PieceStand(unsigned int value=0)
Definition bits/pieceStand.h:48
osl::PieceStand::flags
unsigned int flags
Definition bits/pieceStand.h:46
osl::PieceStand::previousStand
const PieceStand previousStand(Move move) const
Definition bits/pieceStand.h:246
osl::PieceStand::carryUnchangedAfterSub
bool carryUnchangedAfterSub(const PieceStand &original, const PieceStand &other) const
Definition pieceStand.cc:69
osl::PieceStand::previousStand
const PieceStand previousStand(Player pl, Move move) const
Definition bits/pieceStand.h:226
osl::PieceStand::carryUnchangedAfterAdd
bool carryUnchangedAfterAdd(const PieceStand &original, const PieceStand &other) const
Definition pieceStand.cc:60
osl::PieceStand::atMostOneKind
bool atMostOneKind() const
一種類の駒しかない
Definition pieceStand.cc:53
osl::PieceStand::nextStand
const PieceStand nextStand(Move move) const
Definition bits/pieceStand.h:222
osl::PieceStand::getFlags
unsigned int getFlags() const
Definition bits/pieceStand.h:165
osl::PieceStand::get
unsigned int get(Ptype type) const
Definition bits/pieceStand.h:131
osl::PieceStand::addAtmostOnePiece
void addAtmostOnePiece(PieceStand const &ps)
pieceStand同士の加算，減算.
Definition bits/pieceStand.h:108
osl::PieceStand::order
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
Definition bits/pieceStand.h:41
osl::PieceStand::sub
void sub(Ptype type, unsigned int num=1)
Definition bits/pieceStand.h:75
osl::PieceStand::max2
const PieceStand max2(PieceStand other) const
種類毎に this と other の持駒の多い方を取る (max のalternative)
Definition bits/pieceStand.h:187
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::SimpleState
Definition simpleState.h:35
container.h
osl
Definition additionalEffect.h:6
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
osl::ROOK
@ ROOK
Definition basic_type.h:100
osl::BISHOP
@ BISHOP
Definition basic_type.h:99
osl::PAWN
@ PAWN
Definition basic_type.h:95
osl::KING
@ KING
Definition basic_type.h:93
osl::KNIGHT
@ KNIGHT
Definition basic_type.h:97
osl::SILVER
@ SILVER
Definition basic_type.h:98
osl::GOLD
@ GOLD
Definition basic_type.h:94
osl::LANCE
@ LANCE
Definition basic_type.h:96
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に，promote前の型を返す． promoteしていない型の時はそのまま返す
Definition basic_type.h:157
osl::operator<
bool operator<(Offset l, Offset r)
Definition basic_type.h:520
osl::operator!=
bool operator!=(Offset l, Offset r)
Definition basic_type.h:516
osl::Player
Player
Definition basic_type.h:8
osl::BLACK
@ BLACK
Definition basic_type.h:9
osl::isBasic
bool isBasic(Ptype ptype)
ptypeが基本型(promoteしていない)かのチェック
Definition basic_type.h:128
osl::operator<<
std::ostream & operator<<(std::ostream &os, Player player)
Definition basic_type.cc:14
osl::operator==
bool operator==(Square l, Square r)
Definition basic_type.h:758
osl::PieceStandIO
Definition bits/pieceStand.h:271
osl::PieceStandIO::writeNumbers
static std::ostream & writeNumbers(std::ostream &, const PieceStand &stand)
持駒の数を空白区切で出力する.
Definition pieceStand.cc:89
osl::PieceStandIO::readNumbers
static std::istream & readNumbers(std::istream &, PieceStand &stand)
Definition pieceStand.cc:97