00001 #ifndef _NUM_SIMPLE_EFFECT_H
00002 #define _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/apply_move/applyDoUndoXMove.h"
00009 #include "osl/piece.h"
00010 #include "osl/state/simpleState.h"
00011 #include "osl/misc/fastCopier.h"
00012 #include "osl/mobility/mobilityTable.h"
00013 #include "osl/effect/effectedNumTable.h"
00014
00015 #include <boost/static_assert.hpp>
00016
00017 namespace osl
00018 {
00019 namespace checkmate
00020 {
00021 class King8Info;
00022 }
00023 namespace effect
00024 {
00025 class NumSimpleEffectTable;
00026 bool operator==(const NumSimpleEffectTable&,const NumSimpleEffectTable&);
00027 std::ostream& operator<<(std::ostream&, const NumSimpleEffectTable&);
00028
00032 class NumSimpleEffectTable
00033 {
00034 protected:
00035 CArray<NumBitmapEffect, Position::SIZE> effects
00036 #ifdef __GNUC__
00037 __attribute__((aligned(16)))
00038 #endif
00039 ;
00040 CArray<BoardMask,2> changed_effects;
00042 NumBitmapEffect changed_effect_pieces;
00043 public:
00044 CArray<PieceMask,2> effected_mask;
00045 CArray<PieceMask,2> effected_changed_mask;
00047 mobility::MobilityTable mobilityTable;
00049 EffectedNumTable effectedNumTable;
00059 template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
00060 void doEffectShort(const SimpleState& state,Position pos,int num)
00061 {
00062 if ((PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask)!=0)
00063 {
00064 const Position target = pos+DirectionPlayerTraits<Dir,P>::offset();
00065 effects[target.index()].template opEqual<OP>(NumBitmapEffect::makeEffect<P>(num));
00066 if(UC){
00067 int posIndex=BoardMask::index(pos);
00068 changed_effects[P].set(posIndex+BoardMask::getIndexOffset<Dir,P>());
00069 int num1;
00070 if(Piece::isPieceNum(num1=state.getPieceAt(target).number())){
00071 if(OP==NumBitmapEffect::Add){
00072 effected_mask[P].set(num1);
00073 }
00074 else{
00075 if((effects[target.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
00076 effected_mask[P].reset(num1);
00077 }
00078 }
00079 effected_changed_mask[P].set(num1);
00080 }
00081 }
00082 }
00083 }
00094 template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
00095 void doEffectLong(const SimpleState& state,Position pos,int num)
00096 {
00097 if ((PtypeTraits<T>::moveMask & DirectionTraits<DirectionPlayerTraits<Dir,P>::directionByBlack>::mask)!=0)
00098 {
00099 int posIndex;
00100 if(UC){
00101 posIndex=BoardMask::index(pos);
00102 }
00103 const Offset offset=DirectionPlayerTraits<Dir,BLACK>::offset();
00104 assert(!offset.zero());
00105 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect<P>(num);
00106
00107 const Direction SD=longToShort(Dir);
00108 if(OP==NumBitmapEffect::Sub){
00109 Position ePos=mobilityTable.get(longToShort(Dir),num);
00110 int count=((SD==D || SD==DL || SD==DR) ? ePos.y()-pos.y() :
00111 ( (SD==U || SD==UL || SD==UR) ? pos.y()-ePos.y() :
00112 ( SD==L ? ePos.x()-pos.x() : pos.x()-ePos.x())));
00113 assert(0<=count && count<=9);
00114 if(UC){
00115 for(int i=1;i<count;i++){
00116 pos+=offset;
00117 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00118 effects[pos.index()].template opEqual<OP>(effect);
00119 changed_effects[P].set(posIndex);
00120 }
00121 Piece p;
00122 mobilityTable.set(longToShort(Dir),num,Position::STAND());
00123 int num1=state.getPieceAt(ePos).number();
00124 if (!Piece::isEdgeNum(num1)){
00125 effectedNumTable[num1][SD]=EMPTY_NUM;
00126 effects[ePos.index()].template opEqual<OP>(effect);
00127 effected_changed_mask[P].set(num1);
00128 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00129 changed_effects[P].set(posIndex);
00130 if((effects[ePos.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
00131 effected_mask[P].reset(num1);
00132 }
00133 }
00134 }
00135 else{
00136 for(int i=0;i<count;i++){
00137 pos+=offset;
00138 effects[pos.index()].template opEqual<OP>(effect);
00139 }
00140 int num1=state.getPieceAt(ePos).number();
00141 if (!Piece::isEdgeNum(num1))
00142 effectedNumTable[num1][SD]=EMPTY_NUM;
00143 }
00144 }
00145 else{
00146 for (;;)
00147 {
00148 pos=pos+offset;
00149 if(UC){
00150 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
00151 changed_effects[P].set(posIndex);
00152 }
00153 effects[pos.index()].template opEqual<OP>(effect);
00154
00155 int num1=state.getPieceAt(pos).number();
00156 if (!Piece::isEmptyNum(num1)){
00157 if(UC){
00158 mobilityTable.set(longToShort(Dir),num,pos);
00159 if(!Piece::isEdgeNum(num1)){
00160 effectedNumTable[num1][SD]=num;
00161 changed_effects[P].set(posIndex);
00162 effected_mask[P].set(num1);
00163 effected_changed_mask[P].set(num1);
00164 }
00165 }
00166 else if(!Piece::isEdgeNum(num1)){
00167 effectedNumTable[num1][SD]=num;
00168 }
00169 break;
00170 }
00171 }
00172 }
00173 }
00174 }
00184 template<Player P,Ptype T,NumBitmapEffect::Op OP,bool UC>
00185 void doEffectBy(const SimpleState& state,Position pos,int num);
00194 template<NumBitmapEffect::Op OP,bool UC>
00195 void doEffect(const SimpleState& state,PtypeO ptypeo,Position pos,int num);
00196
00203 template<NumBitmapEffect::Op OP,bool UC>
00204 void doEffect(const SimpleState& state,Piece p)
00205 {
00206 doEffect<OP,UC>(state,p.ptypeO(),p.position(),p.number());
00207 }
00212 void init(const SimpleState& state);
00216 NumSimpleEffectTable(const SimpleState& state)
00217 {
00218 assert(reinterpret_cast<size_t>(this) % 16 == 0);
00219 init(state);
00220 }
00225 const NumBitmapEffect getEffect(Position pos) const
00226 {
00227 return effects[pos.index()];
00228 }
00235 template<NumBitmapEffect::Op OP,bool UC>
00236 void doBlockAt(const SimpleState& state,Position pos,int piece_num);
00237 friend bool operator==(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2);
00238
00239
00240
00241 const BoardMask changedEffects(Player pl) const{
00242 return changed_effects[pl];
00243 }
00244 const NumBitmapEffect changedPieces() const {
00245 return changed_effect_pieces;
00246 }
00247 const PieceMask effectedMask(Player pl) const {
00248 return effected_mask[playerToIndex(pl)];
00249 }
00250 const PieceMask effectedChanged(Player pl) const {
00251 return effected_changed_mask[playerToIndex(pl)];
00252 }
00253 void setChangedPieces(NumBitmapEffect const& effect) {
00254 changed_effect_pieces |= effect;
00255 }
00256 void clearChangedEffects(){
00257 changed_effects[0].clear();
00258 changed_effects[1].clear();
00259 changed_effect_pieces.resetAll();
00260 }
00261 void invalidateChangedEffects(){
00262 changed_effects[0].invalidate();
00263 changed_effects[1].invalidate();
00264 changed_effect_pieces.setAll();
00265 }
00266 void clearEffectedChanged(){
00267 effected_changed_mask[0].resetAll();
00268 effected_changed_mask[1].resetAll();
00269 }
00270 friend class osl::misc::FastCopier;
00271 };
00272
00273 inline bool operator!=(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2)
00274 {
00275 return !(et1==et2);
00276 }
00277
00278 }
00279 using effect::NumBitmapEffect;
00280
00281 }
00282
00289 template<osl::effect::NumBitmapEffect::Op OP,bool UC>
00290 void osl::effect::
00291 NumSimpleEffectTable::doBlockAt(const SimpleState& state,Position pos,int piece_num)
00292 {
00293 if(UC){
00294 setChangedPieces(effects[pos.index()]);
00295 }
00296 mask_t mask1 =((effects[pos.index()].getMask(1))
00297 & NumBitmapEffect::longEffectMask());
00298 while (mask1.any()){
00299 int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
00300 assert(32<=num && num<=39);
00301 Piece p1=state.getPieceOf(num);
00302 Player pl1=p1.owner();
00303 assert(p1.ptype()!=PPAWN);
00304 Position pos1=p1.position();
00305 Offset offset0;
00306 Direction d=Board_Table.getShort8<BLACK>(pos1,pos,offset0);
00307 if(OP==NumBitmapEffect::Sub){
00308 Position endPosition=mobilityTable.get(d,num);
00309 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
00310 Piece p;
00311 Position pos2=pos+offset0;
00312 int pos2Index, offset81;
00313 if(UC){
00314 int posIndex=BoardMask::index(pos);
00315 pos2Index=BoardMask::index(pos2);
00316 offset81=pos2Index-posIndex;
00317 }
00318 for(;pos2!=endPosition;pos2+=offset0){
00319 if(UC){
00320 changed_effects[pl1].set(pos2Index);
00321 pos2Index+=offset81;
00322 }
00323 effects[pos2.index()].template opEqual<OP>(effect);
00324 }
00325 effects[pos2.index()].template opEqual<OP>(effect);
00326 int num1=state.getPieceAt(endPosition).number();
00327 if (!Piece::isEdgeNum(num1)){
00328 effectedNumTable[num1][d]=EMPTY_NUM;
00329 if(UC){
00330 changed_effects[pl1].set(pos2Index);
00331 if((effects[endPosition.index()].getMask(1)&NumBitmapEffect::playerEffectMask(pl1)).none()){
00332 effected_mask[pl1].reset(num1);
00333 }
00334 effected_changed_mask[pl1].set(num1);
00335 mobilityTable.set(d,num,pos);
00336 }
00337 }
00338 else
00339 mobilityTable.set(d,num,pos);
00340 effectedNumTable[piece_num][d]=num;
00341 }
00342 else{
00343 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
00344 Position pos2=pos+offset0;
00345 int pos2Index, offset81;
00346 if(UC){
00347 int posIndex=BoardMask::index(pos);
00348 pos2Index=BoardMask::index(pos2);
00349 offset81=pos2Index-posIndex;
00350 }
00351 for(;;){
00352 int num1=state.getPieceAt(pos2).number();
00353 if(!Piece::isEmptyNum(num1)){
00354 if(UC){
00355 mobilityTable.set(d,num,pos2);
00356 if(!Piece::isEdgeNum(num1)){
00357 effectedNumTable[num1][d]=num;
00358 effects[pos2.index()].template opEqual<OP>(effect);
00359 changed_effects[pl1].set(pos2Index);
00360 effected_mask[pl1].set(num1);
00361 effected_changed_mask[pl1].set(num1);
00362 }
00363 }
00364 else if(!Piece::isEdgeNum(num1)){
00365 effectedNumTable[num1][d]=num;
00366 effects[pos2.index()].template opEqual<OP>(effect);
00367 }
00368 break;
00369 }
00370 if(UC){
00371 changed_effects[pl1].set(pos2Index);
00372 pos2Index+=offset81;
00373 }
00374 effects[pos2.index()].template opEqual<OP>(effect);
00375 pos2+=offset0;
00376 }
00377 }
00378 }
00379 }
00380
00381 #endif // _NUM_SIMPLE_EFFECT_H
00382
00383
00384
00385