effectUtil.tcc
Go to the documentation of this file.
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   } // namespace effect_util
00059 } // namespace osl
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 /* _EFFECTUTIL_TCC */
00200 // ;;; Local Variables:
00201 // ;;; mode:c++
00202 // ;;; c-basic-offset:2
00203 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines