1 #ifndef OSL_BASIC_TYPE_H 2 #define OSL_BASIC_TYPE_H 14 return static_cast<Player>(-1-
static_cast<int>(player));
17 return -
static_cast<int>(player);
21 return static_cast<Player>(-n);
26 return 1+(
static_cast<int>(player)<<1);
29 return static_cast<int>(player);
48 struct PlayerTraits<BLACK>{
49 static const int offsetMul=1;
50 static const int index=0;
51 static const int mask=0;
56 struct PlayerTraits<WHITE>{
57 static const int offsetMul=-1;
58 static const int index=1;
59 static const int mask= -1;
131 return static_cast<int>(ptype)>
PROOK;
140 return static_cast<int>(ptype)<
KING;
150 return static_cast<int>(ptype)>
GOLD;
160 Ptype ret=
static_cast<Ptype>(
static_cast<int>(ptype)|8);
176 Ptype ret=
static_cast<Ptype>(
static_cast<int>(ptype)-8);
192 return (static_cast<int>(ptype)|8)>=14;
204 #define NEW_PTYPEO(player,ptype) static_cast<PtypeO>(static_cast<int>(ptype)-(16&static_cast<int>(player))) 213 return static_cast<PtypeO>(
static_cast<int>(ptype)-(16&static_cast<int>(player)));
219 return static_cast<Ptype>(
static_cast<int>(ptypeO)& 15);
226 PtypeO ret=
static_cast<PtypeO>(
static_cast<int>(ptypeO)-8);
234 assert(promoteMask==0 || promoteMask==0x800000);
235 PtypeO ret=
static_cast<PtypeO>(
static_cast<int>(ptypeO)-(promoteMask>>20));
242 return static_cast<PtypeO>(
static_cast<int>(ptypeO)|8);
259 return static_cast<Player>(
static_cast<int>(ptypeO)>>31);
267 return static_cast<PtypeO>((
static_cast<int>(ptypeO)|8)^(~15));
274 return static_cast<PtypeO>(
static_cast<int>(ptypeO)^(~15));
283 int v=
static_cast<int>(ptypeO);
284 return static_cast<PtypeO>(v^((1-(v&15))&~15));
394 return (1<<static_cast<int>(dir));
434 ONBOARD_OFFSET_MIN=-0x88,
436 ONBOARD_OFFSET_MAX=0x88,
438 ONBOARD_OFFSET_SIZE=0x88*2+1
440 static const int BOARD_HEIGHT=16;
450 static int makeOffset(
int dx,
int dy) {
return dx*BOARD_HEIGHT + dy; }
451 Offset(
int dx,
int dy) : offset(makeOffset(dx,dy))
458 template <Player, Direction>
471 unsigned int index()
const {
return offset - OFFSET_MIN; }
485 return result += other;
490 return result -= other;
493 return static_cast<Offset>(
static_cast<int>(offset)*mult);
502 bool zero()
const {
return offset == OFFSET_ZERO; }
551 assert(square < SIZE);
563 int x()
const {
return square >> 4; }
567 int y()
const {
return (square&0xf)-1; }
571 int y1()
const {
return square&0xf; }
572 unsigned int index()
const {
return square - MIN; }
573 static unsigned int indexMax() {
return SIZE - MIN; }
577 bool isOnBoardSlow()
const;
584 return (0xffffff88&(square-0x12)&
585 ((
unsigned int)((square&0x77)^0x12)+0xffffff77))==0;
592 assert(!isPieceStand() && 0<=x() && x()<=10 && 0<=y() && y()<=10);
593 return (0x88&(square-0x12)&((square&0x11)+0xf7))!=0;
599 return (player == BLACK)
601 : makeDirect(
Square(9,9).uintValue()+
Square(1,1).uintValue()-uintValue());
610 return squareForBlack(P);
615 return squareForBlack<WHITE>();
626 return squareForBlack<WHITE>();
632 return Square(10-x(), y());
642 return static_cast<unsigned int>(index()-onBoardMin().index())
643 <= static_cast<unsigned int>(onBoardMax().index()-onBoardMin().index());
656 return P == BLACK ? y <= 3 : y >= 7;
665 return (uintValue()&0xf)<=4;
667 return (uintValue()&0x8)!=0;
675 unsigned int v=uintValue() ^ sq.
uintValue();
676 return (((v+0xefull)^v)&0x110ull)!=0x110ull;
683 unsigned int v=uintValue() ^ sq.
uintValue();
692 unsigned int v=uintValue() ^ sq.
uintValue();
694 return ((v|(uintValue()-sq.
uintValue()))&0xf0)==0;
696 return ((v|(sq.
uintValue()-uintValue()))&0xf0)==0;
703 unsigned int v=uintValue() ^ sq.
uintValue();
716 return result+=offset;
720 return result-=offset;
727 return (uintValue()&0xf)==(Y+1);
730 typename std::enable_if<Y!=2,bool>::type
yLe() {
731 return (uintValue()&0xf)<=(Y+1);
734 typename std::enable_if<Y==2,bool>::type
yLe() {
735 return (uintValue()&0xc)==0;
738 typename std::enable_if<Y!=7,bool>::type
yGe() {
739 return (uintValue()&0xf)>=(Y+1);
742 typename std::enable_if<Y==7,bool>::type
yGe() {
743 return (uintValue()&0x8)!=0;
745 template <Player P, Direction D>
749 template <Player P, Direction D>
751 return neighbor<alt(P),D>();
755 bool isNeighboring8(
Square to)
const;
794 static const int SIZE=40;
799 static const int BitOffsetPtype=16;
800 static const int BitOffsetPromote=BitOffsetPtype+3;
801 static const int BitOffsetMovePromote=BitOffsetPromote+4;
804 : piece((static_cast<int>(owner)<<20)
805 +(static_cast<int>(ptype)<<BitOffsetPtype)
806 +((num)<<8)+ square.uintValue())
822 return static_cast<Ptype>((piece>>BitOffsetPtype)&0xf);
825 return static_cast<PtypeO>(piece>>BitOffsetPtype);
829 return ((piece&0xff00)>>8);
842 piece = (piece&0xffffff00)+square.
uintValue();
859 return static_cast<int>(
static_cast<unsigned int>(piece)&0x800000ff)>0;
861 return static_cast<int>((-piece)&0x800000ff)>0;
867 return Piece(piece-0x80000);
872 return Piece((
int)piece|0x80000);
882 return Piece((piece&0xfff7ff00)^0xfff80000);
887 assert(promote_mask==0 || promote_mask==(1<<23));
888 return Piece(piece - (promote_mask>>(BitOffsetMovePromote-BitOffsetPromote)));
892 return Piece(piece - (promotep<<19));
905 int mask=piece&((1<<19)|0xff);
909 assert(ptype()!=
KING && ptype()!=
GOLD);
914 return (piece&0x8000)!=0;
917 return (num&0x80)!=0;
920 return (piece&0x4000)!=0;
923 assert(!isEmptyNum(num));
924 return (num&0x40)!=0;
927 return (num&0xc0)==0;
931 return (piece&0xf0000)==((T)<<BitOffsetPtype);
939 return (piece&0x1f0000)==(((ptype)<<BitOffsetPtype)|(pl&0x100000));
949 return (piece&0x170000)==(((
osl::promote(ptype))<<BitOffsetPtype)|(pl&0x100000));
951 return isPlayerPtype(pl,ptype);
954 return (piece&0xc000)==0;
961 return static_cast<int>(piece)>=0;
966 return static_cast<Player>(piece>>20);
982 return pl == BLACK ? ((piece+0xe0000)&0x104000)==0 : piece>=0;
1011 # define move_assert(x) assert(x) 1013 # define move_assert(x) 1057 explicit Move(
int value) : move(value)
1061 INVALID_VALUE = (1<<8), DECLARE_WIN = (2<<8),
1062 BLACK_PASS = 0, WHITE_PASS = ((unsigned) -1)<<28,
1067 unsigned int hash()
const;
1071 static const unsigned int MaxUniqMoves=600;
1074 Ptype capture_ptype,
bool is_promote,
Player player)
1078 + (static_cast<unsigned int>(capture_ptype)<<16)
1079 + (static_cast<unsigned int>(is_promote)<<BitOffsetPromote)
1080 + (static_cast<unsigned int>(ptype)<<24)
1081 + (static_cast<int>(player)<<28));
1090 return move & 0x00ff;
1092 bool isPass()
const {
return (move & 0xffff) == 0; }
1101 Ptype capture_ptype,
bool is_promote,
Player player)
1108 init(from, to, ptype, capture_ptype, is_promote, player);
1127 assert(! isInvalid());
1133 assert(! isInvalid());
1139 unsigned int fromTo()
const {
return move & 0xffff; }
1145 return (static_cast<int>(move)&(1<<BitOffsetPromote));
1147 bool isPromotion()
const { assert(isNormal());
return (move & (1<<BitOffsetPromote))!=0; }
1150 bool isDrop()
const { assert(isNormal());
return from().isPieceStand(); }
1152 return isDrop() && ptype() ==
PAWN;
1156 assert(! isInvalid());
1158 const Ptype result =
static_cast<Ptype>((move >> 24) & 0xf);
1163 assert(! isInvalid());
1169 assert(! isInvalid());
1170 const PtypeO result =
static_cast<PtypeO>((move>>24)+((move >> (BitOffsetPromote-3))&8));
1175 assert(! isInvalid());
1177 const PtypeO old_ptypeo =
static_cast<PtypeO>((move>>24)+((move >> (BitOffsetPromote-3))&8));
1182 const Ptype result =
static_cast<Ptype>((move>>16)&0xf);
1186 assert(isCapture());
1192 return capturePtypeO();
1196 assert(! isInvalid());
1203 return static_cast<unsigned int>(move-1) < DECLARE_WIN;
1210 int result =
static_cast<int>(intValue());
1211 result &= ~(0xff00);
1213 return makeDirect(result);
1218 assert(from().uintValue()==0);
1219 int result =
static_cast<int>(intValue());
1221 return makeDirect(result);
1228 assert(! isCapture());
1229 return makeDirect(intValue()+(capture.
intValue()&0xf0000));
1233 return makeDirect((intValue()&0xfff0ffff)+(capture.
intValue()&0xf0000));
1237 return makeDirect((intValue()&0xfff0ffff)
1246 return makeDirect(intValue()^((1<<BitOffsetPromote)^(1<<27)));
1254 return makeDirect(intValue()^((1<<BitOffsetPromote)^(1<<27)));
1261 return makeDirect(intValue()+o.
intValue());
1268 assert((intValue()&0xff)==0);
1277 + (static_cast<unsigned int>(newPtype)<<24));
1287 return (P==BLACK ? to.
y()==2 : to.
y()==8);
1288 default:
return false;
1297 assert(player()==P);
1298 if(isDrop())
return false;
1299 return ignoreUnpromote<P>(ptype(),from(),to());
1302 if(player()==BLACK)
return ignoreUnpromote<BLACK>();
1303 else return ignoreUnpromote<WHITE>();
1310 assert(player()==P);
1311 if(!isPromotion())
return false;
1314 return (P==BLACK ? to().y()!=1 : to().y()!=9);
1316 return (P==BLACK ? to().y()==2 : to().y()==8);
1319 default:
return false;
1323 if(player()==BLACK)
return hasIgnoredUnpromote<BLACK>();
1324 else return hasIgnoredUnpromote<WHITE>();
1326 const Move rotate180()
const;
1330 #ifdef PRESERVE_MOVE_ORDER 1332 l=(l&0xffff0000)+((l>>8)&0xff)+((l<<8)&0xff00);
1334 r=(r&0xffff0000)+((r>>8)&0xff)+((r<<8)&0xff00);
1346 return ! (lhs == rhs);
static bool ignoreUnpromote(Ptype ptype, Square from, Square to)
Square & operator+=(Offset offset)
constexpr Direction primDirUnsafe(Direction d)
8方向について,primitiveな4方向を求める dとしてknight, INVALIDなども来る
static const int BitOffsetMovePromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す ...
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
constexpr Direction inverseUnsafe(Direction d)
static const Piece makeDirect(int value)
std::enable_if< Y==2, bool >::type yLe()
bool canMoveOn() const
Player Pの駒が,thisの上に移動できるか? PIECE_EMPTY 0x00008000 BLACK_PIECE 0x000XxxYY X>=2...
bool isMajor(Ptype ptype)
int operator+(Player, int)
constexpr int dirToMask(Direction dir)
void init(Square from, Square to, Ptype ptype, Ptype capture_ptype, bool is_promote, Player player)
constexpr Direction inverse(Direction d)
constexpr bool isShort(Direction d)
PtypeO altIfPiece(PtypeO ptypeO)
Pieceの時にはowner を反転する
static const Move makeDirect(int value)
constexpr Player alt(Player player)
const Offset operator-(Square other) const
const PtypeO PTYPEO_EDGE __attribute__((unused))
const Square operator+(Offset offset) const
bool canMoveOn(Player pl) const
bool isValidOrPass() const
static const Square makeDirect(int value)
PtypeO capturePtypeOSafe() const
bool hasIgnoredUnpromote() const
MoveをunpromoteするとcutUnpromoteなMoveになる
const Move promote() const
unpromote moveからpromote moveを作る
Piece & operator+=(Offset offset)
static const Piece EDGE()
PtypeO capturePtypeO() const
Ptype getPtype(PtypeO ptypeO)
Move(Square to, Ptype ptype, Player player)
drop
void setSquare(Square square)
const Move unpromote() const
promote moveからunpromote moveを作る
const Offset operator*(const int mult) const
static const Move PASS(Player P)
bool isNormal() const
INVALID でも PASS でもない.
bool isMajorNonPieceOK(Ptype ptype)
int y() const
将棋としてのY座標を返す.
const Piece checkPromote(bool promotep) const
bool isULRD(Square sq) const
2つのSquare(onBoardであることが前提)が, xが等しいかyが等しい
const Square squareForBlack() const
後手の場合は盤面を引っくり返す.
std::ostream & operator<<(std::ostream &os, Player player)
static const Piece EMPTY()
const Offset operator+(Offset other) const
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
static const int BOARD_HEIGHT
Move newAddPtype(Ptype newPtype) const
作ってあったPTYPE_EMPTYのひな形のPTYPEをsetする
int x() const
将棋としてのX座標を返す.
const Move newCapture(Ptype capture) const
Square & operator-=(Offset offset)
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない. ...
bool ignoreUnpromote() const
PtypeO newPtypeO(Player player, Ptype ptype)
bool isValidPtypeO(int ptypeO)
std::enable_if< Y==7, bool >::type yGe()
static const Square makeNoCheck(int x, int y)
assertなしに作る
int operator/(Player, int)
unsigned long operator()(osl::Move m) const
Piece(Player owner, Ptype ptype, int num, Square square)
static bool isEdgeNum(int num)
constexpr bool isShort8(Direction d)
static int reverseY(int y)
unsigned int index() const
bool ignoreUnpromote() const
合法手ではあるが,打歩詰め絡み以外では有利にはならない手.
bool isOnBoard() const
盤面上を表すかどうかの判定. 1<=x() && x()<=9 && 1<=y() && y()<=9 Squareの内部表現に依存する. ...
static const Offset makeDirect(int value)
const Square from() const
Player getOwner(PtypeO ptypeO)
Ptype oldPtype() const
移動前のPtype, i.e., 成る手だった場合成る前
Move(Square from, Square to, Ptype ptype, Ptype capture_ptype, bool is_promote, Player player)
移動
static int reverseX(int x)
static unsigned int indexMax()
const Square rotate180() const
static const Move INVALID()
bool isValid(Player player)
cast等で作られたplayerが正しいかどうかを返す
Move newAddTo(Square sq) const
つくってあったmoveの雛形のsquareをsetする. mのtoは0
bool isPromoted() const
promoteした駒かどうかをチェックする
const Piece promoteWithMask(int promote_mask) const
bool isBasic(Ptype ptype)
ptypeが基本型(promoteしていない)かのチェック
constexpr Direction shortToLong(Direction d)
引数に longDirを与えてはいけない
bool canPromote(Player player) const
constexpr int playerToIndex(Player player)
static bool isEmptyNum(int num)
unsigned int index() const
const Square neighbor() const
int promoteMask() const
pieceに使うためのmaskなので
bool operator<(Offset l, Offset r)
constexpr Direction primDir(Direction d)
8方向について,primitiveな4方向を求める
Offset & operator+=(Offset other)
constexpr int sign(Player player)
bool isCaptureOrPromotion() const
const Piece promote() const
constexpr Direction longToShort(Direction d)
const Square rotate180EdgeOK() const
static const Square nth(unsigned int i)
Move newAddTo(Offset o) const
moveのtoをoffsetだけ変える. 元のtoが0以外でも使える
const Square flipHorizontal() const
bool isOnBoardByOwner(Player owner) const
isOnBoardByOwner の通常関数のバージョン.
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
const Offset operator-() const
bool hasIgnoredUnpromote() const
const Move newCapture(Piece capture) const
const Square square() const
Ptype capturePtype() const
constexpr Player indexToPlayer(int n)
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Offset newOffset(int dx, int dy)
PtypeO oldPtypeO() const
移動前のPtypeO, i.e., 成る手だった場合成る前
int indexForOffset32() const
static const Move DeclareWin()
static const int BitOffsetPtype
bool isUD(Square sq) const
2つのSquare(onBoardであることが前提)のxが等しい
static const Square onBoardMax()
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
static bool canPromoteY(int y)
std::enable_if< Y!=2, bool >::type yLe()
const Square back() const
const PtypeO PTYPEO_EMPTY
Move newFrom(Square new_from) const
constexpr bool isLong(Direction d)
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
const Offset operator-(const Offset other) const
static const Square onBoardMin()
bool isPlayerPtype(Player pl, Ptype ptype) const
あるpieceがPlayer pの持ち物でPtype ptypeであるかどうかをチェックする. TはEMPTY, EDGEではない. ...
std::enable_if< Y!=7, bool >::type yGe()
bool isOnBoardNotPromoted() const
promoteしていないOnBoardの駒であることのチェック Lance位しか使い道がない?
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
static bool isPieceNum(int num)
static int makeOffset(int dx, int dy)
constexpr int playerToMask(Player player)
bool isLR(Square sq) const
2つのSquare(onBoardであることが前提)のyが等しい
bool isU(Square sq) const
sqがPlayer Pにとって上
bool isPromotedNotKingGold() const
const Offset blackOffset() const
Player P からみた offset を黒番のものに変更する
constexpr Ptype unpromoteSafe(Ptype ptype)
const Piece unpromote() const
bool operator==(Square l, Square r)
const Square squareForBlack(Player player) const
bool operator>(Square l, Square r)
int operator*(Player, int)
#define move_assert(x)
move 関係でつかまえ所のないエラーがでるときに定義する
bool isPieceStand() const
int operator-(Player, int)
unsigned int ptypeOIndex(PtypeO ptypeo)
bool isEdge() const
onBoardから8近傍のオフセットを足した点がedgeかどうかの判定 そこそこ速くなった.
bool isPlayerBasicPtype(Player pl, Ptype ptype) const
あるpieceがPlayer pの持ち物でBASIC typeがptypeであるかどうかをチェックする. TはEMPTY, EDGEではない.
bool operator!=(Offset l, Offset r)
const Square rotate180Safe() const
const Square operator-(Offset offset) const
std::istream & operator>>(std::istream &is, Ptype &ptype)
static const Offset ZERO()
Offset & operator-=(Offset other)
unsigned int uintValue() const
static const Square STAND()
bool isOnBoardRegion() const
squareがONBOARD_MINとONBOARD_MAXの間にある
const Move newAddCapture(Piece capture) const
no capture moveからcapture moveを作る
Move newAddFrom(Square new_from) const
bool isMajorBasic(Ptype ptype)
const Piece captured() const
取られたpieceを作成.
unsigned int fromTo() const
fromとtoをまとめて同一性の判定など
bool isInvalid() const
state に apply 可能でない場合にtrue
bool pieceIsBlack() const
pieceであることが分かっている時に,更にBlackかどうかをチェックする.
PtypeO promoteWithMask(PtypeO ptypeO, int promoteMask)
pieceを引数次第でpromoteさせる