00001
00002
00003 #ifndef _PIN_H
00004 #define _PIN_H
00005
00006 #include "osl/state/numEffectState.h"
00007 #include "osl/container/pieceMask.h"
00008 #include <boost/static_assert.hpp>
00009 namespace osl
00010 {
00011 namespace effect_util
00012 {
00013
00014 class PinOrOpen
00015 {
00016 private:
00020 template <Player Defense,Direction DIR>
00021 static void findDirectionStep(const NumEffectState& state, Square target,
00022 PieceMask& pins, PieceMask const& onBoard)
00023 {
00024 const Offset offset = DirectionTraits<DIR>::blackOffset();
00025 Square pos=target-offset;
00026 int num;
00027 while(Piece::isEmptyNum(num=state.pieceAt(pos).number()))
00028 pos-=offset;
00029 if(Piece::isEdgeNum(num)) return;
00030 int num1=state.longEffectNumTable()[num][DIR];
00031 if(Piece::isPieceNum(num1) && onBoard.test(num1)){
00032 pins.set(num);
00033 }
00034 }
00035 public:
00036 template<Player Defense>
00037 static PieceMask makeStep(const NumEffectState& state, Square target)
00038 {
00039 PieceMask pins;
00040 PieceMask mask=state.piecesOnBoard(alt(Defense));
00041 findDirectionStep<Defense,UL>(state,target,pins,mask);
00042 findDirectionStep<Defense,U>(state,target,pins,mask);
00043 findDirectionStep<Defense,UR>(state,target,pins,mask);
00044 findDirectionStep<Defense,L>(state,target,pins,mask);
00045 findDirectionStep<Defense,R>(state,target,pins,mask);
00046 findDirectionStep<Defense,DL>(state,target,pins,mask);
00047 findDirectionStep<Defense,D>(state,target,pins,mask);
00048 findDirectionStep<Defense,DR>(state,target,pins,mask);
00049 return pins;
00050 }
00051
00052 static PieceMask makeStep(const NumEffectState& state, Square target,
00053 Player defense)
00054 {
00055 if(defense==BLACK)
00056 return makeStep<BLACK>(state,target);
00057 else
00058 return makeStep<WHITE>(state,target);
00059 }
00060 static PieceMask make(const NumEffectState& state,Player defense)
00061 {
00062 return makeStep(state,state.kingSquare<BLACK>(),defense);
00063 }
00064 };
00069 class Pin
00070 {
00071 private:
00072 template <Direction DIR>
00073 static void findDirection(const SimpleState& state, Square target,
00074 Player defense, PieceMask& pins)
00075 {
00076 const Offset diff = Board_Table.getOffset(defense, DIR);
00077 const Piece pin = state.nextPiece(target, diff);
00078 if(!pin.isOnBoardByOwner(defense)) return;
00079 const Piece attack_piece = state.nextPiece(pin.square(), diff);
00080 if(!attack_piece.isOnBoardByOwner(alt(defense))) return;
00081 if (Ptype_Table.getMoveMask(attack_piece.ptype())
00082 & DirectionTraits<DirectionTraits<DIR>::longDir>::mask)
00083 pins.set(pin.number());
00084 }
00090 template<Player P>
00091 static void findLance(const NumEffectState& state, Square target,
00092 PieceMask& pins)
00093 {
00094 assert(target==state.kingSquare<P>());
00095 const Offset diff = DirectionPlayerTraits<U,P>::offset();
00096 Square pos = target+diff;
00097 Piece pin;
00098 while ((pin=state.pieceAt(pos)) == Piece::EMPTY())
00099 pos += diff;
00100 if (! pin.isOnBoardByOwner<P>() )
00101 return;
00102 NumBitmapEffect effect=state.effectSetAt(pos);
00103 mask_t mask=(effect.getMask(1)&mask_t::makeDirect(PtypeFuns<LANCE>::indexMask<<8));
00104 if(mask.any()){
00105 pins.set(pin.number());
00106 }
00107 }
00108 public:
00113 static PieceMask makeNaive(const SimpleState& state, Square target,
00114 Player defense);
00115 private:
00116 static bool hasEffectWithOffset(const SimpleState& state,
00117 Piece attack_piece, Piece pin, Offset diff)
00118 {
00119 const Piece attack_piece2 = state.nextPiece(pin.square(), diff);
00120 return attack_piece == attack_piece2;
00121 }
00122 static bool hasEffectWithOffset(const NumEffectState& state,
00123 Piece attack_piece, Piece pin, Offset)
00124 {
00125 return state.hasEffectByPiece(attack_piece, pin.square());
00126 }
00127 static void findOffset(const NumEffectState& state,
00128 Piece attack_piece, Square target,
00129 Player defense, Offset diff, PieceMask& pins)
00130 {
00131 const Piece pin = state.nextPiece(target, diff);
00132 assert(pin.isPiece());
00133 if (pin.owner() != defense)
00134 return;
00135 if (! hasEffectWithOffset(state, attack_piece, pin, diff))
00136 return;
00137 pins.set(pin.number());
00138 }
00139 template <Ptype PTYPE>
00140 static void findPtype(const NumEffectState& state, Square target,
00141 Player attack, Player defense, PieceMask& result)
00142 {
00143 BOOST_STATIC_ASSERT((PTYPE == ROOK) || (PTYPE == BISHOP));
00144 const PtypeO attack_ptypeo = newPtypeO(attack, PTYPE);
00145 for (int i=PtypeTraits<PTYPE>::indexMin;
00146 i < PtypeTraits<PTYPE>::indexLimit; ++i)
00147 {
00148 const Piece attack_piece = state.pieceOf(i);
00149 if (attack_piece.isOnBoardByOwner(attack))
00150 {
00151 const Square attack_position = attack_piece.square();
00152 const Offset32 diff(attack_position, target);
00153 const EffectContent effect
00154 = Ptype_Table.getEffect(attack_ptypeo, diff);
00155 if (!effect.hasBlockableEffect())
00156 continue;
00157 const Offset offset = effect.offset();
00158 #if 0
00159 if (offset.zero())
00160 continue;
00161 #endif
00162 findOffset(state, attack_piece, target, defense,
00163 offset, result);
00164 }
00165 }
00166 }
00167 public:
00172 static PieceMask makeByPiece(const NumEffectState& state, Square target,
00173 Player defense);
00174
00179 static PieceMask makeByPieceKing(const NumEffectState& state, Square target,
00180 Player defense);
00181
00185 template <Player Defense,Direction DIR>
00186 static void findDirectionStep(const NumEffectState& state, Square target,
00187 PieceMask& pins)
00188 {
00189 const Offset offset = DirectionTraits<DIR>::blackOffset();
00190 Square pos=target-offset;
00191 int num;
00192 while(Piece::isEmptyNum(num=state.pieceAt(pos).number()))
00193 pos-=offset;
00194 if(Piece::isEdgeNum(num)) return;
00195 if(Defense==BLACK){
00196 if(!state.pieceAt(pos).pieceIsBlack()) return;
00197 }
00198 else{
00199 if(state.pieceAt(pos).pieceIsBlack()) return;
00200 }
00201 int num1=state.longEffectNumTable()[num][DIR];
00202 if(!Piece::isPieceNum(num1)) return;
00203 if(Defense==BLACK){
00204 if(!state.pieceOf(num1).pieceIsBlack())
00205 pins.set(num);
00206 }
00207 else{
00208 if(state.pieceOf(num1).pieceIsBlack())
00209 pins.set(num);
00210 }
00211 }
00212 template<Player Defense>
00213 static PieceMask makeStep(const NumEffectState& state, Square target)
00214 {
00215 PieceMask pins;
00216 findDirectionStep<Defense,UL>(state,target,pins);
00217 findDirectionStep<Defense,U>(state,target,pins);
00218 findDirectionStep<Defense,UR>(state,target,pins);
00219 findDirectionStep<Defense,L>(state,target,pins);
00220 findDirectionStep<Defense,R>(state,target,pins);
00221 findDirectionStep<Defense,DL>(state,target,pins);
00222 findDirectionStep<Defense,D>(state,target,pins);
00223 findDirectionStep<Defense,DR>(state,target,pins);
00224 return pins;
00225 }
00226
00227 static PieceMask makeStep(const NumEffectState& state, Square target,
00228 Player defense)
00229 {
00230 if(defense==BLACK)
00231 return makeStep<BLACK>(state,target);
00232 else
00233 return makeStep<WHITE>(state,target);
00234 }
00235 template<Player Defense>
00236 static PieceMask makeStep1(const NumEffectState& state, Square target)
00237 {
00238 PieceMask pins=PinOrOpen::makeStep<Defense>(state,target);;
00239 pins &= state.piecesOnBoard(Defense);
00240 return pins;
00241 }
00242
00243 static PieceMask makeStep1(const NumEffectState& state, Square target,
00244 Player defense)
00245 {
00246 if(defense==BLACK)
00247 return makeStep1<BLACK>(state,target);
00248 else
00249 return makeStep1<WHITE>(state,target);
00250 }
00257 static PieceMask make(const NumEffectState& state, Square target,
00258 Player defense)
00259 {
00260 return makeByPiece(state, target, defense);
00261 }
00265 static PieceMask make(const NumEffectState& state, Player defense)
00266 {
00267 return makeByPiece(state, defense);
00268 }
00269 static PieceMask makeNaive(const SimpleState& state, Player defense)
00270 {
00271 return makeNaive(state, state.kingSquare(defense), defense);
00272 }
00273 static PieceMask makeByPiece(const NumEffectState& state, Player defense)
00274 {
00275 return makeByPieceKing(state, state.kingSquare(defense), defense);
00276 }
00280 static int count(const NumEffectState& state, Player defense)
00281 {
00282 const PieceMask pins = make(state, defense);
00283 return pins.countBit();
00284 }
00285 static int count(const NumEffectState& state, Square target,
00286 Player defense)
00287 {
00288 const PieceMask pins = make(state, target, defense);
00289 return pins.countBit();
00290 }
00291 };
00292
00293
00294 }
00295 }
00296
00297 #endif
00298
00299
00300
00301