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 
5 #include "osl/misc/carray.h"
8 #include "osl/piece.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 
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
41  public:
42  CArray<PieceMask,2> effected_mask;
43  CArray<PieceMask,2> effected_changed_mask;
57  template<Player P,Ptype T,Direction Dir,NumBitmapEffect::Op OP,bool UC>
58  void doEffectShort(const SimpleState& state,Square pos,int num)
59  {
61  {
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  {
96  {
97  int posIndex;
98  if(UC){
99  posIndex=BoardMask::index(pos);
100  }
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;
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  }
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  }
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 {
250  }
251  void setChangedPieces(NumBitmapEffect const& effect) {
252  changed_effect_pieces |= effect;
253  }
255  changed_effects[0].clear();
256  changed_effects[1].clear();
257  changed_effect_pieces.resetAll();
258  }
260  changed_effects[0].invalidate();
261  changed_effects[1].invalidate();
262  changed_effect_pieces.setAll();
263  }
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: