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