00001 #ifndef OSL_NUM_SIMPLE_EFFECT_H
00002 #define OSL_NUM_SIMPLE_EFFECT_H
00003
00004 #include "osl/simpleState.h"
00005 #include "osl/bits/numBitmapEffect.h"
00006 #include "osl/bits/boardMask.h"
00007 #include "osl/bits/bitXmask.h"
00008 #include "osl/bits/effectedNumTable.h"
00009 #include "osl/mobility/mobilityTable.h"
00010
00011 namespace osl
00012 {
00013 namespace checkmate
00014 {
00015 class King8Info;
00016 }
00017 namespace effect
00018 {
00019 class NumSimpleEffectTable;
00020 bool operator==(const NumSimpleEffectTable&,const NumSimpleEffectTable&);
00021 std::ostream& operator<<(std::ostream&, const NumSimpleEffectTable&);
00022
00026 class NumSimpleEffectTable
00027 {
00028 protected:
00029 CArray<NumBitmapEffect, Square::SIZE> effects
00030 #ifdef __GNUC__
00031 __attribute__((aligned(16)))
00032 #endif
00033 ;
00034 CArray<BoardMask,2> changed_effects;
00036 NumBitmapEffect changed_effect_pieces;
00037 public:
00038 CArray<PieceMask,2> effected_mask;
00039 CArray<PieceMask,2> effected_changed_mask;
00041 mobility::MobilityTable mobilityTable;
00043 EffectedNumTable effectedNumTable;
00053 template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
00054 void doEffectShort(const SimpleState& state,Square pos,int num)
00055 {
00056 if ((PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask)!=0)
00057 {
00058 const Square target = pos+DirectionPlayerTraits<Dir,P>::offset();
00059 effects[target.index()].template opEqual<OP>(NumBitmapEffect::makeEffect<P>(num));
00060 if(UC){
00061 int posIndex=BoardMask::index(pos);
00062 changed_effects[P].set(posIndex+BoardMask::getIndexOffset<Dir,P>());
00063 int num1;
00064 if(Piece::isPieceNum(num1=state.pieceAt(target).number())){
00065 if(OP==NumBitmapEffect::Add){
00066 effected_mask[P].set(num1);
00067 }
00068 else{
00069 if((effects[target.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
00070 effected_mask[P].reset(num1);
00071 }
00072 }
00073 effected_changed_mask[P].set(num1);
00074 }
00075 }
00076 }
00077 }
00088 template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
00089 void doEffectLong(const SimpleState& state,Square pos,int num)
00090 {
00091 if ((PtypeTraits<T>::moveMask & DirectionTraits<DirectionPlayerTraits<Dir,P>::directionByBlack>::mask)!=0)
00092 {
00093 int posIndex;
00094 if(UC){
00095 posIndex=BoardMask::index(pos);
00096 }
00097 const Offset offset=DirectionPlayerTraits<Dir,BLACK>::offset();
00098 assert(!offset.zero());
00099 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect<P>(num);
00100
00101 const Direction SD=longToShort(Dir);
00102 if(OP==NumBitmapEffect::Sub){
00103 Square ePos=mobilityTable.get(longToShort(Dir),num);
00104 int count=((SD==D || SD==DL || SD==DR) ? ePos.y()-pos.y() :
00105 ( (SD==U || SD==UL || SD==UR) ? pos.y()-ePos.y() :
00106 ( SD==L ? ePos.x()-pos.x() : pos.x()-ePos.x())));
00107 assert(0<=count && count<=9);
00108 if(UC){
00109 for(int i=1;i<count;i++){
00110 pos+=offset;
00111 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00112 effects[pos.index()].template opEqual<OP>(effect);
00113 changed_effects[P].set(posIndex);
00114 }
00115 Piece p;
00116 mobilityTable.set(longToShort(Dir),num,Square::STAND());
00117 int num1=state.pieceAt(ePos).number();
00118 if (!Piece::isEdgeNum(num1)){
00119 effectedNumTable[num1][SD]=EMPTY_NUM;
00120 effects[ePos.index()].template opEqual<OP>(effect);
00121 effected_changed_mask[P].set(num1);
00122 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00123 changed_effects[P].set(posIndex);
00124 if((effects[ePos.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
00125 effected_mask[P].reset(num1);
00126 }
00127 }
00128 }
00129 else{
00130 for(int i=0;i<count;i++){
00131 pos+=offset;
00132 effects[pos.index()].template opEqual<OP>(effect);
00133 }
00134 int num1=state.pieceAt(ePos).number();
00135 if (!Piece::isEdgeNum(num1))
00136 effectedNumTable[num1][SD]=EMPTY_NUM;
00137 }
00138 }
00139 else{
00140 for (;;)
00141 {
00142 pos=pos+offset;
00143 if(UC){
00144 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00145 changed_effects[P].set(posIndex);
00146 }
00147 effects[pos.index()].template opEqual<OP>(effect);
00148
00149 int num1=state.pieceAt(pos).number();
00150 if (!Piece::isEmptyNum(num1)){
00151 if(UC){
00152 mobilityTable.set(longToShort(Dir),num,pos);
00153 if(!Piece::isEdgeNum(num1)){
00154 effectedNumTable[num1][SD]=num;
00155 changed_effects[P].set(posIndex);
00156 effected_mask[P].set(num1);
00157 effected_changed_mask[P].set(num1);
00158 }
00159 }
00160 else if(!Piece::isEdgeNum(num1)){
00161 effectedNumTable[num1][SD]=num;
00162 }
00163 break;
00164 }
00165 }
00166 }
00167 }
00168 }
00178 template<Player P,Ptype T,NumBitmapEffect::Op OP,bool UC>
00179 void doEffectBy(const SimpleState& state,Square pos,int num);
00188 template<NumBitmapEffect::Op OP,bool UC>
00189 void doEffect(const SimpleState& state,PtypeO ptypeo,Square pos,int num);
00190
00197 template<NumBitmapEffect::Op OP,bool UC>
00198 void doEffect(const SimpleState& state,Piece p)
00199 {
00200 doEffect<OP,UC>(state,p.ptypeO(),p.square(),p.number());
00201 }
00206 void init(const SimpleState& state);
00210 NumSimpleEffectTable(const SimpleState& state)
00211 {
00212 assert(reinterpret_cast<size_t>(this) % 16 == 0);
00213 init(state);
00214 }
00219 const NumBitmapEffect effectSetAt(Square pos) const
00220 {
00221 return effects[pos.index()];
00222 }
00229 template<NumBitmapEffect::Op OP,bool UC>
00230 void doBlockAt(const SimpleState& state,Square pos,int piece_num);
00231 friend bool operator==(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2);
00232
00233
00234
00235 const BoardMask changedEffects(Player pl) const{
00236 return changed_effects[pl];
00237 }
00238 const NumBitmapEffect changedPieces() const {
00239 return changed_effect_pieces;
00240 }
00241 const PieceMask effectedMask(Player pl) const {
00242 return effected_mask[playerToIndex(pl)];
00243 }
00244 const PieceMask effectedChanged(Player pl) const {
00245 return effected_changed_mask[playerToIndex(pl)];
00246 }
00247 void setChangedPieces(NumBitmapEffect const& effect) {
00248 changed_effect_pieces |= effect;
00249 }
00250 void clearChangedEffects(){
00251 changed_effects[0].clear();
00252 changed_effects[1].clear();
00253 changed_effect_pieces.resetAll();
00254 }
00255 void invalidateChangedEffects(){
00256 changed_effects[0].invalidate();
00257 changed_effects[1].invalidate();
00258 changed_effect_pieces.setAll();
00259 }
00260 void clearEffectedChanged(){
00261 effected_changed_mask[0].resetAll();
00262 effected_changed_mask[1].resetAll();
00263 }
00265 void copyFrom(const NumSimpleEffectTable& src);
00266 };
00267
00268 inline bool operator!=(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2)
00269 {
00270 return !(et1==et2);
00271 }
00272
00273 }
00274 using effect::NumBitmapEffect;
00275
00276 }
00277
00284 template<osl::effect::NumBitmapEffect::Op OP,bool UC>
00285 void osl::effect::
00286 NumSimpleEffectTable::doBlockAt(const SimpleState& state,Square pos,int piece_num)
00287 {
00288 if(UC){
00289 setChangedPieces(effects[pos.index()]);
00290 }
00291 mask_t mask1 =((effects[pos.index()].getMask(1))
00292 & NumBitmapEffect::longEffectMask());
00293 while (mask1.any()){
00294 int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
00295 assert(32<=num && num<=39);
00296 Piece p1=state.pieceOf(num);
00297 Player pl1=p1.owner();
00298 assert(p1.ptype()!=PPAWN);
00299 Square pos1=p1.square();
00300 Offset offset0;
00301 Direction d=Board_Table.getShort8<BLACK>(pos1,pos,offset0);
00302 if(OP==NumBitmapEffect::Sub){
00303 Square endSquare=mobilityTable.get(d,num);
00304 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
00305 Piece p;
00306 Square pos2=pos+offset0;
00307 int pos2Index, offset81;
00308 if(UC){
00309 int posIndex=BoardMask::index(pos);
00310 pos2Index=BoardMask::index(pos2);
00311 offset81=pos2Index-posIndex;
00312 }
00313 for(;pos2!=endSquare;pos2+=offset0){
00314 if(UC){
00315 changed_effects[pl1].set(pos2Index);
00316 pos2Index+=offset81;
00317 }
00318 effects[pos2.index()].template opEqual<OP>(effect);
00319 }
00320 effects[pos2.index()].template opEqual<OP>(effect);
00321 int num1=state.pieceAt(endSquare).number();
00322 if (!Piece::isEdgeNum(num1)){
00323 effectedNumTable[num1][d]=EMPTY_NUM;
00324 if(UC){
00325 changed_effects[pl1].set(pos2Index);
00326 if((effects[endSquare.index()].getMask(1)&NumBitmapEffect::playerEffectMask(pl1)).none()){
00327 effected_mask[pl1].reset(num1);
00328 }
00329 effected_changed_mask[pl1].set(num1);
00330 mobilityTable.set(d,num,pos);
00331 }
00332 }
00333 else
00334 mobilityTable.set(d,num,pos);
00335 effectedNumTable[piece_num][d]=num;
00336 }
00337 else{
00338 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
00339 Square pos2=pos+offset0;
00340 int pos2Index, offset81;
00341 if(UC){
00342 int posIndex=BoardMask::index(pos);
00343 pos2Index=BoardMask::index(pos2);
00344 offset81=pos2Index-posIndex;
00345 }
00346 for(;;){
00347 int num1=state.pieceAt(pos2).number();
00348 if(!Piece::isEmptyNum(num1)){
00349 if(UC){
00350 mobilityTable.set(d,num,pos2);
00351 if(!Piece::isEdgeNum(num1)){
00352 effectedNumTable[num1][d]=num;
00353 effects[pos2.index()].template opEqual<OP>(effect);
00354 changed_effects[pl1].set(pos2Index);
00355 effected_mask[pl1].set(num1);
00356 effected_changed_mask[pl1].set(num1);
00357 }
00358 }
00359 else if(!Piece::isEdgeNum(num1)){
00360 effectedNumTable[num1][d]=num;
00361 effects[pos2.index()].template opEqual<OP>(effect);
00362 }
00363 break;
00364 }
00365 if(UC){
00366 changed_effects[pl1].set(pos2Index);
00367 pos2Index+=offset81;
00368 }
00369 effects[pos2.index()].template opEqual<OP>(effect);
00370 pos2+=offset0;
00371 }
00372 }
00373 }
00374 }
00375
00376 #endif // OSL_NUM_SIMPLE_EFFECT_H
00377
00378
00379
00380