00001 #ifndef _EFFECTUTIL_TCC
00002 #define _EFFECTUTIL_TCC
00003
00004 #include "osl/effect_util/effectUtil.h"
00005 #include "osl/effect_action/selectCheapest.h"
00006 #include "osl/effect_action/selectPromotable.h"
00007 #include "osl/effect_action/storePiece.h"
00008 #include "osl/move_classifier/kingOpenMove.h"
00009 #include "osl/container/pieceVector.h"
00010 #include <boost/static_assert.hpp>
00011
00012 template <class EffectState>
00013 osl::Piece osl::effect_util::EffectUtil::
00014 cheapestPiece(Player P, const EffectState& state, Position pos)
00015 {
00016 assert(pos.isOnBoard());
00017 effect_action::SelectCheapest selector;
00018 forEachEffect(P, state, pos, selector);
00019 return selector.result;
00020 }
00021
00022 template <class EffectState>
00023 osl::Piece osl::effect_util::EffectUtil::
00024 promotablePiece(Player P, const EffectState& state,
00025 Position effectTarget)
00026 {
00027 assert(effectTarget.isOnBoard());
00028 effect_action::SelectPromotable selector;
00029 forEachEffect(P, state, effectTarget, selector);
00030 return selector.result;
00031 }
00032
00033 template <class EffectState>
00034 void osl::effect_util::EffectUtil::showEffect(const EffectState& state, Position target,
00035 std::ostream& os)
00036 {
00037 assert(target.isOnBoard());
00038 PieceVector pieces;
00039 findEffect(BLACK, state, target, pieces);
00040 os << pieces;
00041 pieces.clear();
00042 findEffect(WHITE, state, target, pieces);
00043 os << pieces;
00044 }
00045
00046 namespace osl
00047 {
00048 namespace effect_util
00049 {
00050 template <osl::Player P, bool InterestEmpty, Direction Dir>
00051 struct TestEffectOfMove
00052 {
00053 template <class State, class Function>
00054 static void testShort(const State& s, int mask, Position from,
00055 Function& f)
00056 {
00057 BOOST_STATIC_ASSERT(! DirectionTraits<Dir>::isLong);
00058 if (! (mask & DirectionTraits<Dir>::mask))
00059 return;
00060
00061 const Offset offset = DirectionPlayerTraits<Dir,P>::offset();
00062 const Position target = from+offset;
00063 const Piece piece = s.getPieceAt(target);
00064 if (piece.isEdge())
00065 return;
00066 if (InterestEmpty || (! piece.isEmpty()))
00067 f(target);
00068 }
00069 template <class State, class Function>
00070 static void testLong(const State& s, int mask, Position from,
00071 Function& f)
00072 {
00073 BOOST_STATIC_ASSERT(DirectionTraits<Dir>::isLong);
00074 if (! (mask & DirectionTraits<Dir>::mask))
00075 return;
00076
00077 const Offset offset = DirectionPlayerTraits<Dir,P>::offset();
00078
00079 Position target = from+offset;
00080 Piece piece = s.getPieceAt(target);
00081 while (piece.isEmpty())
00082 {
00083 if (InterestEmpty)
00084 f(target);
00085 target = target+offset;
00086 piece = s.getPieceAt(target);
00087 }
00088 if (piece.isPiece())
00089 {
00090 f(target);
00091 }
00092 }
00093 };
00094 }
00095 }
00096
00097 template <osl::Player P, class State, class Function, bool InterestEmpty>
00098 void osl::effect_util::EffectUtil::
00099 forEachEffectOfPtypeO(const State& state, Position from, Ptype ptype,
00100 Function& f)
00101 {
00102 const int mask = Ptype_Table.getMoveMask(ptype);
00103 TestEffectOfMove<P,InterestEmpty,UL>::testShort(state, mask, from, f);
00104 TestEffectOfMove<P,InterestEmpty,U>::testShort(state, mask, from, f);
00105 TestEffectOfMove<P,InterestEmpty,UR>::testShort(state, mask, from, f);
00106 TestEffectOfMove<P,InterestEmpty,L>::testShort(state, mask, from, f);
00107 TestEffectOfMove<P,InterestEmpty,R>::testShort(state, mask, from, f);
00108 TestEffectOfMove<P,InterestEmpty,DL>::testShort(state, mask, from, f);
00109 TestEffectOfMove<P,InterestEmpty,D>::testShort(state, mask, from, f);
00110 TestEffectOfMove<P,InterestEmpty,DR>::testShort(state, mask, from, f);
00111 TestEffectOfMove<P,InterestEmpty,UUL>::testShort(state, mask, from, f);
00112 TestEffectOfMove<P,InterestEmpty,UUR>::testShort(state, mask, from, f);
00113 TestEffectOfMove<P,InterestEmpty,LONG_UL>::testLong(state, mask, from, f);
00114 TestEffectOfMove<P,InterestEmpty,LONG_U>::testLong(state, mask, from, f);
00115 TestEffectOfMove<P,InterestEmpty,LONG_UR>::testLong(state, mask, from, f);
00116 TestEffectOfMove<P,InterestEmpty,LONG_L>::testLong(state, mask, from, f);
00117 TestEffectOfMove<P,InterestEmpty,LONG_R>::testLong(state, mask, from, f);
00118 TestEffectOfMove<P,InterestEmpty,LONG_DL>::testLong(state, mask, from, f);
00119 TestEffectOfMove<P,InterestEmpty,LONG_D>::testLong(state, mask, from, f);
00120 TestEffectOfMove<P,InterestEmpty,LONG_DR>::testLong(state, mask, from, f);
00121 }
00122
00123 template <class State, class Function, bool InterestEmpty>
00124 void osl::effect_util::EffectUtil::
00125 forEachEffectOfPtypeO(const State& state, Position from, PtypeO ptypeo,
00126 Function& f)
00127 {
00128 const Player P = getOwner(ptypeo);
00129 if (P == BLACK)
00130 forEachEffectOfPtypeO<BLACK,State,Function,InterestEmpty>
00131 (state, from, getPtype(ptypeo), f);
00132 else
00133 forEachEffectOfPtypeO<WHITE,State,Function,InterestEmpty>
00134 (state, from, getPtype(ptypeo), f);
00135 }
00136
00137 template <class State, class Function, bool InterestEmpty>
00138 void osl::effect_util::EffectUtil::
00139 forEachEffectOfMove(const State& state, Move move, Function& f)
00140 {
00141 const PtypeO ptypeo = move.ptypeO();
00142 const Position from = move.to();
00143 forEachEffectOfPtypeO<State,Function,InterestEmpty>(state, from, ptypeo, f);
00144 }
00145
00146 template <class EffectState>
00147 struct osl::effect_util::EffectUtil::SafeCapture
00148 {
00149 const EffectState& state;
00150 Piece safe_one;
00151 SafeCapture(const EffectState& s) : state(s), safe_one(Piece::EMPTY())
00152 {
00153 }
00154 template <Player P>
00155 void doAction(Piece effect_piece, Position target)
00156 {
00157 if (move_classifier::KingOpenMove<P>::isMember
00158 (state, effect_piece.ptype(), effect_piece.position(), target))
00159 return;
00160 safe_one = effect_piece;
00161 }
00162 };
00163
00164 template <osl::Player P, class EffectState>
00165 osl::Piece
00166 osl::effect_util::EffectUtil::safeCaptureNotByKing(const EffectState& state, Position target,
00167 Piece king)
00168 {
00169 assert(king.owner() == P);
00170 assert(king.ptype() == KING);
00171 SafeCapture<EffectState> safe_captures(state);
00172 state.template forEachEffectNotBy<P>(target, king, safe_captures);
00173
00174 return safe_captures.safe_one;
00175 }
00176
00177 template <class EffectState>
00178 void
00179 osl::effect_util::EffectUtil::
00180 findEffect(Player P, const EffectState& state, Position target,
00181 PieceVector& out)
00182 {
00183 effect_action::StorePiece store(&out);
00184 forEachEffect(P, state, target, store);
00185 }
00186
00187 template<osl::Player P>
00188 bool
00189 osl::effect_util::EffectUtil::isOpenAttackMove(const SimpleState& state, Position target,Position from, Position to)
00190 {
00191 assert(P==state.getTurn());
00192 assert(!from.isPieceStand());
00193 assert(!target.isPieceStand());
00194 Offset offset=Board_Table.getShortOffsetNotKnight(Offset32(target,from));
00195 if(offset.zero() ||
00196 offset==Board_Table.getShortOffsetNotKnight(Offset32(target,to)))
00197 return false;
00198 if(!state.isEmptyBetween(from,target,offset,false)) return false;
00199 Position pos=from;
00200 Piece p;
00201 for(pos-=offset;(p=state.getPieceAt(pos)).isEmpty();pos-=offset){
00202 assert(pos.isOnBoard());
00203 }
00204 if (!p.isOnBoardByOwner<P>())
00205 return false;
00206 return Ptype_Table.getEffect(p.ptypeO(),pos,target).hasEffect();
00207 }
00208
00209 template<osl::Player P>
00210 bool
00211 osl::effect_util::EffectUtil::isAddEffectMove(const SimpleState& state, Position target,Move move)
00212 {
00213 assert(P==state.getTurn());
00214 assert(P==move.player());
00215 PtypeO ptypeo=move.ptypeO();
00216 Position to=move.to();
00217 if(state.hasEffectFromTo(ptypeo,to,target)) return true;
00218 if(isOpenAttackMove<P>(state,target,move.from(),move.to())) return true;
00219 return false;
00220 }
00221
00222 #endif
00223
00224
00225
00226