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, Square 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 Square target = from+offset;
00027 const Piece piece = s.pieceAt(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, Square 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 Square target = from+offset;
00044 Piece piece = s.pieceAt(target);
00045 while (piece.isEmpty())
00046 {
00047 if (InterestEmpty)
00048 f(target);
00049 target = target+offset;
00050 piece = s.pieceAt(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, Square 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, Square 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 public:
00104 const NumEffectState& state;
00105 Piece safe_one;
00106 SafeCapture(const NumEffectState& s) : state(s), safe_one(Piece::EMPTY())
00107 {
00108 }
00109 template <Player P>
00110 void doAction(Piece effect_piece, Square target)
00111 {
00112 if (move_classifier::KingOpenMove<P>::isMember
00113 (state, effect_piece.ptype(), effect_piece.square(), target))
00114 return;
00115 safe_one = effect_piece;
00116 }
00117 };
00118
00119 template <osl::Player P>
00120 osl::Piece
00121 osl::effect_util::EffectUtil::safeCaptureNotByKing(const NumEffectState& state, Square target,
00122 Piece king)
00123 {
00124 assert(king.owner() == P);
00125 assert(king.ptype() == KING);
00126 PieceMask ignore = state.pin(P);
00127 ignore.set(king.number());
00128 const Piece piece = state.findAttackNotBy(P, target, ignore);
00129 if (piece.isPiece())
00130 return piece;
00131 SafeCapture safe_captures(state);
00132 state.template forEachEffectNotBy<P>(target, king, safe_captures);
00133
00134 return safe_captures.safe_one;
00135 }
00136
00137 template <class EvalT>
00138 struct osl::effect_util::EffectUtil::FindThreat
00139 {
00140 const NumEffectState& state;
00141 Player target;
00142 int attacker_value;
00143 PieceVector& supported, & unsupported;
00144 FindThreat(const NumEffectState& st, Player t, int a,
00145 PieceVector& s, PieceVector& u)
00146 : state(st), target(t), attacker_value(a), supported(s), unsupported(u)
00147 {
00148 }
00149 void operator()(Square pos)
00150 {
00151 const Piece cur = state.pieceOnBoard(pos);
00152 assert(cur.isPiece());
00153 if (cur.owner() != target)
00154 return;
00155 if (state.hasEffectAt(target, pos))
00156 {
00157 if (abs(EvalT::captureValue(cur.ptypeO()))
00158 > attacker_value)
00159 supported.push_back(cur);
00160 }
00161 else
00162 {
00163 unsupported.push_back(cur);
00164 }
00165 }
00166 };
00167
00168 template <class EvalT>
00169 void osl::EffectUtil::
00170 findThreat(const NumEffectState& state, Square position,
00171 PtypeO ptypeo, PieceVector& out)
00172 {
00173 PieceVector supported, unsupported;
00174 const int attacker_value = abs(EvalT::captureValue(ptypeo));
00175 FindThreat<EvalT> f(state, alt(getOwner(ptypeo)), attacker_value,
00176 supported, unsupported);
00177 forEachEffectOfPtypeO<FindThreat<EvalT>, false>
00178 (state, position, ptypeo, f);
00179
00180 unsupported.sortByPtype();
00181 supported.sortByPtype();
00182 PieceVector::iterator u=unsupported.begin(), s=supported.begin();
00183
00184 if (u!=unsupported.end())
00185 {
00186 while ((s!=supported.end())
00187 && ((abs(EvalT::captureValue(s->ptypeO()))
00188 - attacker_value)
00189 > abs(EvalT::captureValue(u->ptypeO()))))
00190 {
00191 out.push_back(*s);
00192 ++s;
00193 }
00194 }
00195 out.push_back(u, unsupported.end());
00196 out.push_back(s, supported.end());
00197 }
00198
00199 #endif
00200
00201
00202
00203