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 #endif /* _EFFECTUTIL_TCC */
00138 // ;;; Local Variables:
00139 // ;;; mode:c++
00140 // ;;; c-basic-offset:2
00141 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines