numSimpleEffect.h
Go to the documentation of this file.
00001 #ifndef OSL_NUM_SIMPLE_EFFECT_H
00002 #define OSL_NUM_SIMPLE_EFFECT_H
00003 
00004 #include "osl/effect/numBitmapEffect.h"
00005 #include "osl/misc/carray.h"
00006 #include "osl/container/boardMask.h"
00007 #include "osl/container/bitXmask.h"
00008 #include "osl/piece.h"
00009 #include "osl/state/simpleState.h"
00010 #include "osl/mobility/mobilityTable.h"
00011 #include "osl/effect/effectedNumTable.h"
00012 
00013 #include <boost/static_assert.hpp>
00014 
00015 namespace osl 
00016 {
00017   namespace checkmate
00018   {
00019     class King8Info;
00020   }
00021   namespace effect
00022   {
00023     class NumSimpleEffectTable;
00024     bool operator==(const NumSimpleEffectTable&,const NumSimpleEffectTable&);
00025     std::ostream& operator<<(std::ostream&, const NumSimpleEffectTable&);
00026 
00030     class NumSimpleEffectTable
00031     {
00032     protected:
00033       CArray<NumBitmapEffect, Square::SIZE> effects
00034 #ifdef __GNUC__
00035       __attribute__((aligned(16)))
00036 #endif
00037         ;
00038       CArray<BoardMask,2> changed_effects; // each player
00040       NumBitmapEffect changed_effect_pieces; 
00041     public:
00042       CArray<PieceMask,2> effected_mask;
00043       CArray<PieceMask,2> effected_changed_mask;
00045       mobility::MobilityTable mobilityTable;
00047       EffectedNumTable effectedNumTable;
00057       template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
00058       void doEffectShort(const SimpleState& state,Square pos,int num)
00059       {
00060         if ((PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask)!=0)
00061           {
00062             const Square target = pos+DirectionPlayerTraits<Dir,P>::offset();
00063             effects[target.index()].template opEqual<OP>(NumBitmapEffect::makeEffect<P>(num));
00064             if(UC){
00065               int posIndex=BoardMask::index(pos);
00066               changed_effects[P].set(posIndex+BoardMask::getIndexOffset<Dir,P>());
00067               int num1;
00068               if(Piece::isPieceNum(num1=state.pieceAt(target).number())){
00069                 if(OP==NumBitmapEffect::Add){
00070                   effected_mask[P].set(num1);
00071                 }
00072                 else{ // OP==Sub
00073                   if((effects[target.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
00074                     effected_mask[P].reset(num1);
00075                   }
00076                 }
00077                 effected_changed_mask[P].set(num1);
00078               }
00079             }
00080           }
00081       }
00092       template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
00093       void doEffectLong(const SimpleState& state,Square pos,int num)
00094       {
00095         if ((PtypeTraits<T>::moveMask & DirectionTraits<DirectionPlayerTraits<Dir,P>::directionByBlack>::mask)!=0)
00096           {
00097             int posIndex;
00098             if(UC){
00099               posIndex=BoardMask::index(pos);
00100             }
00101             const Offset offset=DirectionPlayerTraits<Dir,BLACK>::offset();
00102             assert(!offset.zero());
00103             NumBitmapEffect effect=NumBitmapEffect::makeLongEffect<P>(num);
00104 
00105             const Direction SD=longToShort(Dir);
00106             if(OP==NumBitmapEffect::Sub){
00107               Square ePos=mobilityTable.get(longToShort(Dir),num);
00108               int count=((SD==D || SD==DL || SD==DR) ? ePos.y()-pos.y() :
00109                          ( (SD==U || SD==UL || SD==UR) ? pos.y()-ePos.y() :
00110                            ( SD==L ? ePos.x()-pos.x() : pos.x()-ePos.x())));
00111               assert(0<=count && count<=9);
00112               if(UC){
00113                 for(int i=1;i<count;i++){
00114                   pos+=offset;
00115                   posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00116                   effects[pos.index()].template opEqual<OP>(effect);
00117                   changed_effects[P].set(posIndex);
00118                 }
00119                 Piece p;
00120                 mobilityTable.set(longToShort(Dir),num,Square::STAND());
00121                 int num1=state.pieceAt(ePos).number();
00122                 if (!Piece::isEdgeNum(num1)){
00123                   effectedNumTable[num1][SD]=EMPTY_NUM;
00124                   effects[ePos.index()].template opEqual<OP>(effect);
00125                   effected_changed_mask[P].set(num1);
00126                   posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00127                   changed_effects[P].set(posIndex);
00128                   if((effects[ePos.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
00129                     effected_mask[P].reset(num1);
00130                   }
00131                 }
00132               }
00133               else{
00134                 for(int i=0;i<count;i++){
00135                   pos+=offset;
00136                   effects[pos.index()].template opEqual<OP>(effect);
00137                 }
00138                 int num1=state.pieceAt(ePos).number();
00139                 if (!Piece::isEdgeNum(num1))
00140                   effectedNumTable[num1][SD]=EMPTY_NUM;
00141               }
00142             }
00143             else{ // OP==Add
00144               for (;;)
00145                 {
00146                   pos=pos+offset;
00147                   if(UC){
00148                     posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00149                     changed_effects[P].set(posIndex);
00150                   }
00151                   effects[pos.index()].template opEqual<OP>(effect);
00152                   // effect内にemptyを含むようにしたら短くなる
00153                   int num1=state.pieceAt(pos).number();
00154                   if (!Piece::isEmptyNum(num1)){
00155                     if(UC){
00156                       mobilityTable.set(longToShort(Dir),num,pos);
00157                       if(!Piece::isEdgeNum(num1)){
00158                         effectedNumTable[num1][SD]=num;
00159                         changed_effects[P].set(posIndex);
00160                         effected_mask[P].set(num1);
00161                         effected_changed_mask[P].set(num1);
00162                       }
00163                     }
00164                     else if(!Piece::isEdgeNum(num1)){
00165                       effectedNumTable[num1][SD]=num;
00166                     }
00167                     break;
00168                   }
00169                 }
00170             }
00171           }
00172       }
00182       template<Player P,Ptype T,NumBitmapEffect::Op OP,bool UC>
00183       void doEffectBy(const SimpleState& state,Square pos,int num);
00192       template<NumBitmapEffect::Op OP,bool UC>
00193       void doEffect(const SimpleState& state,PtypeO ptypeo,Square pos,int num);
00194 
00201       template<NumBitmapEffect::Op OP,bool UC>
00202       void doEffect(const SimpleState& state,Piece p)
00203       {
00204         doEffect<OP,UC>(state,p.ptypeO(),p.square(),p.number());
00205       }
00210       void init(const SimpleState& state);
00214       NumSimpleEffectTable(const SimpleState& state)
00215       {
00216         assert(reinterpret_cast<size_t>(this) % 16 == 0);
00217         init(state);
00218       }
00223       const NumBitmapEffect effectSetAt(Square pos) const
00224       {
00225         return effects[pos.index()];
00226       }
00233       template<NumBitmapEffect::Op OP,bool UC>
00234       void doBlockAt(const SimpleState& state,Square pos,int piece_num);
00235       friend bool operator==(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2);
00236       /*
00237        *
00238        */
00239       const BoardMask changedEffects(Player pl) const{
00240         return changed_effects[pl];
00241       }
00242       const NumBitmapEffect changedPieces() const {
00243         return changed_effect_pieces;
00244       }
00245       const PieceMask effectedMask(Player pl) const {
00246         return effected_mask[playerToIndex(pl)];
00247       }
00248       const PieceMask effectedChanged(Player pl) const {
00249         return effected_changed_mask[playerToIndex(pl)];
00250       }
00251       void setChangedPieces(NumBitmapEffect const& effect) {
00252         changed_effect_pieces |= effect;
00253       }
00254       void clearChangedEffects(){
00255         changed_effects[0].clear();
00256         changed_effects[1].clear();
00257         changed_effect_pieces.resetAll();
00258       }
00259       void invalidateChangedEffects(){
00260         changed_effects[0].invalidate();
00261         changed_effects[1].invalidate();
00262         changed_effect_pieces.setAll();
00263       }
00264       void clearEffectedChanged(){
00265         effected_changed_mask[0].resetAll();
00266         effected_changed_mask[1].resetAll();
00267       }
00269       void copyFrom(const NumSimpleEffectTable& src);
00270     };
00271 
00272     inline bool operator!=(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2)
00273     {
00274       return !(et1==et2);
00275     }
00276 
00277   } // namespace effect
00278   using effect::NumBitmapEffect;
00279 
00280 } // namespace osl
00281 
00288 template<osl::effect::NumBitmapEffect::Op OP,bool UC>
00289 void osl::effect::
00290 NumSimpleEffectTable::doBlockAt(const SimpleState& state,Square pos,int piece_num)
00291 {
00292   if(UC){
00293     setChangedPieces(effects[pos.index()]);
00294   }
00295   mask_t mask1 =((effects[pos.index()].getMask(1))
00296                  & NumBitmapEffect::longEffectMask());
00297   while (mask1.any()){
00298     int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
00299     assert(32<=num && num<=39);
00300     Piece p1=state.pieceOf(num);
00301     Player pl1=p1.owner();
00302     assert(p1.ptype()!=PPAWN);
00303     Square pos1=p1.square();
00304     Offset offset0;
00305     Direction d=Board_Table.getShort8<BLACK>(pos1,pos,offset0);
00306     if(OP==NumBitmapEffect::Sub){
00307       Square endSquare=mobilityTable.get(d,num);
00308       NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
00309       Piece p;
00310       Square pos2=pos+offset0;
00311       int pos2Index, offset81;
00312       if(UC){
00313         int posIndex=BoardMask::index(pos);
00314         pos2Index=BoardMask::index(pos2);
00315         offset81=pos2Index-posIndex;
00316       }
00317       for(;pos2!=endSquare;pos2+=offset0){
00318         if(UC){
00319           changed_effects[pl1].set(pos2Index);
00320           pos2Index+=offset81;
00321         }
00322         effects[pos2.index()].template opEqual<OP>(effect);
00323       }
00324       effects[pos2.index()].template opEqual<OP>(effect);
00325       int num1=state.pieceAt(endSquare).number();
00326       if (!Piece::isEdgeNum(num1)){
00327         effectedNumTable[num1][d]=EMPTY_NUM;
00328         if(UC){
00329           changed_effects[pl1].set(pos2Index);
00330           if((effects[endSquare.index()].getMask(1)&NumBitmapEffect::playerEffectMask(pl1)).none()){
00331             effected_mask[pl1].reset(num1);
00332           }
00333           effected_changed_mask[pl1].set(num1);
00334           mobilityTable.set(d,num,pos);
00335         }
00336       }
00337       else 
00338         mobilityTable.set(d,num,pos);
00339       effectedNumTable[piece_num][d]=num;
00340     }
00341     else{
00342       NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
00343       Square pos2=pos+offset0;
00344       int pos2Index, offset81;
00345       if(UC){
00346         int posIndex=BoardMask::index(pos);
00347         pos2Index=BoardMask::index(pos2);
00348         offset81=pos2Index-posIndex;
00349       }
00350       for(;;){
00351         int num1=state.pieceAt(pos2).number();
00352         if(!Piece::isEmptyNum(num1)){
00353           if(UC){
00354             mobilityTable.set(d,num,pos2);
00355             if(!Piece::isEdgeNum(num1)){
00356               effectedNumTable[num1][d]=num;
00357               effects[pos2.index()].template opEqual<OP>(effect);
00358               changed_effects[pl1].set(pos2Index);
00359               effected_mask[pl1].set(num1);
00360               effected_changed_mask[pl1].set(num1);
00361             }
00362           }
00363           else if(!Piece::isEdgeNum(num1)){
00364             effectedNumTable[num1][d]=num;
00365             effects[pos2.index()].template opEqual<OP>(effect);
00366           }
00367           break;
00368         }
00369         if(UC){
00370           changed_effects[pl1].set(pos2Index);
00371           pos2Index+=offset81;
00372         }
00373         effects[pos2.index()].template opEqual<OP>(effect);
00374         pos2+=offset0;
00375       }
00376     }
00377   }
00378 }
00379 
00380 #endif // OSL_NUM_SIMPLE_EFFECT_H
00381 // ;;; Local Variables:
00382 // ;;; mode:c++
00383 // ;;; c-basic-offset:2
00384 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines