numSimpleEffect.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
numSimpleEffect.h
Go to the documentation of this file.
1 #ifndef OSL_NUM_SIMPLE_EFFECT_H
2 #define OSL_NUM_SIMPLE_EFFECT_H
3
4 #include "osl/effect/numBitmapEffect.h"
5 #include "osl/misc/carray.h"
6 #include "osl/container/boardMask.h"
7 #include "osl/container/bitXmask.h"
8 #include "osl/piece.h"
9 #include "osl/state/simpleState.h"
10 #include "osl/mobility/mobilityTable.h"
11 #include "osl/effect/effectedNumTable.h"
12
13 #include <boost/static_assert.hpp>
14
15 namespace osl
16 {
17 namespace checkmate
18 {
19 class King8Info;
20 }
21 namespace effect
22 {
23 class NumSimpleEffectTable;
24 bool operator==(const NumSimpleEffectTable&,const NumSimpleEffectTable&);
25 std::ostream& operator<<(std::ostream&, const NumSimpleEffectTable&);
26
30 class NumSimpleEffectTable
31 {
32 protected:
33 CArray<NumBitmapEffect, Square::SIZE> effects
34 #ifdef __GNUC__
35 __attribute__((aligned(16)))
36 #endif
37 ;
38 CArray<BoardMask,2> changed_effects; // each player
40 NumBitmapEffect changed_effect_pieces;
41 public:
42 CArray<PieceMask,2> effected_mask;
43 CArray<PieceMask,2> effected_changed_mask;
45 mobility::MobilityTable mobilityTable;
47 EffectedNumTable effectedNumTable;
57 template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
58 void doEffectShort(const SimpleState& state,Square pos,int num)
59 {
60 if ((PtypeTraits<T>::moveMask & DirectionTraits<Dir>::mask)!=0)
61 {
62 const Square target = pos+DirectionPlayerTraits<Dir,P>::offset();
63 effects[target.index()].template opEqual<OP>(NumBitmapEffect::makeEffect<P>(num));
64 if(UC){
65 int posIndex=BoardMask::index(pos);
66 changed_effects[P].set(posIndex+BoardMask::getIndexOffset<Dir,P>());
67 int num1;
68 if(Piece::isPieceNum(num1=state.pieceAt(target).number())){
69 if(OP==NumBitmapEffect::Add){
70 effected_mask[P].set(num1);
71 }
72 else{ // OP==Sub
73 if((effects[target.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
74 effected_mask[P].reset(num1);
75 }
76 }
77 effected_changed_mask[P].set(num1);
78 }
79 }
80 }
81 }
92 template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
93 void doEffectLong(const SimpleState& state,Square pos,int num)
94 {
95 if ((PtypeTraits<T>::moveMask & DirectionTraits<DirectionPlayerTraits<Dir,P>::directionByBlack>::mask)!=0)
96 {
97 int posIndex;
98 if(UC){
99 posIndex=BoardMask::index(pos);
100 }
101 const Offset offset=DirectionPlayerTraits<Dir,BLACK>::offset();
102 assert(!offset.zero());
103 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect<P>(num);
104
105 const Direction SD=longToShort(Dir);
106 if(OP==NumBitmapEffect::Sub){
107 Square ePos=mobilityTable.get(longToShort(Dir),num);
108 int count=((SD==D || SD==DL || SD==DR) ? ePos.y()-pos.y() :
109 ( (SD==U || SD==UL || SD==UR) ? pos.y()-ePos.y() :
110 ( SD==L ? ePos.x()-pos.x() : pos.x()-ePos.x())));
111 assert(0<=count && count<=9);
112 if(UC){
113 for(int i=1;i<count;i++){
114 pos+=offset;
115 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
116 effects[pos.index()].template opEqual<OP>(effect);
117 changed_effects[P].set(posIndex);
118 }
119 Piece p;
120 mobilityTable.set(longToShort(Dir),num,Square::STAND());
121 int num1=state.pieceAt(ePos).number();
122 if (!Piece::isEdgeNum(num1)){
123 effectedNumTable[num1][SD]=EMPTY_NUM;
124 effects[ePos.index()].template opEqual<OP>(effect);
125 effected_changed_mask[P].set(num1);
126 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
127 changed_effects[P].set(posIndex);
128 if((effects[ePos.index()].getMask(1)&NumBitmapEffect::playerEffectMask(P)).none()){
129 effected_mask[P].reset(num1);
130 }
131 }
132 }
133 else{
134 for(int i=0;i<count;i++){
135 pos+=offset;
136 effects[pos.index()].template opEqual<OP>(effect);
137 }
138 int num1=state.pieceAt(ePos).number();
139 if (!Piece::isEdgeNum(num1))
140 effectedNumTable[num1][SD]=EMPTY_NUM;
141 }
142 }
143 else{ // OP==Add
144 for (;;)
145 {
146 pos=pos+offset;
147 if(UC){
148 posIndex+=BoardMask::getIndexOffset<Dir,BLACK>();
149 changed_effects[P].set(posIndex);
150 }
151 effects[pos.index()].template opEqual<OP>(effect);
152 // effect内にemptyを含むようにしたら短くなる
153 int num1=state.pieceAt(pos).number();
154 if (!Piece::isEmptyNum(num1)){
155 if(UC){
156 mobilityTable.set(longToShort(Dir),num,pos);
157 if(!Piece::isEdgeNum(num1)){
158 effectedNumTable[num1][SD]=num;
159 changed_effects[P].set(posIndex);
160 effected_mask[P].set(num1);
161 effected_changed_mask[P].set(num1);
162 }
163 }
164 else if(!Piece::isEdgeNum(num1)){
165 effectedNumTable[num1][SD]=num;
166 }
167 break;
168 }
169 }
170 }
171 }
172 }
182 template<Player P,Ptype T,NumBitmapEffect::Op OP,bool UC>
183 void doEffectBy(const SimpleState& state,Square pos,int num);
192 template<NumBitmapEffect::Op OP,bool UC>
193 void doEffect(const SimpleState& state,PtypeO ptypeo,Square pos,int num);
194
201 template<NumBitmapEffect::Op OP,bool UC>
202 void doEffect(const SimpleState& state,Piece p)
203 {
204 doEffect<OP,UC>(state,p.ptypeO(),p.square(),p.number());
205 }
210 void init(const SimpleState& state);
214 NumSimpleEffectTable(const SimpleState& state)
215 {
216 assert(reinterpret_cast<size_t>(this) % 16 == 0);
217 init(state);
218 }
223 const NumBitmapEffect effectSetAt(Square pos) const
224 {
225 return effects[pos.index()];
226 }
233 template<NumBitmapEffect::Op OP,bool UC>
234 void doBlockAt(const SimpleState& state,Square pos,int piece_num);
235 friend bool operator==(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2);
236 /*
237 *
238 */
239 const BoardMask changedEffects(Player pl) const{
240 return changed_effects[pl];
241 }
242 const NumBitmapEffect changedPieces() const {
243 return changed_effect_pieces;
244 }
245 const PieceMask effectedMask(Player pl) const {
246 return effected_mask[playerToIndex(pl)];
247 }
248 const PieceMask effectedChanged(Player pl) const {
249 return effected_changed_mask[playerToIndex(pl)];
250 }
251 void setChangedPieces(NumBitmapEffect const& effect) {
252 changed_effect_pieces |= effect;
253 }
254 void clearChangedEffects(){
255 changed_effects[0].clear();
256 changed_effects[1].clear();
257 changed_effect_pieces.resetAll();
258 }
259 void invalidateChangedEffects(){
260 changed_effects[0].invalidate();
261 changed_effects[1].invalidate();
262 changed_effect_pieces.setAll();
263 }
264 void clearEffectedChanged(){
265 effected_changed_mask[0].resetAll();
266 effected_changed_mask[1].resetAll();
267 }
269 void copyFrom(const NumSimpleEffectTable& src);
270 };
271
272 inline bool operator!=(const NumSimpleEffectTable& et1,const NumSimpleEffectTable& et2)
273 {
274 return !(et1==et2);
275 }
276
277 } // namespace effect
278 using effect::NumBitmapEffect;
279
280 } // namespace osl
281
288 template<osl::effect::NumBitmapEffect::Op OP,bool UC>
289 void osl::effect::
290 NumSimpleEffectTable::doBlockAt(const SimpleState& state,Square pos,int piece_num)
291 {
292 if(UC){
293 setChangedPieces(effects[pos.index()]);
294 }
295 mask_t mask1 =((effects[pos.index()].getMask(1))
296 & NumBitmapEffect::longEffectMask());
297 while (mask1.any()){
298 int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
299 assert(32<=num && num<=39);
300 Piece p1=state.pieceOf(num);
301 Player pl1=p1.owner();
302 assert(p1.ptype()!=PPAWN);
303 Square pos1=p1.square();
304 Offset offset0;
305 Direction d=Board_Table.getShort8<BLACK>(pos1,pos,offset0);
306 if(OP==NumBitmapEffect::Sub){
307 Square endSquare=mobilityTable.get(d,num);
308 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
309 Piece p;
310 Square pos2=pos+offset0;
311 int pos2Index, offset81;
312 if(UC){
313 int posIndex=BoardMask::index(pos);
314 pos2Index=BoardMask::index(pos2);
315 offset81=pos2Index-posIndex;
316 }
317 for(;pos2!=endSquare;pos2+=offset0){
318 if(UC){
319 changed_effects[pl1].set(pos2Index);
320 pos2Index+=offset81;
321 }
322 effects[pos2.index()].template opEqual<OP>(effect);
323 }
324 effects[pos2.index()].template opEqual<OP>(effect);
325 int num1=state.pieceAt(endSquare).number();
326 if (!Piece::isEdgeNum(num1)){
327 effectedNumTable[num1][d]=EMPTY_NUM;
328 if(UC){
329 changed_effects[pl1].set(pos2Index);
330 if((effects[endSquare.index()].getMask(1)&NumBitmapEffect::playerEffectMask(pl1)).none()){
331 effected_mask[pl1].reset(num1);
332 }
333 effected_changed_mask[pl1].set(num1);
334 mobilityTable.set(d,num,pos);
335 }
336 }
337 else
338 mobilityTable.set(d,num,pos);
339 effectedNumTable[piece_num][d]=num;
340 }
341 else{
342 NumBitmapEffect effect=NumBitmapEffect::makeLongEffect(pl1,num);
343 Square pos2=pos+offset0;
344 int pos2Index, offset81;
345 if(UC){
346 int posIndex=BoardMask::index(pos);
347 pos2Index=BoardMask::index(pos2);
348 offset81=pos2Index-posIndex;
349 }
350 for(;;){
351 int num1=state.pieceAt(pos2).number();
352 if(!Piece::isEmptyNum(num1)){
353 if(UC){
354 mobilityTable.set(d,num,pos2);
355 if(!Piece::isEdgeNum(num1)){
356 effectedNumTable[num1][d]=num;
357 effects[pos2.index()].template opEqual<OP>(effect);
358 changed_effects[pl1].set(pos2Index);
359 effected_mask[pl1].set(num1);
360 effected_changed_mask[pl1].set(num1);
361 }
362 }
363 else if(!Piece::isEdgeNum(num1)){
364 effectedNumTable[num1][d]=num;
365 effects[pos2.index()].template opEqual<OP>(effect);
366 }
367 break;
368 }
369 if(UC){
370 changed_effects[pl1].set(pos2Index);
371 pos2Index+=offset81;
372 }
373 effects[pos2.index()].template opEqual<OP>(effect);
374 pos2+=offset0;
375 }
376 }
377 }
378 }
379
380 #endif // OSL_NUM_SIMPLE_EFFECT_H
381 // ;;; Local Variables:
382 // ;;; mode:c++
383 // ;;; c-basic-offset:2
384 // ;;; End: