00001
00002
00003 #ifndef _APPLY_MOVE_H
00004 #define _APPLY_MOVE_H
00005
00006 #include "osl/apply_move/applyDoUndoXMove.h"
00007 #include "osl/position.h"
00008 #include "osl/move.h"
00009 #include "osl/piece.h"
00010 #include <boost/type_traits.hpp>
00011
00012 namespace osl
00013 {
00014 namespace apply_move
00015 {
00019 struct ApplyPass
00020 {
00021 template <class State, class Func>
00022 static void doUndoPass(State& state, Func &f)
00023 {
00024 BOOST_STATIC_ASSERT(! boost::is_pointer<State>::value);
00025 state.changeTurn();
00026 f(Position::STAND());
00027 state.changeTurn();
00028 }
00029 };
00030
00038 template<Player P>
00039 struct ApplyMove
00040 {
00041 template <class State, class Func>
00042 static void doUndoMoveOrPass(State& state, Move move, Func &f)
00043 {
00044 BOOST_STATIC_ASSERT(! boost::is_pointer<State>::value);
00045 assert(state.getTurn() == move.player());
00046 if (move.isPass())
00047 ApplyPass::doUndoPass(state, f);
00048 else
00049 doUndoMove(state, move, f);
00050 }
00051
00052 template <class State, class Func>
00053 static void doUndoMove(State& state, Move move, Func &f)
00054 {
00055 BOOST_STATIC_ASSERT(! boost::is_pointer<State>::value);
00056 assert(move.isValid());
00057 assert(state.isAlmostValidMove(move));
00058 assert(P == move.player());
00059 Position from=move.from();
00060 Position to=move.to();
00061 if (from.isPieceStand())
00062 {
00063 assert(state.getPieceAt(to) == Piece::EMPTY());
00064 ApplyDoUndoDropMove<P,State>::template doUndoDropMove<Func>(state,to,move.ptype(),f);
00065 }
00066 else
00067 {
00068 assert(state.getPieceAt(from) != Piece::EMPTY());
00069 Piece captured=state.getPieceAt(to);
00070 if (captured != Piece::EMPTY())
00071 {
00072 ApplyDoUndoCaptureMove<P,State>::template doUndoCaptureMove<Func>
00073 (state,from,to,captured,move.promoteMask(),f);
00074 }
00075 else
00076 {
00077 ApplyDoUndoSimpleMove<P,State>::template doUndoSimpleMove<Func>
00078 (state,from,to,move.promoteMask(),f);
00079 }
00080 }
00081 }
00082 };
00083
00084 struct ApplyMoveOfTurn
00085 {
00094 template <class State, class Func>
00095 static void doUndoMove(State& state, Move move, Func &f)
00096 {
00097 assert(state.getTurn() == move.player());
00098 if (move.isPass())
00099 {
00100 ApplyPass::doUndoPass(state, f);
00101 return;
00102 }
00103 if (move.player() == BLACK)
00104 ApplyMove<BLACK>::doUndoMove(state, move, f);
00105 else
00106 ApplyMove<WHITE>::doUndoMove(state, move, f);
00107 }
00108
00112 template<typename State>
00113 static void doMove(State& state, Move move)
00114 {
00115 BOOST_STATIC_ASSERT(! boost::is_pointer<State>::value);
00116 assert(state.getTurn() == move.player());
00117 if (! move.isPass())
00118 {
00119 assert(state.isAlmostValidMove(move));
00120 const Position from=move.from();
00121 const Position to=move.to();
00122 if (from.isPieceStand())
00123 {
00124 state.doDropMove(to,move.ptype());
00125 }
00126 else
00127 {
00128 const Piece captured = state.getPieceOnBoard(to);
00129 if (captured != Piece::EMPTY())
00130 {
00131 state.doCaptureMove(from,to,captured,move.promoteMask());
00132 }
00133 else
00134 {
00135 state.doSimpleMove(from,to,move.promoteMask());
00136 }
00137 }
00138 }
00139 state.changeTurn();
00140 }
00141 };
00142 }
00143 using apply_move::ApplyPass;
00144 using apply_move::ApplyMove;
00145 using apply_move::ApplyMoveOfTurn;
00146 }
00147
00148
00149 #endif
00150
00151
00152
00153