/usr/include/osl/move.h is in libosl-dev 0.6.0-3.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | #ifndef OSL_MOVE_H
#define OSL_MOVE_H
#include "osl/player.h"
#include "osl/ptype.h"
#include "osl/square.h"
#include "osl/piece.h"
#include <iosfwd>
/** move 関係でつかまえ所のないエラーがでるときに定義する */
// #define MOVE_DEBUG
#ifdef MOVE_DEBUG
# include <cassert>
# define move_assert(x) assert(x)
#else
# define move_assert(x)
#endif
// 2009/12/10 以前のfromが下位にあるパターンと
// operator< を同じにしたい時に定義する.
// #define PRESERVE_MOVE_ORDER
namespace osl
{
namespace state {
class SimpleState;
}
/** 16bit 表現*/
enum Move16 {
MOVE16_NONE = 0,
};
/**
* 圧縮していない moveの表現 .
* - invalid: isInvalid 以外の演算はできない
* - declare_win: isInvalid 以外の演算はできない
* - pass: from, to, ptype, oldPtype はとれる.player()はとれない.
*
* Pieceとpromotepをそろえる -> 変える.
* 下位から
* 2009/12/10から
* - to : 8 bit
* - from : 8 bit
* - capture ptype : 4 bit
* - dummy : 3 bit
* - promote? : 1 bit
* - ptype : 4 bit - promote moveの場合はpromote後のもの
* - owner : signed
* 2009/12/10以前
* - from : 8 bit
* - to : 8 bit
* - dummy : 3 bit
* - promote? : 1 bit
* - capture ptype : 4 bit
* - ptype : 4 bit - promote moveの場合はpromote後のもの
* - owner : signed
*/
class Move
{
public:
static const int BitOffsetPromote=Piece::BitOffsetMovePromote; // 23
private:
int move;
explicit Move(int value) : move(value)
{
}
enum {
INVALID_VALUE = (1<<8), DECLARE_WIN = (2<<8),
BLACK_PASS = 0, WHITE_PASS = (-1)<<28,
};
public:
int intValue() const { return move; }
/** 駒を取らない手を [0, 16305] にmap */
unsigned int hash() const;
/** 一局面辺りの合法手の最大値
* 重複して手を生成することがある場合は,600では不足かもしれない
*/
static const unsigned int MaxUniqMoves=600;
private:
void init(Square from, Square to, Ptype ptype,
Ptype capture_ptype, bool is_promote, Player player)
{
move = (to.uintValue()
+ (from.uintValue()<<8)
+ (static_cast<unsigned int>(capture_ptype)<<16)
+ (static_cast<unsigned int>(is_promote)<<BitOffsetPromote)
+ (static_cast<unsigned int>(ptype)<<24)
+ (static_cast<int>(player)<<28));
}
public:
Move() : move(INVALID_VALUE)
{
}
/** INVALID でも PASS でもない. isValid()かどうかは分からない.*/
bool isNormal() const {
// PASS や INVALID は to() が 00
return move & 0x00ff;
}
bool isPass() const { return (move & 0xffff) == 0; }
static const Move makeDirect(int value) { return Move(value); }
static const Move PASS(Player P) { return Move(P<<28); }
static const Move INVALID() { return Move(INVALID_VALUE); }
static const Move DeclareWin() { return Move(DECLARE_WIN); }
/**
* 移動
*/
Move(Square from, Square to, Ptype ptype,
Ptype capture_ptype, bool is_promote, Player player)
{
move_assert(from.isValid());
move_assert(to.isOnBoard());
move_assert(isValid(ptype));
move_assert(isValid(capture_ptype));
move_assert(isValid(player));
init(from, to, ptype, capture_ptype, is_promote, player);
move_assert(isValid());
}
/**
* drop
*/
Move(Square to, Ptype ptype, Player player)
{
move_assert(to.isOnBoard());
move_assert(isValid(ptype));
move_assert(isValid(player));
init(Square::STAND(), to, ptype, PTYPE_EMPTY, false, player);
move_assert(isValid());
}
static const Move fromMove16(Move16, const state::SimpleState&);
Move16 toMove16() const;
const Square from() const
{
assert(! isInvalid());
move_assert(isValidOrPass());
const Square result = Square::makeDirect((move>>8) & 0xff);
return result;
}
const Square to() const {
assert(! isInvalid());
move_assert(isValidOrPass());
const Square result = Square::makeDirect(move & 0xff);
return result;
}
/** fromとtoをまとめて同一性の判定など */
unsigned int fromTo() const { return move & 0xffff; }
/**
* pieceに使うためのmaskなので
*/
int promoteMask() const {
assert(isNormal());
return (static_cast<int>(move)&(1<<BitOffsetPromote));
}
bool isPromotion() const { assert(isNormal()); return (move & (1<<BitOffsetPromote))!=0; }
bool isCapture() const { assert(isNormal()); return capturePtype() != PTYPE_EMPTY; }
bool isCaptureOrPromotion() const { return isCapture() || isPromotion(); }
bool isDrop() const { assert(isNormal()); return from().isPieceStand(); }
bool isPawnDrop() const {
return isDrop() && ptype() == PAWN;
}
Ptype ptype() const {
assert(! isInvalid());
move_assert(isValidOrPass());
const Ptype result = static_cast<Ptype>((move >> 24) & 0xf);
return result;
}
/** 移動後のPtype, i.e., 成る手だった場合成った後 */
PtypeO ptypeO() const {
assert(! isInvalid());
const PtypeO result = static_cast<PtypeO>(move >> 24);
return result;
}
/** 移動前のPtypeO, i.e., 成る手だった場合成る前 */
PtypeO oldPtypeO() const {
assert(! isInvalid());
const PtypeO result = static_cast<PtypeO>((move>>24)+((move >> (BitOffsetPromote-3))&8));
return result;
}
/** 移動前のPtype, i.e., 成る手だった場合成る前 */
Ptype oldPtype() const {
assert(! isInvalid());
move_assert(isValidOrPass());
const PtypeO old_ptypeo = static_cast<PtypeO>((move>>24)+((move >> (BitOffsetPromote-3))&8));
return getPtype(old_ptypeo);
}
Ptype capturePtype() const {
assert(isNormal());
const Ptype result = static_cast<Ptype>((move>>16)&0xf);
return result;
}
PtypeO capturePtypeO() const {
assert(isCapture());
return newPtypeO(alt(player()), capturePtype());
}
PtypeO capturePtypeOSafe() const {
if (! isCapture())
return PTYPEO_EMPTY;
return capturePtypeO();
}
Player player() const {
assert(! isInvalid());
const Player result = static_cast<Player>(move>>28);
return result;
}
bool isValid() const;
/** state に apply 可能でない場合にtrue */
bool isInvalid() const {
return static_cast<unsigned int>(move-1) < DECLARE_WIN;
}
bool isValidOrPass() const { return isPass() || isValid(); }
Move newFrom(Square new_from) const
{
assert(isNormal());
int result = static_cast<int>(intValue());
result &= ~(0xff00);
result += (new_from.uintValue()<<8);
return makeDirect(result);
}
Move newAddFrom(Square new_from) const
{
assert(isNormal());
assert(from().uintValue()==0);
int result = static_cast<int>(intValue());
result += (new_from.uintValue()<<8);
return makeDirect(result);
}
/**
* no capture moveからcapture moveを作る
*/
const Move newAddCapture(Piece capture) const
{
assert(! isCapture());
return makeDirect(intValue()+(capture.intValue()&0xf0000));
}
const Move newCapture(Piece capture) const
{
return makeDirect((intValue()&0xfff0ffff)+(capture.intValue()&0xf0000));
}
const Move newCapture(Ptype capture) const
{
return makeDirect((intValue()&0xfff0ffff)
+(static_cast<int>(capture)<<Piece::BitOffsetPtype));
}
/**
* promote moveからunpromote moveを作る
*/
const Move unpromote() const {
assert(isNormal());
move_assert(isPromotion() && isPromoted(ptype()));
return makeDirect(intValue()^((1<<BitOffsetPromote)^(1<<27)));
}
/**
* unpromote moveからpromote moveを作る
*/
const Move promote() const {
assert(isNormal());
move_assert(!isPromotion() && canPromote(ptype()));
return makeDirect(intValue()^((1<<BitOffsetPromote)^(1<<27)));
}
/**
* moveのtoをoffsetだけ変える.
* 元のtoが0以外でも使える
*/
inline Move newAddTo(Offset o) const{
return makeDirect(intValue()+o.intValue());
}
/**
* つくってあったmoveの雛形のsquareをsetする.
* mのtoは0
*/
inline Move newAddTo(Square sq) const{
assert((intValue()&0xff)==0);
return Move::makeDirect(intValue()+sq.uintValue());
}
/**
* 作ってあったPTYPE_EMPTYのひな形のPTYPEをsetする
*/
inline Move newAddPtype(Ptype newPtype) const{
assert(ptype()==PTYPE_EMPTY);
return Move::makeDirect(intValue()
+ (static_cast<unsigned int>(newPtype)<<24));
}
template<Player P>
static bool ignoreUnpromote(Ptype ptype,Square from,Square to){
switch(ptype){
case PAWN:
return to.canPromote<P>();
case BISHOP: case ROOK:
return to.canPromote<P>() || from.canPromote<P>();
case LANCE:
return (P==BLACK ? to.y()==2 : to.y()==8);
default: return false;
}
}
/**
* 合法手ではあるが,打歩詰め絡み以外では有利にはならない手.
* TODO 遅い
*/
template<Player P>
bool ignoreUnpromote() const{
assert(player()==P);
if(isDrop()) return false;
return ignoreUnpromote<P>(ptype(),from(),to());
}
bool ignoreUnpromote() const{
if(player()==BLACK) return ignoreUnpromote<BLACK>();
else return ignoreUnpromote<WHITE>();
}
/**
* MoveをunpromoteするとcutUnpromoteなMoveになる
*/
template<Player P>
bool hasIgnoredUnpromote() const{
assert(player()==P);
if(!isPromotion()) return false;
switch(ptype()){
case PPAWN:
return (P==BLACK ? to().y()!=1 : to().y()!=9);
case PLANCE:
return (P==BLACK ? to().y()==2 : to().y()==8);
case PBISHOP: case PROOK:
return true;
default: return false;
}
}
bool hasIgnoredUnpromote() const{
if(player()==BLACK) return hasIgnoredUnpromote<BLACK>();
else return hasIgnoredUnpromote<WHITE>();
}
const Move rotate180() const;
};
inline bool operator<(Move lhs, Move rhs)
{
#ifdef PRESERVE_MOVE_ORDER
int l=lhs.intValue();
l=(l&0xffff0000)+((l>>8)&0xff)+((l<<8)&0xff00);
int r=rhs.intValue();
r=(r&0xffff0000)+((r>>8)&0xff)+((r<<8)&0xff00);
return l<r;
#else
return lhs.intValue() < rhs.intValue();
#endif
}
inline bool operator==(Move lhs, Move rhs)
{
return lhs.intValue() == rhs.intValue();
}
inline bool operator!=(Move lhs, Move rhs)
{
return ! (lhs == rhs);
}
std::ostream& operator<<(std::ostream& os, Move move);
namespace stl
{
template <typename T> struct hash;
template <> struct hash<Move>
{
unsigned long operator()(Move m) const { return m.intValue(); }
};
} // namespace stl
}
#endif /* OSL_MOVE_H */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
|