00001
00002
00003 #ifndef _SIMPLE_STATE_H
00004 #define _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/apply_move/applyDoUndoXMove.h"
00021 #include "osl/misc/fastCopier.h"
00022 #include "osl/ptypeTable.h"
00023
00024 #include <iosfwd>
00025
00026 namespace osl
00027 {
00028 namespace state
00029 {
00030 class SimpleState;
00031 std::ostream& operator<<(std::ostream& os,const SimpleState& state);
00037 bool operator==(const SimpleState& st1,const SimpleState& st2);
00038
00039 class SimpleState
00040 {
00041 private:
00042 friend std::ostream& operator<<(std::ostream& os,const SimpleState& state);
00043 friend bool operator==(const SimpleState& st1,const SimpleState& st2);
00044 typedef SimpleState state_t;
00045 public:
00046 static const bool hasPawnMask=true;
00047 protected:
00048 CArray<Piece,Position::SIZE> board
00049 #ifdef __GNUC__
00050 __attribute__((aligned(16)))
00051 #endif
00052 ;
00056 CArray<Piece,Piece::SIZE> pieces
00057 #ifdef __GNUC__
00058 __attribute__((aligned(16)))
00059 #endif
00060 ;
00061 CArray<PieceMask,2> stand_mask;
00062 CArray<BitXmask,2> pawnMask;
00063 CArray<CArray<char,PTYPE_SIZE-PTYPE_BASIC_MIN>,2> stand_count;
00064
00066 Player turn;
00067 PieceMask used_mask;
00068
00069 friend class osl::apply_move::ApplyDoUndoSimpleMove<BLACK,SimpleState>;
00070 friend class osl::apply_move::ApplyDoUndoSimpleMove<WHITE,SimpleState>;
00071 friend class osl::apply_move::ApplyDoUndoCaptureMove<BLACK,SimpleState>;
00072 friend class osl::apply_move::ApplyDoUndoCaptureMove<WHITE,SimpleState>;
00073 friend class osl::apply_move::ApplyDoUndoDropMove<BLACK,SimpleState>;
00074 friend class osl::apply_move::ApplyDoUndoDropMove<WHITE,SimpleState>;
00075 friend class osl::misc::FastCopier;
00076 public:
00077
00078 explicit SimpleState();
00079 explicit SimpleState(Handicap h);
00080
00081 virtual ~SimpleState();
00083 void init();
00085 void init(Handicap h);
00086
00087 void initPawnMask();
00088 public:
00089 const Piece getPieceOf(int num) const{
00090 return pieces[num];
00091 }
00092 void setPieceOf(int num,Piece p) {
00093 pieces[num]=p;
00094 }
00095 template<Player P>
00096 const Piece getKingPiece() const{
00097 return getPieceOf(KingTraits<P>::index);
00098 }
00099 const Piece getKingPiece(Player P) const{
00100 assert(isValid(P));
00101 if (P==BLACK)
00102 return getKingPiece<BLACK>();
00103 else
00104 return getKingPiece<WHITE>();
00105 }
00106 template<Player P>
00107 Position getKingPosition() const{
00108 return getKingPiece<P>().position();
00109 }
00110 Position getKingPosition(Player player) const{
00111 assert(isValid(player));
00112 if (player==BLACK)
00113 return getKingPosition<BLACK>();
00114 else
00115 return getKingPosition<WHITE>();
00116 }
00117
00118 void setBoard(Position pos,Piece piece)
00119 {
00120 board[pos.index()]=piece;
00121 }
00122 protected:
00123 PieceMask& standMask(Player p) {
00124 return stand_mask[p];
00125 }
00126 public:
00127 const PieceMask& standMask(Player p) const {
00128 return stand_mask[p];
00129 }
00130 const PieceMask& usedMask() const {return used_mask;}
00131 bool isOffBoard(int num) const{
00132 return standMask(BLACK).test(num)
00133 || standMask(WHITE).test(num);
00134 }
00135
00137 void clearPawn(Player pl,Position pos){
00138 pawnMask[pl].clear(pos);
00139 }
00141 void setPawn(Player pl,Position pos){
00142 pawnMask[pl].set(pos);
00143 }
00144 public:
00145 bool isPawnMaskSet(Player player, int x) const
00146 {
00147 return pawnMask[player].isSet(x);
00148 }
00149
00150 template<Player P>
00151 bool isPawnMaskSet(int x)const {return isPawnMaskSet(P,x); }
00152
00153 void setPiece(Player player,Position pos,Ptype ptype);
00154 void setPieceAll(Player player);
00155
00160 const Piece getPieceAt(Position pos) const { return board[pos.index()];}
00161 const Piece* getPiecePtr(Position pos) const { return &board[pos.index()];}
00162 const Piece getPieceOnBoard(Position pos) const
00163 {
00164 assert(pos.isOnBoard());
00165 return getPieceAt(pos);
00166 }
00167
00168 bool isOnBoard(int num) const {
00169 return getPieceOf(num).isOnBoard();
00170 }
00174 int countPiecesOnStand(Player pl,Ptype ptype) const {
00175 assert(isBasic(ptype));
00176 return stand_count[pl][ptype-PTYPE_BASIC_MIN];
00177 }
00179 template <Ptype Type>
00180 int countPiecesOnStand(Player pl) const {
00181 return countPiecesOnStand(pl, Type);
00182 }
00183 bool hasPieceOnStand(Player player,Ptype ptype) const{
00184 return countPiecesOnStand(player, ptype)!=0;
00185 }
00186 template<Ptype T>
00187 bool hasPieceOnStand(Player P) const {
00188 return countPiecesOnStand(P, T);
00189 }
00190 private:
00191 int countPiecesOnStandBit(Player pl,Ptype ptype) const {
00192 return (standMask(pl).getMask(Ptype_Table.getIndex(ptype))
00193 & Ptype_Table.getMaskLow(ptype)).countBit();
00194 }
00195 public:
00200 Piece nextPiece(Position cur, Offset diff) const
00201 {
00202 assert(! diff.zero());
00203 cur += diff;
00204 while (getPieceAt(cur) == Piece::EMPTY())
00205 cur += diff;
00206 return getPieceAt(cur);
00207 }
00208
00209 void setTurn(Player player) {
00210 turn=player;
00211 }
00212 Player getTurn() const{
00213 return turn;
00214 }
00218 void changeTurn() {
00219 osl::changeTurn(turn);
00220 }
00221 void makeMovePass() { changeTurn(); }
00222
00223
00224 bool isConsistent(bool showError=true) const;
00226 template <bool showError>
00227 bool isAlmostValidMove(Move move) const;
00235 bool isAlmostValidMove(Move move,bool showError=true) const;
00242 bool isValidMove(Move move,bool showError=true) const;
00243
00249 bool isValidMoveByRule(Move move,bool showError) const;
00250
00259 bool isEmptyBetween(Position from, Position to,Offset offset,bool pieceExistsAtTo=false) const
00260 {
00261 assert(from.isOnBoard());
00262 assert(! offset.zero());
00263 assert(offset==Board_Table.getShortOffset(Offset32(to,from)));
00264 Position pos=from+offset;
00265 for (; getPieceAt(pos).isEmpty(); pos+=offset) {
00266 if (!pieceExistsAtTo && pos==to)
00267 return true;
00268 }
00269 return pos==to;
00270
00271 }
00278 bool isEmptyBetween(Position from, Position to,bool noSpaceAtTo=false) const{
00279 assert(from.isOnBoard());
00280 Offset offset=Board_Table.getShortOffset(Offset32(to,from));
00281 assert(! offset.zero());
00282 return isEmptyBetween(from,to,offset,noSpaceAtTo);
00283 }
00284
00286 bool dump() const;
00287 void doSimpleMove(Position from, Position to, int promoteMask);
00288 void doDropMove(Position to,Ptype ptype);
00289 void doCaptureMove(Position from, Position to, Piece target,int promoteMask);
00293 const SimpleState emulateCapture(Piece from, Player new_owner) const;
00294
00298 const SimpleState emulateHandPiece(Player from, Player to, Ptype ptype) const;
00299 const SimpleState rotate180() const;
00300 const SimpleState flipHorizontal() const;
00301 };
00302 }
00303 using state::SimpleState;
00304
00305 namespace apply_move
00306 {
00307 template<Player P>
00308 struct ApplyDoUndoSimpleMove<P,state::SimpleState>
00309 {
00310 static void prologue(state::SimpleState& s,
00311 Position from, Position to, int promoteMask,
00312 Piece& oldPiece, int& num)
00313 {
00314 oldPiece=s.getPieceAt(from);
00315 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
00316 newPiece+=(to-from);
00317 num=oldPiece.number();
00318 s.setPieceOf(num,newPiece);
00319 s.setBoard(to,newPiece);
00320 s.setBoard(from,Piece::EMPTY());
00321 }
00322 static void epilogue(state::SimpleState& s, Position from, Position to,
00323 Piece oldPiece, int num)
00324 {
00325
00326 s.setPieceOf(num,oldPiece);
00327 s.setBoard(from,oldPiece);
00328 s.setBoard(to,Piece::EMPTY());
00329 }
00330 template <typename F>
00331 static void doUndoSimpleMove(state::SimpleState& s,
00332 Position from, Position to, int promoteMask,F& func);
00333 };
00334
00335 template<Player P>
00336 template <typename F>
00337 void ApplyDoUndoSimpleMove<P,state::SimpleState>::
00338 doUndoSimpleMove(state::SimpleState& s,
00339 Position from, Position to, int promoteMask,F& func)
00340 {
00341 Piece oldPiece;
00342 int num;
00343 prologue(s, from, to, promoteMask, oldPiece, num);
00344 if (promoteMask!=0 && num < PtypeTraits<PAWN>::indexLimit)
00345 {
00346 s.clearPawn(P,from);
00347 s.changeTurn();
00348 func(to);
00349 s.changeTurn();
00350 s.setPawn(P,from);
00351 }
00352 else{
00353 s.changeTurn();
00354 func(to);
00355 s.changeTurn();
00356 }
00357 epilogue(s, from, to, oldPiece, num);
00358 }
00359
00360 template<Player P>
00361 struct ApplyDoUndoDropMove<P,state::SimpleState>
00362 {
00363 typedef state::SimpleState state_t;
00364
00369 static void prologue(state::SimpleState& s, Ptype ptype, Position to,
00370 Piece& oldPiece, int& num, int& numIndex, int& numLow)
00371 {
00372 #if OSL_WORDSIZE == 64
00373 numIndex=0;
00374 const mask_t ownMochigoma=
00375 s.standMask(P).getMask(0) & Ptype_Table.getMaskLow(ptype);
00376 assert(ownMochigoma.any() || (s.dump(), 0));
00377 num=numLow=ownMochigoma.bsf();
00378 #elif OSL_WORDSIZE == 32
00379 numIndex=Ptype_Table.getIndex(ptype);
00380 const mask_t ownMochigoma=
00381 s.standMask(P).getMask(numIndex) & Ptype_Table.getMaskLow(ptype);
00382 assert(ownMochigoma.any() || (s.dump(), 0));
00383 numLow=ownMochigoma.bsf();
00384 num=numLow|(numIndex<<5);
00385 #endif
00386 oldPiece=s.getPieceOf(num);
00387 Piece p=oldPiece;
00388 p += to-Position::STAND();
00389
00390 s.setPieceOf(num,p);
00391 s.setBoard(to,p);
00392 s.standMask(P).xorMask(numIndex,PieceMask::numToMask(numLow));
00393 s.stand_count[P][ptype-PTYPE_BASIC_MIN]--;
00394 }
00395
00396 static void epilogue(state::SimpleState& s, Ptype ptype, Position to,
00397 Piece oldPiece, int num,
00398 int numIndex, int numLow)
00399 {
00400 s.standMask(P).xorMask(numIndex,PieceMask::numToMask(numLow));
00401 s.setBoard(to,Piece::EMPTY());
00402 s.setPieceOf(num,oldPiece);
00403 s.stand_count[P][ptype-PTYPE_BASIC_MIN]++;
00404 }
00405 template <typename F>
00406 static void doUndoDropMove(state::SimpleState& s,
00407 Position to, Ptype ptype,F& func);
00408 };
00409
00410
00411 template<Player P>
00412 template <typename F>
00413 void ApplyDoUndoDropMove<P,state::SimpleState>::
00414 doUndoDropMove(state::SimpleState& s,
00415 Position to, Ptype ptype,F& func)
00416 {
00417 Piece oldPiece;
00418 int num, numIndex, numLow;
00419 prologue(s, ptype, to, oldPiece, num, numIndex, numLow);
00420
00421 if (ptype==PAWN)
00422 {
00423 s.setPawn(P,to);
00424 s.changeTurn();
00425 func(to);
00426 s.changeTurn();
00427 s.clearPawn(P,to);
00428 }
00429 else
00430 {
00431 s.changeTurn();
00432 func(to);
00433 s.changeTurn();
00434 }
00435 epilogue(s, ptype, to, oldPiece, num, numIndex, numLow);
00436 }
00437
00438 template<Player P>
00439 struct ApplyDoUndoCaptureMove<P,state::SimpleState>
00440 {
00441 typedef state::SimpleState state_t;
00442 template <typename F>
00443 static void doUndoCaptureMove(state_t& s,
00444 Position from,Position to, Piece p1, int promoteMask,F& func);
00445
00446 static
00447 void prologue(state::SimpleState& s,
00448 Position from, Position to, Piece target, int promoteMask,
00449 Ptype& capturePtype, Piece& oldPiece, int& num0,
00450 int& num1, int& num1Index, mask_t& num1Mask)
00451 {
00452 capturePtype=target.ptype();
00453 num1=target.number();
00454 num1Index=PieceMask::numToIndex(num1);
00455 num1Mask=PieceMask::numToMask(num1);
00456
00457 s.standMask(P).xorMask(num1Index,num1Mask);
00458 oldPiece=s.getPieceAt(from);
00459 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
00460 newPiece+=(to-from);
00461 num0=oldPiece.number();
00462 s.setPieceOf(num0,newPiece);
00463 s.setPieceOf(num1,target.captured());
00464 s.setBoard(to,newPiece);
00465 s.setBoard(from,Piece::EMPTY());
00466 s.stand_count[P][unpromote(capturePtype)-PTYPE_BASIC_MIN]++;
00467 }
00468
00469 static
00470 void epilogue(state::SimpleState& s, Position from, Position to, Piece target,
00471 Ptype capturePtype, Piece oldPiece, int num0,
00472 int num1, int num1Index, mask_t num1Mask)
00473 {
00474 s.standMask(P).xorMask(num1Index,num1Mask);
00475 s.setPieceOf(num0,oldPiece);
00476 s.setPieceOf(num1,target);
00477 s.setBoard(from,oldPiece);
00478 s.setBoard(to,target);
00479 s.stand_count[P][unpromote(capturePtype)-PTYPE_BASIC_MIN]--;
00480 }
00481 };
00482
00483
00484 template<Player P>
00485 template <typename F>
00486 void ApplyDoUndoCaptureMove<P,state::SimpleState>::
00487 doUndoCaptureMove(state_t& s,
00488 Position from,Position to, Piece target, int promoteMask,F& func)
00489 {
00490 Piece oldPiece;
00491 int num0, num1;
00492 int num1Index;
00493 mask_t num1Mask;
00494 Ptype capturePtype;
00495 prologue(s, from, to, target, promoteMask,
00496 capturePtype, oldPiece, num0, num1, num1Index, num1Mask);
00497 s.changeTurn();
00498 if (capturePtype==PAWN){
00499 s.clearPawn(PlayerTraits<P>::opponent,to);
00500 if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit){
00501 s.clearPawn(P,from);
00502 func(to);
00503 s.setPawn(P,from);
00504 }
00505 else{
00506 func(to);
00507 }
00508 s.setPawn(PlayerTraits<P>::opponent,to);
00509 }
00510 else if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit){
00511 s.clearPawn(P,from);
00512 func(to);
00513 s.setPawn(P,from);
00514 }
00515 else{
00516 func(to);
00517 }
00518 s.changeTurn();
00519
00520 epilogue(s, from, to, target, capturePtype, oldPiece, num0, num1, num1Index, num1Mask);
00521 }
00522 }
00523 }
00524
00525 #endif
00526
00527
00528
00529