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/effectContent.h"
00014 #include "osl/move.h"
00015 #include "osl/player.h"
00016 #include "osl/handicap.h"
00017 #include "osl/misc/carray.h"
00018 #include "osl/effect_action/pieceFilter.h"
00019 #include "osl/apply_move/applyDoUndoXMove.h"
00020 #include "osl/apply_move/doUndoMoveLockForward.h"
00021 #include "osl/ptypeTable.h"
00022
00023 #include <iosfwd>
00024
00025 namespace osl
00026 {
00027 namespace state
00028 {
00029 class SimpleState;
00030 std::ostream& operator<<(std::ostream& os,const SimpleState& state);
00031 bool operator==(const SimpleState& st1,const SimpleState& st2);
00032
00033 class SimpleState
00034 {
00038 class NotEmpty{
00039 public:
00040 bool operator()(Position) const{ return false; }
00041 };
00042 public:
00044 typedef SimpleState simple_board_t;
00045 typedef SimpleState simple_state_t;
00046 typedef SimpleState effect_state_t;
00047 private:
00048 friend std::ostream& operator<<(std::ostream& os,const SimpleState& state);
00049 friend bool operator==(const SimpleState& st1,const SimpleState& st2);
00050 typedef SimpleState state_t;
00051 public:
00052 static const bool hasPawnMask=false;
00053 protected:
00054 PieceMask used_mask;
00055 CArray<PieceMask,2> stand_mask;
00056 CArray<Piece,Position::SIZE> board;
00060 CArray<Piece,Piece::SIZE> pieces;
00061
00063 Player turn;
00064
00065 friend class osl::apply_move::ApplyDoUndoSimpleMove<BLACK,SimpleState>;
00066 friend class osl::apply_move::ApplyDoUndoSimpleMove<WHITE,SimpleState>;
00067 friend class osl::apply_move::ApplyDoUndoCaptureMove<BLACK,SimpleState>;
00068 friend class osl::apply_move::ApplyDoUndoCaptureMove<WHITE,SimpleState>;
00069 friend class osl::apply_move::ApplyDoUndoDropMove<BLACK,SimpleState>;
00070 friend class osl::apply_move::ApplyDoUndoDropMove<WHITE,SimpleState>;
00071 friend class osl::apply_move::DoUndoMoveLockSimple<SimpleState>;
00072 friend class osl::apply_move::DoUndoMoveLockCapture<SimpleState>;
00073 friend class osl::apply_move::DoUndoMoveLockDrop<SimpleState>;
00074 public:
00075
00076 explicit SimpleState();
00077 explicit SimpleState(Handicap h);
00078
00079 virtual ~SimpleState();
00081 void init();
00083 void init(Handicap h);
00084 const Piece getPieceOf(int num) const{
00085 return pieces[num];
00086 }
00087 void setPieceOf(int num,Piece p) {
00088 pieces[num]=p;
00089 }
00090 template<Player P>
00091 const Piece getKingPiece() const{
00092 return getPieceOf(KingTraits<P>::index);
00093 }
00094 const Piece getKingPiece(Player P) const{
00095 assert(isValid(P));
00096 if (P==BLACK)
00097 return getKingPiece<BLACK>();
00098 else
00099 return getKingPiece<WHITE>();
00100 }
00101 template<Player P>
00102 Position getKingPosition() const{
00103 return getKingPiece<P>().position();
00104 }
00105 Position getKingPosition(Player player) const{
00106 assert(isValid(player));
00107 if (player==BLACK)
00108 return getKingPosition<BLACK>();
00109 else
00110 return getKingPosition<WHITE>();
00111 }
00112
00113 void setBoard(Position pos,Piece piece)
00114 {
00115 board[pos.index()]=piece;
00116 }
00117 protected:
00118 PieceMask& standMask(Player p) {
00119 return stand_mask[playerToIndex(p)];
00120 }
00121 public:
00122 const PieceMask& standMask(Player p) const {
00123 return stand_mask[playerToIndex(p)];
00124 }
00125 const PieceMask& usedMask() const {return used_mask;}
00126 bool isOffBoard(int num) const{
00127 return standMask(BLACK).test(num)
00128 || standMask(WHITE).test(num);
00129 }
00130
00131 template<Player P>
00132 bool isPawnMaskSet(int x) const{
00133 Position pos(x,(P==BLACK ? 2 : 1));
00134 Piece p1=getPieceAt(pos);
00135 Piece p2=getPieceAt(pos+DirectionTraits<D>::blackOffset());
00136 Piece p3=getPieceAt(pos+DirectionTraits<D>::blackOffset()*2);
00137 Piece p4=getPieceAt(pos+DirectionTraits<D>::blackOffset()*3);
00138 Piece p5=getPieceAt(pos+DirectionTraits<D>::blackOffset()*4);
00139 Piece p6=getPieceAt(pos+DirectionTraits<D>::blackOffset()*5);
00140 Piece p7=getPieceAt(pos+DirectionTraits<D>::blackOffset()*6);
00141 Piece p8=getPieceAt(pos+DirectionTraits<D>::blackOffset()*7);
00142 return (p1.ptypeOMask(newPtypeO(P,PAWN))
00143 & p2.ptypeOMask(newPtypeO(P,PAWN))
00144 & p3.ptypeOMask(newPtypeO(P,PAWN))
00145 & p4.ptypeOMask(newPtypeO(P,PAWN))
00146 & p5.ptypeOMask(newPtypeO(P,PAWN))
00147 & p6.ptypeOMask(newPtypeO(P,PAWN))
00148 & p7.ptypeOMask(newPtypeO(P,PAWN))
00149 & p8.ptypeOMask(newPtypeO(P,PAWN)))==0;
00150 }
00151 bool isPawnMaskSet(Player player, int x) const;
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 getPieceOnBoard(Position pos) const
00162 {
00163 assert(pos.isOnBoard());
00164 return getPieceAt(pos);
00165 }
00166
00167 bool isOnBoard(int num) const {
00168 return getPieceOf(num).isOnBoard();
00169 }
00170 template<Player P,Ptype T>
00171 bool hasPieceOnStand() const {
00172 return (standMask(P).getMask(PtypeFuns<T>::indexNum)
00173 & mask_t::makeDirect(PtypeFuns<T>::indexMask)).any();
00174 }
00175 bool hasPieceOnStand(Player player,Ptype ptype) const{
00176 #if OSL_WORDSIZE == 64
00177
00181 return (standMask(player).getMask(0)
00182 & Ptype_Table.getMaskLow(ptype)).any();
00183 #elif OSL_WORDSIZE == 32
00184 return (standMask(player).getMask(Ptype_Table.getIndex(ptype))
00185 & Ptype_Table.getMaskLow(ptype)).any();
00186 #endif
00187 }
00191 int countPiecesOnStand(Player pl,Ptype ptype) const {
00192 return (standMask(pl).getMask(Ptype_Table.getIndex(ptype))
00193 & Ptype_Table.getMaskLow(ptype)).countBit();
00194 }
00196 template <Ptype Type>
00197 int countPiecesOnStand(Player pl) const {
00198 assert(isBasic(Type));
00199 return (standMask(pl).getMask(PtypeFuns<Type>::indexNum)
00200 & mask_t::makeDirect(PtypeFuns<Type>::indexMask)).countBit();
00201 }
00206 Piece nextPiece(Position cur, Offset diff) const
00207 {
00208 assert(! diff.zero());
00209 cur += diff;
00210 while (getPieceAt(cur) == Piece::EMPTY())
00211 cur += diff;
00212 return getPieceAt(cur);
00213 }
00214
00215 void setTurn(Player player) {
00216 turn=player;
00217 }
00218 Player getTurn() const{
00219 return turn;
00220 }
00224 void changeTurn() {
00225 osl::changeTurn(turn);
00226 }
00227
00228
00229 bool isConsistent(bool showError=true) const;
00231 template <bool showError>
00232 bool isAlmostValidMove(Move move) const;
00240 bool isAlmostValidMove(Move move,bool showError=true) const;
00247 bool isValidMove(Move move,bool showError=true) const;
00248
00254 bool isValidMoveByRule(Move move,bool showError) const;
00255
00264 bool isEmptyBetween(Position from, Position to,Offset offset,bool pieceExistsAtTo=false) const
00265 {
00266 assert(from.isOnBoard());
00267 assert(! offset.zero());
00268 assert(offset==Board_Table.getShortOffset(Offset32(to,from)));
00269 Position pos=from+offset;
00270 for (; getPieceAt(pos).isEmpty(); pos+=offset) {
00271 if (!pieceExistsAtTo && pos==to)
00272 return true;
00273 }
00274 return pos==to;
00275
00276 }
00283 bool isEmptyBetween(Position from, Position to,bool noSpaceAtTo=false) const{
00284 assert(from.isOnBoard());
00285 Offset offset=Board_Table.getShortOffset(Offset32(to,from));
00286 assert(! offset.zero());
00287 return isEmptyBetween(from,to,offset,noSpaceAtTo);
00288 }
00296 bool hasEffectFromTo(PtypeO ptypeo,Position attacker,
00297 Position target) const
00298 {
00299 Offset32 offset32=Offset32(target,attacker);
00300 EffectContent effect=Ptype_Table.getEffect(ptypeo,offset32);
00301 if (! effect.hasEffect())
00302 return false;
00303 if (effect.hasUnblockableEffect())
00304 return true;
00305 assert(Board_Table.getShortOffset(offset32) == effect.offset());
00306 return isEmptyBetween(attacker,target,effect.offset());
00307 }
00314 bool hasEffectTo(Piece attackerPiece,Position targetPosition) const{
00315 assert(attackerPiece.isPiece() && targetPosition.isOnBoard());
00316 return hasEffectFromTo(attackerPiece.ptypeO(),
00317 attackerPiece.position(),
00318 targetPosition);
00319 }
00320
00334 template<Player P,bool setPieceP>
00335 bool lastMoveIsOpenCheck(Position from,Position kingPosition,Piece &attackPiece) const{
00336 if (from.isPieceStand())
00337 return false;
00338 Offset offset=Board_Table.getShortOffset(Offset32(from,kingPosition));
00339 if (offset.zero()
00340 || !isEmptyBetween(kingPosition,from,offset))
00341 return false;
00342 Piece p;
00343 Position pos;
00344 for (pos=from+offset;(p=getPieceAt(pos)).isEmpty();pos+=offset)
00345 ;
00346 if (p.isOnBoardByOwner<PlayerTraits<P>::opponent>()
00347 && Ptype_Table.getEffect(p.ptypeO(),pos,kingPosition).hasEffect())
00348 {
00349 if (setPieceP) attackPiece=p;
00350 return true;
00351 }
00352 return false;
00353 }
00354
00361 template<Player P>
00362 bool lastMoveIsCheck(Move last_move, Piece& attack_piece) const{
00363 assert(last_move.isNormal());
00364 assert(last_move.player() == alt(P));
00365 attack_piece = Piece::EMPTY();
00366 const Position king_position = getPieceOf(KingTraits<P>::index).position();
00367 const Position last_to = last_move.to();
00368 const Position last_from = last_move.from();
00369 const Piece last_piece=getPieceAt(last_to);
00370 if (hasEffectTo(last_piece, king_position)) {
00371 if (! lastMoveIsOpenCheck<P,false>(last_move.from(), king_position,
00372 attack_piece))
00373 attack_piece=last_piece;
00374 return true;
00375 }
00376 return lastMoveIsOpenCheck<P,true>(last_from,king_position,attack_piece);
00377 }
00378
00379
00380
00382 template<Player P,Ptype T,typename F>
00383 void forEachOnBoard(F & func) const {
00384 const int first = PtypeTraits<T>::indexMin;
00385 const int last = PtypeTraits<T>::indexLimit;
00386 for (int num=first; num<last; ++num)
00387 {
00388 Piece p=getPieceOf(num);
00389 if (p.isOnBoardByOwner<P>()) {
00390 func(p);
00391 }
00392 }
00393 }
00397 template<Player P,Ptype Type,class Action,Direction Dir>
00398 void forEachEffectOfPieceDir(Position, Action&, Int2Type<false>) const {}
00399 template<Player P,Ptype Type,class Action,Direction Dir>
00400 void forEachEffectOfPieceDir(Position piecePosition,Action & action,Int2Type<true>) const {
00401 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00402 action.template doAction<P>(getPieceAt(piecePosition),piecePosition+offset);
00403 }
00404
00405 template<Player P,Ptype Type,class Action,Direction Dir>
00406 void forEachEffectOfPieceDir(Position piecePosition,Action & action) const {
00407 forEachEffectOfPieceDir<P,Type,Action,Dir>(piecePosition,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00408 }
00412 template<Player P,Ptype Type,class Action,Direction Dir>
00413 void forEachEffectOfPieceLongDir(Position, Action&, Int2Type<false>) const {}
00414 template<Player P,Ptype Type,class Action,Direction Dir>
00415 void forEachEffectOfPieceLongDir(Position piecePosition,Action & action,Int2Type<true>) const {
00416 Piece piece=getPieceAt(piecePosition);
00417 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00418 assert(offset.intValue() != 35);
00419 Position pos=piecePosition+offset;
00420 for (;getPieceAt(pos).isEmpty();pos+=offset)
00421 action.template doAction<P>(piece,pos);
00422 action.template doAction<P>(piece,pos);
00423 }
00424
00425 template<Player P,Ptype Type,class Action,Direction Dir>
00426 void forEachEffectOfPieceLongDir(Position piecePosition,Action & action) const {
00427 forEachEffectOfPieceLongDir<P,Type,Action,Dir>(piecePosition,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
00428 }
00434 template<Player P,Ptype Type,class Action>
00435 void forEachEffectOfPiece(Position piecePosition,Action & action) const;
00440 template<class Action>
00441 void forEachEffectOfPiece(Piece piece,Action & action) const;
00442
00448 template<Player P,class Action,bool checkDone,class PositionCheck>
00449 void forEachEffectWithCheck(Position pos,Action & action,PositionCheck const& positionCheck) const;
00450
00451 template<Player P,class Action>
00452 void forEachEffect(Position pos,Action & action) const {
00453 forEachEffectWithCheck<P,Action,false,NotEmpty>(pos,action,NotEmpty());
00454 }
00459 template<Player P>
00460 const Piece hasEffectPiece(Position target) const;
00465 const Piece hasEffectPiece(Player pl,Position target) const;
00466
00467 template<Player P>
00468 bool hasEffectBy(Position pos) const{
00469 return hasEffectPiece<P>(pos) != Piece::EMPTY();
00470 }
00471 bool hasEffectBy(Player player,Position pos) const{
00472 if (player==BLACK)
00473 return hasEffectBy<BLACK>(pos);
00474 else
00475 return hasEffectBy<WHITE>(pos);
00476 }
00480 template<Player P>
00481 bool hasEffectByWithRemove(Position target,Position removed) const;
00482
00483 bool hasEffectByWithRemove(Player player, Position target,Position removed) const{
00484 if (player==BLACK)
00485 return hasEffectByWithRemove<BLACK>(target,removed);
00486 else
00487 return hasEffectByWithRemove<WHITE>(target,removed);
00488 }
00489
00490
00497 template<Player P>
00498 bool hasEffectBy(Position target,Piece& attackerPiece) const;
00499
00500 bool hasEffectBy(Player pl,Position target,Piece& attackerPiece) const{
00501 if(pl==BLACK)
00502 return hasEffectBy<BLACK>(target,attackerPiece);
00503 else
00504 return hasEffectBy<WHITE>(target,attackerPiece);
00505 }
00506
00510 template<Player P>
00511 bool hasMultipleEffectBy(Position target) const;
00512 bool hasMultipleEffectBy(Player player,Position target) const;
00513
00514 template<Player P,class Action>
00515 void forEachEffectNotBy(Position pos,Piece p,Action & action) const {
00516 typedef PieceFilter<Action> action_t;
00517 action_t notByAction(action,p);
00518 forEachEffect<P,action_t>(pos,notByAction);
00519 }
00525 template<Player P>
00526 bool hasEffectNotBy(Piece piece,Position target) const;
00527
00533 bool hasEffectNotBy(Player player,Piece piece,Position target) const {
00534 if (player==BLACK)
00535 return hasEffectNotBy<BLACK>(piece,target);
00536 else
00537 return hasEffectNotBy<WHITE>(piece,target);
00538 }
00539
00540
00541 template<Player P,class Action>
00542 void forEachEffectPtypeDirection(Position pos,Action & action,Direction dir,Ptype ptype,Int2Type<false> canMove) const{}
00543
00544 template<Player P,class Action>
00545 void forEachEffectPtypeDirection(Position pos,Action & action,Direction dir,Ptype ptype,Int2Type<true> canMove) const{
00546 Position pos1=pos-Board_Table.template getOffset<P>(dir);
00547 Piece p=getPieceAt(pos1);
00548 PtypeO ptypeo=p.ptypeO();
00549 if (Ptype_Table.getShortMoveMask(P,ptypeo,dir)!=0 && unpromote(getPtype(ptypeo))==ptype) {
00550 action.template doAction<P>(p,pos);
00551 }
00552 }
00553
00554 template<Player P,Ptype Type,Direction Dir,class Action>
00555 void forEachEffectPtypeDirection(Position pos,Action & action) const{
00556 BOOST_STATIC_ASSERT((PtypeTraits<Type>::isBasic));
00557 forEachEffectPtypeDirection<P,Action>(pos,action,Dir,Type,Int2Type<PtypeDirectionTraits<Type,Dir>::canMove || PtypeDirectionTraits<PtypeFuns<Type>::promotePtype,Dir>::canMove>());
00558 }
00559
00560 template<Player P,Ptype Type,class Action>
00561 void forEachEffectPtype(Position pos,Action & action) const;
00565 template<Direction Dir,Player P>
00566 bool hasEffectDir(Position to) const{
00567 BOOST_STATIC_ASSERT((DirectionTraits<Dir>::isLong));
00568 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
00569 Piece p;
00570 for (Position pos=to-offset;(p=getPieceAt(pos)).isEmpty();pos-=offset)
00571 ;
00572 if (p.isOnBoardByOwner<P>()
00573 && (Ptype_Table.getMoveMask(p.ptype())&DirectionTraits<Dir>::mask)!=0)
00574 return true;
00575 return false;
00576 }
00577
00578
00580 bool dump() const;
00581 void doSimpleMove(Position from, Position to, int promoteMask);
00582 void doDropMove(Position to,Ptype ptype);
00583 void doCaptureMove(Position from, Position to, Piece target,int promoteMask);
00587 const SimpleState emulateCapture(Piece from, Player new_owner) const;
00588
00592 const SimpleState emulateHandPiece(Player from, Player to, Ptype ptype) const;
00593 const SimpleState rotate180() const;
00594 const SimpleState flipHorizontal() const;
00595 };
00596 }
00597 using state::SimpleState;
00598
00599 namespace apply_move
00600 {
00601 template<Player P>
00602 struct ApplyDoUndoSimpleMove<P,SimpleState>
00603 {
00604 static void prologue(SimpleState& s,
00605 Position from, Position to, int promoteMask,
00606 Piece& oldPiece, int& num)
00607 {
00608 oldPiece=s.getPieceAt(from);
00609 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
00610 newPiece+=(to-from);
00611 num=oldPiece.number();
00612 s.setPieceOf(num,newPiece);
00613 s.setBoard(to,newPiece);
00614 s.setBoard(from,Piece::EMPTY());
00615 }
00616 static void epilogue(SimpleState& s, Position from, Position to,
00617 Piece oldPiece, int num)
00618 {
00619
00620 s.setPieceOf(num,oldPiece);
00621 s.setBoard(from,oldPiece);
00622 s.setBoard(to,Piece::EMPTY());
00623 }
00624 template <typename F>
00625 static void doUndoSimpleMove(SimpleState& s,
00626 Position from, Position to, int promoteMask,F& func);
00627 };
00628
00629 template<Player P>
00630 template <typename F>
00631 void ApplyDoUndoSimpleMove<P,SimpleState>::
00632 doUndoSimpleMove(SimpleState& s,
00633 Position from, Position to, int promoteMask,F& func)
00634 {
00635 Piece oldPiece;
00636 int num;
00637 prologue(s, from, to, promoteMask, oldPiece, num);
00638 s.changeTurn();
00639 func(to);
00640 s.changeTurn();
00641 epilogue(s, from, to, oldPiece, num);
00642 }
00643
00644 template<Player P>
00645 struct ApplyDoUndoDropMove<P,SimpleState>
00646 {
00647 typedef SimpleState state_t;
00648
00653 static void prologue(SimpleState& s, Ptype ptype, Position to,
00654 Piece& oldPiece, int& num, int& numIndex, int& numLow)
00655 {
00656 #if OSL_WORDSIZE == 64
00657 numIndex=0;
00658 const mask_t ownMochigoma=
00659 s.standMask(P).getMask(0) & Ptype_Table.getMaskLow(ptype);
00660 assert(ownMochigoma.any() || (s.dump(), 0));
00661 num=numLow=ownMochigoma.bsf();
00662 #elif OSL_WORDSIZE == 32
00663 numIndex=Ptype_Table.getIndex(ptype);
00664 const mask_t ownMochigoma=
00665 s.standMask(P).getMask(numIndex) & Ptype_Table.getMaskLow(ptype);
00666 assert(ownMochigoma.any() || (s.dump(), 0));
00667 numLow=ownMochigoma.bsf();
00668 num=numLow|(numIndex<<5);
00669 #endif
00670 oldPiece=s.getPieceOf(num);
00671 Piece p=oldPiece;
00672 p += to-Position::STAND();
00673
00674 s.setPieceOf(num,p);
00675 s.setBoard(to,p);
00676 s.standMask(P).xorMask(numIndex,PieceMask::numToMask(numLow));
00677 }
00678
00679 static void epilogue(SimpleState& s, Position to,
00680 Piece oldPiece, int num,
00681 int numIndex, int numLow)
00682 {
00683 s.standMask(P).xorMask(numIndex,PieceMask::numToMask(numLow));
00684 s.setBoard(to,Piece::EMPTY());
00685 s.setPieceOf(num,oldPiece);
00686 }
00687 template <typename F>
00688 static void doUndoDropMove(SimpleState& s,
00689 Position to, Ptype ptype,F& func);
00690 };
00691
00692
00693 template<Player P>
00694 template <typename F>
00695 void ApplyDoUndoDropMove<P,SimpleState>::
00696 doUndoDropMove(SimpleState& s,
00697 Position to, Ptype ptype,F& func)
00698 {
00699 Piece oldPiece;
00700 int num, numIndex, numLow;
00701 prologue(s, ptype, to, oldPiece, num, numIndex, numLow);
00702 s.changeTurn();
00703 func(to);
00704 s.changeTurn();
00705 epilogue(s, to, oldPiece, num, numIndex, numLow);
00706 }
00707
00708 template<Player P>
00709 struct ApplyDoUndoCaptureMove<P,SimpleState>
00710 {
00711 typedef SimpleState state_t;
00712 template <typename F>
00713 static void doUndoCaptureMove(state_t& s,
00714 Position from,Position to, Piece p1, int promoteMask,F& func);
00715
00716 static
00717 void prologue(SimpleState& s,
00718 Position from, Position to, Piece target, int promoteMask,
00719 Ptype& capturePtype, Piece& oldPiece, int& num0,
00720 int& num1, int& num1Index, mask_t& num1Mask)
00721 {
00722 capturePtype=target.ptype();
00723 num1=target.number();
00724 num1Index=PieceMask::numToIndex(num1);
00725 num1Mask=PieceMask::numToMask(num1);
00726
00727 s.standMask(P).xorMask(num1Index,num1Mask);
00728 oldPiece=s.getPieceAt(from);
00729 Piece newPiece=oldPiece.promoteWithMask(promoteMask);
00730 newPiece+=(to-from);
00731 num0=oldPiece.number();
00732 s.setPieceOf(num0,newPiece);
00733 s.setPieceOf(num1,target.captured());
00734 s.setBoard(to,newPiece);
00735 s.setBoard(from,Piece::EMPTY());
00736 }
00737
00738 static
00739 void epilogue(SimpleState& s, Position from, Position to, Piece target,
00740 Piece oldPiece, int num0,
00741 int num1, int num1Index, mask_t num1Mask)
00742 {
00743 s.standMask(P).xorMask(num1Index,num1Mask);
00744 s.setPieceOf(num0,oldPiece);
00745 s.setPieceOf(num1,target);
00746 s.setBoard(from,oldPiece);
00747 s.setBoard(to,target);
00748 }
00749 };
00750
00751
00752 template<Player P>
00753 template <typename F>
00754 void ApplyDoUndoCaptureMove<P,SimpleState>::
00755 doUndoCaptureMove(state_t& s,
00756 Position from,Position to, Piece target, int promoteMask,F& func)
00757 {
00758 Piece oldPiece;
00759 int num0, num1;
00760 int num1Index;
00761 mask_t num1Mask;
00762 Ptype capturePtype;
00763 prologue(s, from, to, target, promoteMask,
00764 capturePtype, oldPiece, num0, num1, num1Index, num1Mask);
00765 s.changeTurn();
00766 func(to);
00767 s.changeTurn();
00768
00769 epilogue(s, from, to, target, oldPiece, num0, num1, num1Index, num1Mask);
00770 }
00771
00772 template<> class DoUndoMoveLockSimple<SimpleState>;
00773 template<> class DoUndoMoveLockDrop<SimpleState>;
00774 template<> class DoUndoMoveLockCapture<SimpleState>;
00775 }
00776 }
00777
00778 #endif
00779
00780
00781
00782