Go to the documentation of this file.00001
00002
00003 #ifndef OSL_SIMPLE_STATE_H
00004 #define OSL_SIMPLE_STATE_H
00005
00006 #include "osl/misc/loki.h"
00007 #include "osl/direction.h"
00008 #include "osl/boardTable.h"
00009 #include "osl/ptype.h"
00010 #include "osl/ptypeTraits.h"
00011 #include "osl/piece.h"
00012 #include "osl/container/pieceMask.h"
00013 #include "osl/container/bitXmask.h"
00014 #include "osl/effectContent.h"
00015 #include "osl/move.h"
00016 #include "osl/player.h"
00017 #include "osl/handicap.h"
00018 #include "osl/misc/carray.h"
00019 #include "osl/effect_action/pieceFilter.h"
00020 #include "osl/ptypeTable.h"
00021
00022 #include <iosfwd>
00023
00024 namespace osl
00025 {
00026 namespace state
00027 {
00028 class SimpleState;
00029 std::ostream& operator<<(std::ostream& os,const SimpleState& state);
00035 bool operator==(const SimpleState& st1,const SimpleState& st2);
00036
00037 class SimpleState
00038 {
00039 private:
00040 friend std::ostream& operator<<(std::ostream& os,const SimpleState& state);
00041 friend bool operator==(const SimpleState& st1,const SimpleState& st2);
00042 typedef SimpleState state_t;
00043 public:
00044 static const bool hasPawnMask=true;
00045 protected:
00046 CArray<Piece,Square::SIZE> board
00047 #ifdef __GNUC__
00048 __attribute__((aligned(16)))
00049 #endif
00050 ;
00054 CArray<Piece,Piece::SIZE> pieces
00055 #ifdef __GNUC__
00056 __attribute__((aligned(16)))
00057 #endif
00058 ;
00059 CArray<PieceMask,2> stand_mask;
00060 CArray<BitXmask,2> pawnMask;
00061 CArray<CArray<char,PTYPE_SIZE-PTYPE_BASIC_MIN>,2> stand_count;
00062
00064 Player player_to_move;
00065 PieceMask used_mask;
00066 public:
00067
00068 explicit SimpleState();
00069 explicit SimpleState(Handicap h);
00070
00071 virtual ~SimpleState();
00073 void init();
00075 void init(Handicap h);
00076
00077 void initPawnMask();
00078 public:
00079 const Piece pieceOf(int num) const{
00080 return pieces[num];
00081 }
00082 void setPieceOf(int num,Piece p) {
00083 pieces[num]=p;
00084 }
00085 template<Player P>
00086 const Piece kingPiece() const{
00087 return pieceOf(KingTraits<P>::index);
00088 }
00089 const Piece kingPiece(Player P) const{
00090 assert(isValid(P));
00091 if (P==BLACK)
00092 return kingPiece<BLACK>();
00093 else
00094 return kingPiece<WHITE>();
00095 }
00096 template<Player P>
00097 Square kingSquare() const{
00098 return kingPiece<P>().square();
00099 }
00100 Square kingSquare(Player player) const{
00101 assert(isValid(player));
00102 if (player==BLACK)
00103 return kingSquare<BLACK>();
00104 else
00105 return kingSquare<WHITE>();
00106 }
00107 template <Ptype PTYPE>
00108 static int nthLimit() {
00109 return PtypeTraits<PTYPE>::indexLimit - PtypeTraits<PTYPE>::indexMin;
00110 }
00116 template <Ptype PTYPE>
00117 const Piece nth(int n) const {
00118 assert(0 <= n && n < nthLimit<PTYPE>());
00119 return pieceOf(PtypeTraits<PTYPE>::indexMin+n);
00120 }
00121
00122 void setBoard(Square sq,Piece piece)
00123 {
00124 board[sq.index()]=piece;
00125 }
00126 protected:
00127 PieceMask& standMask(Player p) {
00128 return stand_mask[p];
00129 }
00130 public:
00131 const PieceMask& standMask(Player p) const {
00132 return stand_mask[p];
00133 }
00134 const PieceMask& usedMask() const {return used_mask;}
00135 bool isOffBoard(int num) const{
00136 return standMask(BLACK).test(num)
00137 || standMask(WHITE).test(num);
00138 }
00139
00141 void clearPawn(Player pl,Square sq){
00142 pawnMask[pl].clear(sq);
00143 }
00145 void setPawn(Player pl,Square sq){
00146 pawnMask[pl].set(sq);
00147 }
00148 public:
00149 bool isPawnMaskSet(Player player, int x) const
00150 {
00151 return pawnMask[player].isSet(x);
00152 }
00153
00154 template<Player P>
00155 bool isPawnMaskSet(int x)const {return isPawnMaskSet(P,x); }
00156
00158 bool canDropPawnTo(Player player, int x) const
00159 {
00160 return hasPieceOnStand<PAWN>(player) && ! isPawnMaskSet(player, x);
00161 }
00162
00163 void setPiece(Player player,Square sq,Ptype ptype);
00164 void setPieceAll(Player player);
00165
00170 const Piece pieceAt(Square sq) const { return board[sq.index()];}
00171 const Piece operator[](Square sq) const { return pieceAt(sq);}
00172 const Piece* getPiecePtr(Square sq) const { return &board[sq.index()];}
00173 const Piece pieceOnBoard(Square sq) const
00174 {
00175 assert(sq.isOnBoard());
00176 return pieceAt(sq);
00177 }
00178
00179 bool isOnBoard(int num) const {
00180 return pieceOf(num).isOnBoard();
00181 }
00185 int countPiecesOnStand(Player pl,Ptype ptype) const {
00186 assert(isBasic(ptype));
00187 return stand_count[pl][ptype-PTYPE_BASIC_MIN];
00188 }
00190 template <Ptype Type>
00191 int countPiecesOnStand(Player pl) const {
00192 return countPiecesOnStand(pl, Type);
00193 }
00194 bool hasPieceOnStand(Player player,Ptype ptype) const{
00195 return countPiecesOnStand(player, ptype)!=0;
00196 }
00197 template<Ptype T>
00198 bool hasPieceOnStand(Player P) const {
00199 return countPiecesOnStand(P, T);
00200 }
00201 private:
00202 int countPiecesOnStandBit(Player pl,Ptype ptype) const {
00203 return (standMask(pl).getMask(Ptype_Table.getIndex(ptype))
00204 & Ptype_Table.getMaskLow(ptype)).countBit();
00205 }
00206 public:
00211 Piece nextPiece(Square cur, Offset diff) const
00212 {
00213 assert(! diff.zero());
00214 cur += diff;
00215 while (pieceAt(cur) == Piece::EMPTY())
00216 cur += diff;
00217 return pieceAt(cur);
00218 }
00219
00220 void setTurn(Player player) {
00221 player_to_move=player;
00222 }
00223 Player turn() const{
00224 return player_to_move;
00225 }
00229 void changeTurn() {
00230 player_to_move = alt(player_to_move);
00231 }
00232
00233 bool isConsistent(bool show_error=true) const;
00235 template <bool show_error>
00236 bool isAlmostValidMove(Move move) const;
00244 bool isAlmostValidMove(Move move,bool show_error=true) const;
00251 bool isValidMove(Move move,bool show_error=true) const;
00252 protected:
00253 template <bool show_error> bool isAlmostValidDrop(Move move) const;
00254 template <bool show_error> bool testValidityOtherThanEffect(Move move) const;
00255 public:
00260 static bool isValidMoveByRule(Move move,bool show_error);
00261
00270 bool isEmptyBetween(Square from, Square to,Offset offset,bool pieceExistsAtTo=false) const
00271 #ifdef __GNUC__
00272 __attribute__ ((pure))
00273 #endif
00274 {
00275 assert(from.isOnBoard());
00276 assert(! offset.zero());
00277 assert(offset==Board_Table.getShortOffset(Offset32(to,from)));
00278 Square sq=from+offset;
00279 for (; pieceAt(sq).isEmpty(); sq+=offset) {
00280 if (!pieceExistsAtTo && sq==to)
00281 return true;
00282 }
00283 return sq==to;
00284
00285 }
00292 bool
00293 #ifdef __GNUC__
00294 __attribute__ ((pure))
00295 #endif
00296 isEmptyBetween(Square from, Square to,bool noSpaceAtTo=false) const{
00297 assert(from.isOnBoard());
00298 Offset offset=Board_Table.getShortOffset(Offset32(to,from));
00299 assert(! offset.zero());
00300 return isEmptyBetween(from,to,offset,noSpaceAtTo);
00301 }
00302
00304 bool dump() const;
00308 const SimpleState emulateCapture(Piece from, Player new_owner) const;
00309
00313 const SimpleState emulateHandPiece(Player from, Player to, Ptype ptype) const;
00314 const SimpleState rotate180() const;
00315 const SimpleState flipHorizontal() const;
00316 };
00317 }
00318 using state::SimpleState;
00319
00320 }
00321
00322 #endif
00323
00324
00325
00326