00001 #ifndef _MOVE_H
00002 #define _MOVE_H
00003 #include "osl/player.h"
00004 #include "osl/ptype.h"
00005 #include "osl/position.h"
00006 #include <iosfwd>
00007
00009
00010 #ifdef MOVE_DEBUG
00011 # include <cassert>
00012 # define move_assert(x) assert(x)
00013 #else
00014 # define move_assert(x)
00015 #endif
00016
00017 namespace osl
00018 {
00035 class Move
00036 {
00037 int move;
00038 explicit Move(int value) : move(value)
00039 {
00040 }
00041 enum {
00042 INVALID_VALUE = 1, DECLARE_WIN = 2,
00043 BLACK_PASS = 0, WHITE_PASS = (-1)<<28,
00044 };
00045 public:
00046 int intValue() const { return move; }
00050 static const unsigned int MaxUniqMoves=600;
00051 private:
00052 void init(Position from, Position to, Ptype ptype,
00053 Ptype capture_ptype, bool is_promote, Player player)
00054 {
00055 move = (from.uintValue()
00056 | (to.uintValue() <<8)
00057 | (static_cast<unsigned int>(is_promote)<<19)
00058 | (static_cast<unsigned int>(capture_ptype)<<20)
00059 | (static_cast<unsigned int>(ptype)<<24)
00060 | (static_cast<int>(player)<<28));
00061 }
00062 public:
00063 Move() : move(INVALID_VALUE)
00064 {
00065 }
00067 bool isNormal() const {
00068
00069 return move & 0xff00;
00070 }
00071 bool isPass() const { return (move & 0xffff) == 0; }
00072 static const Move makeDirect(int value) { return Move(value); }
00073 static const Move PASS(Player P) { return Move(P<<28); }
00074 static const Move INVALID() { return Move(INVALID_VALUE); }
00075 static const Move DeclareWin() { return Move(DECLARE_WIN); }
00079 Move(Position from, Position to, Ptype ptype,
00080 Ptype capture_ptype, bool is_promote, Player player)
00081 {
00082 move_assert(from.isValid());
00083 move_assert(to.isOnBoard());
00084 move_assert(isValid(ptype));
00085 move_assert(isValid(capture_ptype));
00086 move_assert(isValid(player));
00087 init(from, to, ptype, capture_ptype, is_promote, player);
00088 move_assert(isValid());
00089 }
00093 Move(Position to, Ptype ptype, Player player)
00094 {
00095 move_assert(to.isOnBoard());
00096 move_assert(isValid(ptype));
00097 move_assert(isValid(player));
00098 init(Position::STAND(), to, ptype, PTYPE_EMPTY, false, player);
00099 move_assert(isValid());
00100 }
00101
00102 const Position from() const
00103 {
00104 assert(! isInvalid());
00105 move_assert(isValidOrPass());
00106 const Position result = Position::makeDirect(move & 0xff);
00107 return result;
00108 }
00109 const Position to() const {
00110 assert(! isInvalid());
00111 move_assert(isValidOrPass());
00112 const Position result = Position::makeDirect((move >> 8) & 0xff);
00113 return result;
00114 }
00115 int promoteMask() const {
00116 assert(isNormal());
00117 return (static_cast<int>(move)&(1<<19));
00118 }
00119 static int promoteMask(bool is_promote) {
00120 return is_promote<<19;
00121 }
00122 bool isPromote() const { assert(isNormal()); return (move & (1<<19)); }
00123 bool isDrop() const { assert(isNormal()); return from().isPieceStand(); }
00124
00125 Ptype ptype() const {
00126 assert(! isInvalid());
00127 move_assert(isValidOrPass());
00128 const Ptype result = static_cast<Ptype>((move >> 24) & 0xf);
00129 return result;
00130 }
00132 PtypeO ptypeO() const {
00133 assert(! isInvalid());
00134 const PtypeO result = static_cast<PtypeO>(move >> 24);
00135 return result;
00136 }
00138 PtypeO oldPtypeO() const {
00139 assert(! isInvalid());
00140 const PtypeO result = static_cast<PtypeO>((move>>24)+((move >> (19-3))&8));
00141 return result;
00142 }
00144 Ptype oldPtype() const {
00145 assert(! isInvalid());
00146 move_assert(isValidOrPass());
00147 const PtypeO old_ptypeo = static_cast<PtypeO>((move>>24)+((move >> (19-3))&8));
00148 return getPtype(old_ptypeo);
00149 }
00150 Ptype capturePtype() const {
00151 assert(isNormal());
00152 const Ptype result = static_cast<Ptype>((move>>20)&0xf);
00153 return result;
00154 }
00155 PtypeO capturePtypeO() const {
00156 assert(capturePtype() != PTYPE_EMPTY);
00157 return newPtypeO(alt(player()), capturePtype());
00158 }
00159 PtypeO capturePtypeOSafe() const {
00160 if (capturePtype() == PTYPE_EMPTY)
00161 return PTYPEO_EMPTY;
00162 return capturePtypeO();
00163 }
00164
00165 Player player() const {
00166 assert(! isInvalid());
00167 const Player result = static_cast<Player>(move>>28);
00168 return result;
00169 }
00170
00171 const Move noPromote() const {
00172 assert(isNormal());
00173 move_assert(move.isPromote() && isPromoted(move.ptype()));
00174 return Move(move^((1<<19)|(1<<27)));
00175 }
00176 void setCapturePtype(Ptype capture_ptype)
00177 {
00178 assert(isNormal());
00179 unsigned int result = static_cast<unsigned int>(move);
00180 result &= ~(15 << 20);
00181 result += static_cast<unsigned int>(capture_ptype) << 20;
00182 move = result;
00183 }
00184 void setFrom(Position new_from)
00185 {
00186 assert(isNormal());
00187 unsigned int result = static_cast<unsigned int>(move);
00188 result &= ~(0xff);
00189 result += new_from.uintValue();
00190 move = result;
00191 }
00192
00193 bool isValid() const;
00195 bool isInvalid() const {
00196 return static_cast<unsigned int>(move-1) < DECLARE_WIN;
00197 }
00198 bool isValidOrPass() const { return isPass() || isValid(); }
00199 };
00200
00201 inline bool operator<(Move lhs, Move rhs)
00202 {
00203 return lhs.intValue() < rhs.intValue();
00204 }
00205 inline bool operator==(Move lhs, Move rhs)
00206 {
00207 return lhs.intValue() == rhs.intValue();
00208 }
00209 inline bool operator!=(Move lhs, Move rhs)
00210 {
00211 return ! (lhs == rhs);
00212 }
00213
00214 std::ostream& operator<<(std::ostream& os, Move move);
00215 }
00216 #endif
00217
00218
00219
00220