00001 #ifndef _EFFECTUTIL_TCC
00002 #define _EFFECTUTIL_TCC
00003
00004 #include "osl/effect_util/effectUtil.h"
00005 #include "osl/effect_action/storePiece.h"
00006 #include "osl/move_classifier/kingOpenMove.h"
00007 #include "osl/container/pieceVector.h"
00008 #include <boost/static_assert.hpp>
00009
00010 namespace osl
00011 {
00012 namespace effect_util
00013 {
00014 template <osl::Player P, bool InterestEmpty, Direction Dir>
00015 struct TestEffectOfMove
00016 {
00017 template <class State, class Function>
00018 static void testShort(const State& s, int mask, Position from,
00019 Function& f)
00020 {
00021 BOOST_STATIC_ASSERT(! DirectionTraits<Dir>::isLong);
00022 if (! (mask & DirectionTraits<Dir>::mask))
00023 return;
00024
00025 const Offset offset = DirectionPlayerTraits<Dir,P>::offset();
00026 const Position target = from+offset;
00027 const Piece piece = s.getPieceAt(target);
00028 if (piece.isEdge())
00029 return;
00030 if (InterestEmpty || (! piece.isEmpty()))
00031 f(target);
00032 }
00033 template <class State, class Function>
00034 static void testLong(const State& s, int mask, Position from,
00035 Function& f)
00036 {
00037 BOOST_STATIC_ASSERT(DirectionTraits<Dir>::isLong);
00038 if (! (mask & DirectionTraits<Dir>::mask))
00039 return;
00040
00041 const Offset offset = DirectionPlayerTraits<Dir,P>::offset();
00042
00043 Position target = from+offset;
00044 Piece piece = s.getPieceAt(target);
00045 while (piece.isEmpty())
00046 {
00047 if (InterestEmpty)
00048 f(target);
00049 target = target+offset;
00050 piece = s.getPieceAt(target);
00051 }
00052 if (piece.isPiece())
00053 {
00054 f(target);
00055 }
00056 }
00057 };
00058 }
00059 }
00060
00061 template <osl::Player P, class Function, bool InterestEmpty>
00062 void osl::effect_util::EffectUtil::
00063 forEachEffectOfPtypeO(const NumEffectState& state, Position from, Ptype ptype,
00064 Function& f)
00065 {
00066 const int mask = Ptype_Table.getMoveMask(ptype);
00067 TestEffectOfMove<P,InterestEmpty,UL>::testShort(state, mask, from, f);
00068 TestEffectOfMove<P,InterestEmpty,U>::testShort(state, mask, from, f);
00069 TestEffectOfMove<P,InterestEmpty,UR>::testShort(state, mask, from, f);
00070 TestEffectOfMove<P,InterestEmpty,L>::testShort(state, mask, from, f);
00071 TestEffectOfMove<P,InterestEmpty,R>::testShort(state, mask, from, f);
00072 TestEffectOfMove<P,InterestEmpty,DL>::testShort(state, mask, from, f);
00073 TestEffectOfMove<P,InterestEmpty,D>::testShort(state, mask, from, f);
00074 TestEffectOfMove<P,InterestEmpty,DR>::testShort(state, mask, from, f);
00075 TestEffectOfMove<P,InterestEmpty,UUL>::testShort(state, mask, from, f);
00076 TestEffectOfMove<P,InterestEmpty,UUR>::testShort(state, mask, from, f);
00077 TestEffectOfMove<P,InterestEmpty,LONG_UL>::testLong(state, mask, from, f);
00078 TestEffectOfMove<P,InterestEmpty,LONG_U>::testLong(state, mask, from, f);
00079 TestEffectOfMove<P,InterestEmpty,LONG_UR>::testLong(state, mask, from, f);
00080 TestEffectOfMove<P,InterestEmpty,LONG_L>::testLong(state, mask, from, f);
00081 TestEffectOfMove<P,InterestEmpty,LONG_R>::testLong(state, mask, from, f);
00082 TestEffectOfMove<P,InterestEmpty,LONG_DL>::testLong(state, mask, from, f);
00083 TestEffectOfMove<P,InterestEmpty,LONG_D>::testLong(state, mask, from, f);
00084 TestEffectOfMove<P,InterestEmpty,LONG_DR>::testLong(state, mask, from, f);
00085 }
00086
00087 template <class Function, bool InterestEmpty>
00088 void osl::effect_util::EffectUtil::
00089 forEachEffectOfPtypeO(const NumEffectState& state, Position from, PtypeO ptypeo,
00090 Function& f)
00091 {
00092 const Player P = getOwner(ptypeo);
00093 if (P == BLACK)
00094 forEachEffectOfPtypeO<BLACK,Function,InterestEmpty>
00095 (state, from, getPtype(ptypeo), f);
00096 else
00097 forEachEffectOfPtypeO<WHITE,Function,InterestEmpty>
00098 (state, from, getPtype(ptypeo), f);
00099 }
00100
00101 struct osl::effect_util::EffectUtil::SafeCapture
00102 {
00103 const NumEffectState& state;
00104 Piece safe_one;
00105 SafeCapture(const NumEffectState& s) : state(s), safe_one(Piece::EMPTY())
00106 {
00107 }
00108 template <Player P>
00109 void doAction(Piece effect_piece, Position target)
00110 {
00111 if (move_classifier::KingOpenMove<P>::isMember
00112 (state, effect_piece.ptype(), effect_piece.position(), target))
00113 return;
00114 safe_one = effect_piece;
00115 }
00116 };
00117
00118 template <osl::Player P>
00119 osl::Piece
00120 osl::effect_util::EffectUtil::safeCaptureNotByKing(const NumEffectState& state, Position target,
00121 Piece king)
00122 {
00123 assert(king.owner() == P);
00124 assert(king.ptype() == KING);
00125 PieceMask ignore = state.pin(P);
00126 ignore.set(king.number());
00127 const Piece piece = state.findThreatNotBy(P, target, ignore);
00128 if (piece.isPiece())
00129 return piece;
00130 SafeCapture safe_captures(state);
00131 state.template forEachEffectNotBy<P>(target, king, safe_captures);
00132
00133 return safe_captures.safe_one;
00134 }
00135
00136 #endif
00137
00138
00139
00140