00001 #ifndef OSL_EFFECT_ACTION
00002 #define OSL_EFFECT_ACTION
00003 #include "osl/numEffectState.h"
00004
00005 namespace osl
00006 {
00007 namespace effect_action
00008 {
00012 template<class Action>
00013 class AlwaysMove
00014 {
00015 private:
00016 const NumEffectState& state;
00017 Action& ac;
00018 public:
00019 AlwaysMove(const NumEffectState& s, Action & a) : state(s), ac(a) {}
00023 template<Player P,Ptype Type>
00024 void doActionPtype(Piece p1,Square to){
00025 assert(Type == unpromote(p1.ptype()));
00026 Square from=p1.square();
00027 if (canPromote(Type) &&
00028 !p1.isPromotedNotKingGold() &&
00029 (to.canPromote<P>() || from.canPromote<P>())){
00030 ac.unknownMove(from,to,state.pieceAt(to),promote(Type),true,P);
00031 }
00032 if (!canPromote(Type) ||
00033 PtypePlayerTraits<Type,P>::canDropTo(to) ||
00034 p1.isPromotedNotKingGold()){
00035 ac.unknownMove(from,to,state.pieceAt(to),p1.ptype(),false,P);
00036 }
00037 }
00041 template<Player P>
00042 void doAction(Piece p1,Square to)
00043 {
00044 Square from=p1.square();
00045 Ptype ptype=p1.ptype();
00046 if(canPromote(ptype))
00047 {
00048 if (to.canPromote<P>())
00049 {
00050 ac.unknownMove(from,to,state.pieceAt(to),promote(ptype),true,P);
00051 if(Ptype_Table.canDropTo(P, ptype,to))
00052 {
00053 ac.unknownMove(from,to,state.pieceAt(to),ptype,false,P);
00054 }
00055 }
00056 else if (from.canPromote<P>())
00057 {
00058 ac.unknownMove(from,to,state.pieceAt(to),promote(ptype),true,P);
00059 ac.unknownMove(from,to,state.pieceAt(to),ptype,false,P);
00060 }
00061 else
00062 {
00063 ac.unknownMove(from,to,state.pieceAt(to),ptype,false,P);
00064 }
00065 }
00066 else
00067 {
00068 ac.unknownMove(from,to,state.pieceAt(to),ptype,false,P);
00069 }
00070 }
00071 bool done() const{ return false; }
00072 };
00073
00077 template<class Action>
00078 class BetterToPromote
00079 {
00080 private:
00081 const NumEffectState& state;
00082 Action & ac;
00083 public:
00084 BetterToPromote(const NumEffectState& s, Action& a)
00085 : state(s), ac(a)
00086 {
00087 }
00088 template<Player P,Ptype Type>
00089 void doActionPtype(Piece p1,Square to){
00090 assert(Type == unpromote(p1.ptype()));
00091 Square from=p1.square();
00092 Piece target = state.pieceAt(to);
00093 if (canPromote(Type) &&
00094 !p1.isPromotedNotKingGold() &&
00095 (to.canPromote<P>() || from.canPromote<P>())){
00096 ac.unknownMove(from,to,target,promote(Type),true,P);
00097 }
00098 if (!canPromote(Type) ||
00099 PtypePlayerTraits<Type,P>::canDropTo(to) ||
00100 p1.isPromotedNotKingGold()){
00101 if (! (to.canPromote<P>() || from.canPromote<P>())
00102 || (! PtypeTraits<Type>::betterToPromote
00103 && (p1.ptype() != LANCE
00104 || PtypePlayerTraits<LANCE,P>::canDropTo(to + DirectionPlayerTraits<U,P>::offset()))))
00105 ac.unknownMove(from,to,target,p1.ptype(),false,P);
00106 }
00107 }
00111 template<Player P>
00112 void doAction(Piece p1,Square to)
00113 {
00114 Square from=p1.square();
00115 Ptype ptype=p1.ptype();
00116 Piece target = state.pieceAt(to);
00117 if(canPromote(ptype))
00118 {
00119 if (to.canPromote<P>())
00120 {
00121 ac.unknownMove(from,to,target,promote(ptype),true,P);
00122 if(Ptype_Table.canDropTo(P, ptype,to)
00123 && ! Ptype_Table.isBetterToPromote(ptype)
00124 && (ptype != LANCE
00125 || PtypePlayerTraits<LANCE,P>::canDropTo(to + DirectionPlayerTraits<U,P>::offset())))
00126
00127 {
00128 ac.unknownMove(from,to,target,ptype,false,P);
00129 }
00130 return;
00131 }
00132 if (from.canPromote<P>())
00133 {
00134 ac.unknownMove(from,to,target,promote(ptype),true,P);
00135 if(! Ptype_Table.isBetterToPromote(ptype)
00136 && (ptype != LANCE
00137 || PtypePlayerTraits<LANCE,P>::canDropTo(to + DirectionPlayerTraits<U,P>::offset())))
00138 ac.unknownMove(from,to,target,ptype,false,P);
00139 return;
00140 }
00141
00142 }
00143 ac.unknownMove(from,to,target,ptype,false,P);
00144 }
00145 };
00146
00150 struct StorePiece
00151 {
00152 PieceVector *store;
00153 explicit StorePiece(PieceVector *s) : store(s)
00154 {
00155 }
00156 template<Player P,Ptype Type>
00157 void doActionPtype(Piece p, Square pos)
00158 {
00159 doAction<P>(p, pos);
00160 }
00161 template<Player P>
00162 void doAction(Piece p, Square)
00163 {
00164 store->push_back(p);
00165 }
00166 };
00167
00171 struct StorePtypeOSquare
00172 {
00173 PtypeOSquareVector *out;
00174 Square target;
00175 StorePtypeOSquare(PtypeOSquareVector *s, Square t)
00176 : out(s), target(t)
00177 {
00178 }
00179 template<Player P,Ptype Type>
00180 void doActionPtype(Piece p)
00181 {
00182 store(p);
00183 }
00184 template<Player P>
00185 void doAction(Piece p, Square)
00186 {
00187 store(p);
00188 }
00189
00190 void store(Piece p)
00191 {
00192 const PtypeO ptypeO = p.ptypeO();
00193 out->push_back(std::make_pair(ptypeO, p.square()));
00194 }
00195 };
00196 }
00197 }
00198 #endif // OSL_EFFECT_ACTION
00199
00200
00201
00202