All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
numEffectState.h
Go to the documentation of this file.
1 /* numEffectState.h
2  */
3 #ifndef OSL_NUM_EFFECT_STATE_H
4 #define OSL_NUM_EFFECT_STATE_H
5 
8 #include "osl/misc/align16New.h"
9 #include <boost/cstdint.hpp>
10 
11 namespace osl
12 {
13  namespace checkmate
14  {
15  class King8Info;
16  }
17  namespace state
18  {
19  class NumEffectState;
25  bool operator==(const NumEffectState& st1, const NumEffectState& st2);
26 
32  class NumEffectState : public SimpleState
33 #if OSL_WORDSIZE == 32
34  , public misc::Align16New
35 #endif
36  {
38  CArray<PieceMask,2> pieces_onboard;
40  PieceMask promoted;
41  CArray<PieceMask,2> pin_or_open;
42  KingMobility king_mobility;
43  CArray<uint64_t,2> king8infos;
44 
45  friend bool operator==(const NumEffectState& st1,const NumEffectState& st2);
47  public:
48  // ----------------------------------------------------------------------
49  // 0. 将棋以外の操作
50  // ----------------------------------------------------------------------
54  void copyFrom(const NumEffectState& src);
55  void copyFrom(const SimpleState& src);
56  bool isConsistent(bool showError=true) const;
58  bool isConsistent(const NumEffectState& prev, Move moved, bool show_error=true) const;
59  void showEffect(std::ostream& os) const;
60 
61 
62  // ----------------------------------------------------------------------
63  // 1. 盤面全体の情報
64  // ----------------------------------------------------------------------
65  const PieceMask& piecesOnBoard(Player p) const { return pieces_onboard[p]; }
66  const PieceMask promotedPieces() const { return promoted; }
67  const PieceMask pin(Player king) const
68  {
69  return pin_or_open[king]&piecesOnBoard(king);
70  }
72  const PieceMask checkShadow(Player attack) const
73  {
74  return pin_or_open[alt(attack)]&piecesOnBoard(attack);
75  }
76  PieceMask pinOrOpen(Player king) const
77  {
78  return pin_or_open[king];
79  }
80  uint64_t Iking8Info(Player king) const
81  {
82  return king8infos[king];
83  }
85 #ifdef __GNUC__
86  __attribute__ ((pure))
87 #endif
88  king8Info(Player king) const;
90  bool inCheck(Player P) const
91  {
92  const Square king = kingSquare(P);
93 #ifdef ALLOW_KING_ABSENCE
94  if (king.isPieceStand())
95  return false;
96 #endif
97  return hasEffectAt(alt(P), king);
98  }
100  bool inCheck() const { return inCheck(turn()); }
101  const EffectedNumTable& longEffectNumTable() const
102  {
103  return effects.effectedNumTable;
104  }
105 
107  const PieceMask effectedMask(Player pl) const
108  {
109  return effects.effected_mask[pl];
110  }
114  const PieceMask effectedChanged(Player pl) const
115  {
116  return effects.effected_changed_mask[pl];
117  }
118  bool hasChangedEffects() const {
119  return ! effects.changedEffects(BLACK).isInvalid();
120  }
121  const BoardMask changedEffects(Player pl) const{
122  assert(hasChangedEffects());
123  return effects.changedEffects(pl);
124  }
125  const BoardMask changedEffects() const{
126  BoardMask ret = changedEffects(BLACK);
127  return ret |= changedEffects(WHITE);
128  }
129  const NumBitmapEffect changedPieces() const{
130  return effects.changedPieces();
131  }
132  template <Ptype PTYPE> bool longEffectChanged() const
133  {
134  return changedPieces().template hasLong<PTYPE>();
135  }
136  template <Ptype PTYPE> bool anyEffectChanged() const
137  {
138  return changedPieces().template hasAny<PTYPE>();
139  }
140 
142  const Piece findThreatenedPiece(Player P) const;
143 
144  // ----------------------------------------------------------------------
145  // 2. 駒に関する情報
146  // ----------------------------------------------------------------------
147  bool isOnBoardNum(int num) const
148  {
149  return piecesOnBoard(BLACK).test(num) || piecesOnBoard(WHITE).test(num);
150  }
151 
152  Square mobilityOf(Direction d,int num) const
153  {
154  return effects.mobilityTable.get(d,num);
155  }
157  {
158  return mobilityOf(d, p.number());
159  }
161  {
162  return Square::makeDirect(king_mobility[p][d]);
163  }
170  {
171  if (p == BLACK)
172  d = inverse(d);
173  return kingMobilityAbs(p, d);
174  }
179  template<Player P>
181  {
182  assert(p.owner() == P);
183  assert(pinOrOpen(P).test(p.number()));
184  Square king=kingSquare<P>();
185  return Board_Table.getShort8<P>(p.square(),king);
186  }
188  {
189  if (p.owner() == BLACK)
190  return pinnedDir<BLACK>(p);
191  else
192  return pinnedDir<WHITE>(p);
193  }
198  template<Player P>
199  bool pinnedCanMoveTo(Piece p,Square to) const
200  {
201  assert(p.owner() == P);
202  Direction d=pinnedDir<P>(p);
203  Square from=p.square();
204  return primDir(d)==primDirUnsafe(Board_Table.getShort8Unsafe<P>(from,to));
205  }
206  bool pinnedCanMoveTo(Piece p,Square to) const
207  {
208  if (p.owner() == BLACK)
209  return pinnedCanMoveTo<BLACK>(p, to);
210  else
211  return pinnedCanMoveTo<WHITE>(p, to);
212  }
216  template<Player P>
217  Piece pinAttacker(Piece pinned) const
218  {
219  assert(pinned.owner() == P);
220  assert(pinOrOpen(P).test(pinned.number()));
221  Direction d=pinnedDir<P>(pinned);
222  int attacker_num=longEffectNumTable()[pinned.number()][(P==BLACK ? d : inverseUnsafe(d))];
223  return pieceOf(attacker_num);
224  }
225  Piece pinAttacker(Piece pinned) const
226  {
227  if (pinned.owner() == BLACK)
228  return pinAttacker<BLACK>(pinned);
229  else
230  return pinAttacker<WHITE>(pinned);
231  }
232  // ----------------------------------------------------------------------
233  // 3. あるSquareへの利き
234  // ----------------------------------------------------------------------
235  const NumBitmapEffect effectSetAt(Square sq) const
236  {
237  return effects.effectSetAt(sq);
238  }
243  int countEffect(Player player,Square target) const
244  {
245  assert(target.isOnBoard());
246  return effectSetAt(target).countEffect(player);
247  }
253  int
254 #ifdef __GNUC__
255  __attribute__ ((pure))
256 #endif
257  countEffect(Player player,Square target, PieceMask pins) const
258  {
259  assert(target.isOnBoard());
260  const NumBitmapEffect effect = effectSetAt(target);
261  const int all = effect.countEffect(player);
262  pins &= effect;
263  return all - pins.countBit();
264  }
265 
266  // ----------------------------------------------------------------------
267  // 3.1 集合を返す
268  // ----------------------------------------------------------------------
269  template <Ptype PTYPE>
271  {
272  return effectSetAt(target).template selectBit<PTYPE>() & piecesOnBoard(P).template getMask<PTYPE>();
273  }
274  const mask_t allEffectAt(Player P, Ptype ptype, Square target) const;
275  template <Ptype PTYPE> const mask_t longEffectAt(Square target) const
276  {
277  return effectSetAt(target).selectLong<PTYPE>() >> 8;
278  }
279  template <Ptype PTYPE> const mask_t longEffectAt(Square target, Player owner) const
280  {
281  return longEffectAt<PTYPE>(target) & piecesOnBoard(owner).getMask(1);
282  }
284  {
285  return effectSetAt(target).selectLong() >> 8;
286  }
287  const mask_t longEffectAt(Square target, Player owner) const
288  {
289  return longEffectAt(target) & piecesOnBoard(owner).getMask(1);
290  }
291 
292  // ----------------------------------------------------------------------
293  // 3.2 bool を返す
294  // ----------------------------------------------------------------------
300  template<Player P>
301  bool hasEffectAt(Square target) const {
302  assert(target.isOnBoard());
303  mask_t mask=effectSetAt(target).getMask(1);
304  mask&=NumBitmapEffect::playerEffectMask<P>();
305  return !mask.none();
306  }
312  bool hasEffectAt(Player player,Square target) const {
313  assert(target.isOnBoard());
314  mask_t mask=effectSetAt(target).getMask(1);
315  mask&=NumBitmapEffect::playerEffectMask(player);
316  return !mask.none();
317  }
318 
322  template <Ptype PTYPE>
323  bool hasLongEffectAt(Player P, Square to) const {
324  BOOST_STATIC_ASSERT( (PTYPE == LANCE || PTYPE == BISHOP || PTYPE == ROOK) );
325  return longEffectAt<PTYPE>(to, P).any();
326  }
327 
331  template <Ptype PTYPE>
332  bool hasEffectByPtype(Player attack, Square target) const
333  {
334  return allEffectAt<PTYPE>(attack, target).any();
335  }
339  template <Ptype PTYPE>
341  {
342  mask_t mask=allEffectAt<PTYPE>(attack, target);
343  if (isPromoted(PTYPE))
344  mask &= promoted.getMask<PTYPE>();
345  else
346  mask &= ~(promoted.getMask<PTYPE>());
347  return mask.any();
348  }
353  template<Direction Dir,Player P>
354  bool hasEffectInDirection(Square to) const {
356  const PieceMask& pieces_onboard=piecesOnBoard(P);
357  mask_t mask1=pieces_onboard.getMask(1);
359  ? mask_t::makeDirect(PtypeFuns<LANCE>::indexMask)
360  : mask_t::makeDirect(0))
362  ? mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)
363  : mask_t::makeDirect(0))
365  ? mask_t::makeDirect(PtypeFuns<ROOK>::indexMask)
366  : mask_t::makeDirect(0)));
367  mask1 <<= 8;
368  // 短い利きを排除
369  mask1&=effectSetAt(to).getMask(1)& NumBitmapEffect::longEffectMask();
370  while (mask1.any())
371  {
372  int num=mask1.takeOneBit()+NumBitmapEffect::longToNumOffset;
373  Square from = pieceOf(num).square();
376  return true;
377  }
378  return false;
379  }
386  bool hasEffectNotBy(Player player,Piece piece,Square target) const {
387  assert(piece.owner()==player);
388  PieceMask pieces_onboard=piecesOnBoard(player);
389  int num=piece.number();
390  pieces_onboard.reset(num);
391  return (pieces_onboard&effectSetAt(target)).any();
392  }
397  assert(target.isOnBoard());
398  PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
399  m.clearBit<KING>();
400  return m.any();
401  }
406  assert(target.isOnBoard());
407  PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
408  return m.any();
409  }
417  {
418  mask_t mask=effectSetAt(target).getMask(1);
419  mask&=NumBitmapEffect::playerEffectMask(player);
420  return NumBitmapEffect::playerEffect(player).getMask(1) < mask;
421  }
422 
427  bool hasEffectByPiece(Piece attack, Square target) const
428  {
429  assert(attack.isPiece());
430  assert(target.isOnBoard());
431  return effectSetAt(target).test(attack.number());
432  }
433 
434 
442  bool hasEffectIf(PtypeO ptypeo,Square attacker,
443  Square target) const
444 #ifdef __GNUC__
445  __attribute__ ((pure))
446 #endif
447  {
448  Offset32 offset32=Offset32(target,attacker);
449  EffectContent effect=Ptype_Table.getEffect(ptypeo,offset32);
450  if (! effect.hasEffect())
451  return false;
452  if (effect.hasUnblockableEffect())
453  return true;
454  assert(Board_Table.getShortOffset(offset32) == effect.offset());
455  return this->isEmptyBetween(attacker,target,effect.offset());
456  }
460  template<Player P>
461  bool
462 #ifdef __GNUC__
463  __attribute__ ((pure))
464 #endif
465  hasEffectByWithRemove(Square target,Square removed) const;
466 
467  bool hasEffectByWithRemove(Player player, Square target,Square removed) const{
468  if (player==BLACK)
469  return hasEffectByWithRemove<BLACK>(target,removed);
470  else
471  return hasEffectByWithRemove<WHITE>(target,removed);
472  }
473 
474 
475  // ----------------------------------------------------------------------
476  // 3.3 pieceを探す
477  // ----------------------------------------------------------------------
479  template <Ptype PTYPE>
480  const Piece findAttackAt(Player attack, Square target) const
481  {
482  mask_t mask=allEffectAt<PTYPE>(attack, target);
483  if (mask.none())
484  return Piece::EMPTY();
485  return pieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
486  }
487  template <Ptype PTYPE>
489  {
490  mask_t mask=allEffectAt<PTYPE>(attack, target);
491  if (isPromoted(PTYPE))
492  mask &= promoted.getMask<PTYPE>();
493  else
494  mask &= ~(promoted.getMask<PTYPE>());
495  if (mask.none())
496  return Piece::EMPTY();
497  return pieceOf(mask.takeOneBit()+PtypeFuns<PTYPE>::indexNum*32);
498  }
503  const Piece findLongAttackAt(Player owner, int piece, Direction d) const
504  {
505  assert(pieceOf(piece).isOnBoardByOwner(owner));
506  if (owner == BLACK)
507  d = inverse(d);
508  const int num = effects.effectedNumTable[piece][d];
509  if (num == EMPTY_NUM)
510  return Piece::EMPTY();
511  return pieceOf(num);
512  }
513  const Piece findLongAttackAt(Player owner, Piece piece, Direction d) const
514  {
515  assert(piece.isPiece());
516  assert(piece.owner() == owner);
517  return findLongAttackAt(owner, piece.number(), d);
518  }
519  const Piece findLongAttackAt(Piece piece, Direction d) const
520  {
521  assert(piece.isPiece());
522  return findLongAttackAt(piece.owner(), piece, d);
523  }
524  const Piece findLongAttackAt(Square square, Direction d) const
525  {
526  return findLongAttackAt(pieceOnBoard(square), d);
527  }
531  const Piece selectCheapPiece(PieceMask effect) const;
537  const Piece findCheapAttack(Player P, Square square) const
538  {
539  return selectCheapPiece(piecesOnBoard(P) & effectSetAt(square));
540  }
546  const Piece findCheapAttackNotBy(Player P, Square square, const PieceMask& ignore) const
547  {
548  PieceMask pieces = piecesOnBoard(P);
549  pieces &= ~ignore;
550  return selectCheapPiece(pieces & effectSetAt(square));
551  }
552  const Piece findAttackNotBy(Player P, Square square, const PieceMask& ignore) const
553  {
554  PieceMask pieces = piecesOnBoard(P);
555  pieces &= ~ignore;
556  pieces &= effectSetAt(square);
557  if (pieces.none())
558  return Piece::EMPTY();
559  return pieceOf(pieces.takeOneBit());
560  }
569  template<Player P>
570  bool findCheckPiece(Piece& attack_piece) const
571  {
572  return hasEffectAt<PlayerTraits<P>::opponent>(kingSquare(P),attack_piece);
573  }
574  bool hasEffectAt(Player P, Square target,Piece& attackerPiece) const
575  {
576  if (P == BLACK)
577  return hasEffectAt<BLACK>(target, attackerPiece);
578  else
579  return hasEffectAt<WHITE>(target, attackerPiece);
580  }
587  template<Player P>
588  bool hasEffectAt(Square target,Piece& attackerPiece) const {
589  attackerPiece=Piece::EMPTY();
590  const PieceMask& pieceMask=piecesOnBoard(P)&effectSetAt(target);
591 #if OSL_WORDSIZE == 64
592  mask_t mask=pieceMask.getMask(0);
593  if (mask.none()) return false;
598  if (mask.hasMultipleBit())
599  return true;
600  int num=mask.bsf();
601  attackerPiece=pieceOf(num);
602  return true;
603 #elif OSL_WORDSIZE == 32
604  mask_t mask0=pieceMask.getMask(0);
605  mask_t mask1=pieceMask.getMask(1);
606  if (mask0.any())
607  {
608  if (mask1.any())
609  return true;
610  int num=mask0.bsf();
611  if (mask0 == PieceMask::numToMask(num))
612  attackerPiece=pieceOf(num);
613  return true;
614  }
615  else if (mask1.any())
616  {
617  int num=mask1.bsf();
618  if (mask1==PieceMask::numToMask(num))
619  attackerPiece=pieceOf(num+32);
620  return true;
621  }
622  else
623  return false;
624 #endif
625  }
626 
627  // ----------------------------------------------------------------------
628  // 4. 指手
629  // ----------------------------------------------------------------------
640  template <bool show_error>
641  bool isAlmostValidMove(Move move) const;
642  bool isAlmostValidMove(Move move,bool show_error=true) const;
643  void makeMove(Move move);
645  {
646  changeTurn();
649  }
650 
651  template <class Function>
652  void makeUnmakePass(Function &f)
653  {
654  changeTurn();
655  f(Square::STAND());
656  changeTurn();
657  }
658  template <class Function>
659  void makeUnmakeMove(Move move, Function &f)
660  {
661  if (move.player() == BLACK)
662  makeUnmakeMove(Player2Type<BLACK>(), move, f);
663  else
664  makeUnmakeMove(Player2Type<WHITE>(), move, f);
665  }
666  template <Player P, class Function>
667  void makeUnmakeMove(Player2Type<P> player, Move move, Function &f)
668  {
669  if (move.isPass())
670  return makeUnmakePass(f);
671  assert(move.isValid());
672  assert(isAlmostValidMove(move));
673  assert(P == move.player());
674  assert(P == turn());
675  Square from=move.from();
676  Square to=move.to();
677  if (from.isPieceStand())
678  {
679  assert(pieceAt(to) == Piece::EMPTY());
680  doUndoDropMove(player,to,move.ptype(),f);
681  }
682  else
683  {
684  assert(pieceAt(from) != Piece::EMPTY());
685  Piece captured=pieceAt(to);
686  if (captured != Piece::EMPTY())
687  {
688  doUndoCaptureMove(player,from,to,captured,move.promoteMask(),f);
689  }
690  else
691  {
692  doUndoSimpleMove(player,from,to,move.promoteMask(),f);
693  }
694  }
695  }
696  bool wasCheckEvasion(Move last_move) const;
697  // ----------------------------------------------------------------------
698  // 5. forEachXXX
699  // ----------------------------------------------------------------------
702  template<Player P,Ptype T,typename F>
703  void forEachOnBoard(F& func) const {
704  mask_t onMask=piecesOnBoard(P).template selectBit<T>() ;
705  while (onMask.any())
706  {
707  int num=onMask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
708  Piece p = pieceOf(num);
709  func(p);
710  }
711  }
714  template<Player P,Ptype T,typename F>
715  void forEachOnBoardPtypeStrict(F& func) const
716  {
717  mask_t mask=piecesOnBoard(P).template selectBit<T>() ;
718  if (isPromoted(T))
719  mask &= promoted.getMask<T>();
720  else
721  mask &= ~(promoted.getMask<T>());
722  while (mask.any())
723  {
724  int num=mask.takeOneBit()+((PtypeFuns<T>::indexNum)<<5);
725  func(pieceOf(num));
726  }
727  }
728  private:
729  template<Player P,class Action>
730  void forEachEffect(const PieceMask& pieces, Square sq,Action & action) const
731  {
732 #if OSL_WORDSIZE == 64
733  mask_t mask=pieces.getMask(0);
734  while (mask.any())
735  {
736  const int num=mask.takeOneBit();
737  action.template doAction<P>(pieceOf(num),sq);
738  }
739 #elif OSL_WORDSIZE == 32
740  mask_t mask0=pieces.getMask(0);
741  while (mask0.any())
742  {
743  const int num=mask0.takeOneBit();
744  action.template doAction<P>(pieceOf(num),sq);
745  }
746  mask_t mask1=pieces.getMask(1);
747  while (mask1.any())
748  {
749  const int num=mask1.takeOneBit()+32;
750  action.template doAction<P>(pieceOf(num),sq);
751  }
752 #endif
753  }
754  public:
759  template<Player P,class Action>
760  void forEachEffect(Square sq,Action & action) const
761  {
762  const PieceMask pieceMask=piecesOnBoard(P)&effectSetAt(sq);
763  forEachEffect<P,Action>(pieceMask, sq, action);
764  }
770  template<Player P,class Action>
771  void forEachEffect(Square sq,Action & action,const PieceMask& pin) const
772  {
773  PieceMask pieceMask=piecesOnBoard(P)&effectSetAt(sq);
774  pieceMask &= ~pin;
775  forEachEffect<P,Action>(pieceMask, sq, action);
776  }
777 
783  template<Player P,class Action>
784  void forEachEffectNotBy(Square sq,Piece piece,Action & action) const {
785  PieceMask pieces=piecesOnBoard(P)&effectSetAt(sq);
786  pieces.reset(piece.number());
787  forEachEffect<P,Action>(pieces, sq, action);
788  }
789 
790  private:
791  template<Player P,Ptype Type,class Action,Direction Dir>
792  void forEachEffectOfPieceDir(Square, Action&, Int2Type<false>) const {}
793  template<Player P,Ptype Type,class Action,Direction Dir>
794  void forEachEffectOfPieceDir(Square pieceSquare,Action & action,Int2Type<true>) const {
796  action.template doAction<P>(this->pieceAt(pieceSquare),pieceSquare+offset);
797  }
798 
799  template<Player P,Ptype Type,class Action,Direction Dir>
800  void forEachEffectOfPieceDir(Square pieceSquare,Action & action) const {
801  forEachEffectOfPieceDir<P,Type,Action,Dir>(pieceSquare,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
802  }
803  template<Player P,Ptype Type,class Action,Direction Dir>
804  void forEachEffectOfPieceLongDir(Square, Action&, Int2Type<false>) const {}
805  template<Player P,Ptype Type,class Action,Direction Dir>
806  void forEachEffectOfPieceLongDir(Square pieceSquare,Action & action,Int2Type<true>) const {
807  Piece piece=this->pieceAt(pieceSquare);
809  assert(offset.intValue() != 35);
810  Square sq=pieceSquare+offset;
811  for (;this->pieceAt(sq).isEmpty();sq+=offset)
812  action.template doAction<P>(piece,sq);
813  action.template doAction<P>(piece,sq);
814  }
815 
816  template<Player P,Ptype Type,class Action,Direction Dir>
817  void forEachEffectOfPieceLongDir(Square pieceSquare,Action & action) const {
818  forEachEffectOfPieceLongDir<P,Type,Action,Dir>(pieceSquare,action,Int2Type<(PtypeTraits<Type>::moveMask & DirectionTraits<Dir>::mask)!=0>());
819  }
820  public:
828  template<Player P,Ptype Type,class Action>
829  void forEachEffectOfPiece(Square pieceSquare,Action & action) const;
830  template<class Action>
831  void forEachEffectOfPiece(Piece piece,Action & action) const;
832 
833 
834  private:
835  void doSimpleMove(Square from, Square to, int promoteMask);
836  void doDropMove(Square to,Ptype ptype);
837  void doCaptureMove(Square from, Square to, Piece target,int promoteMask);
838 
839  template <Player P, class Function>
840  void doUndoSimpleMove(Player2Type<P> player,
841  Square from, Square to, int promoteMask,Function& func);
842  template <Player P>
843  void prologueSimple(Player2Type<P>, Square from, Square to, int promoteMask,
844  Piece& oldPiece, int& num,
845  PtypeO& oldPtypeO, PtypeO& new_ptypeo,
846  CArray<PieceMask,2>& pin_or_open_backup,
847  KingMobility& king_mobility_backup,
848  PieceMask& promoted_backup,
849  CArray<PieceMask,2>& effected_mask_backup,
850  CArray<PieceMask,2>& effected_changed_mask_backup,
851  CArray<uint64_t,2>& king8infos_backup,
852  MobilityTable &mobility_backup
853  );
854  void epilogueSimple(Square from, Square to, Piece oldPiece,
855  int num, PtypeO oldPtypeO, PtypeO newPtypeO,
856  const CArray<PieceMask,2>& pin_or_open_backup,
857  const KingMobility& king_mobility_backup,
858  const PieceMask& promoted_backup,
859  const CArray<PieceMask,2>& effected_mask_backup,
860  const CArray<PieceMask,2>& effected_changed_mask_backup,
861  const CArray<uint64_t,2>& king8infos_backup,
862  const MobilityTable &mobility_backup
863  );
864  template <Player P, class Function>
865  void doUndoDropMove(Player2Type<P> player,
866  Square to, Ptype ptype, Function& func);
867  template <Player P>
868  void prologueDrop(Player2Type<P>, Square to, Ptype ptype,
869  Piece& oldPiece, int& num, PtypeO& ptypeO,
870  int& numIndex, mask_t& numMask,
871  CArray<PieceMask,2>& pin_or_open_backup,
872  KingMobility& king_mobility_backup,
873  CArray<PieceMask,2>& effected_mask_backup,
874  CArray<PieceMask,2>& effected_changed_mask_backup,
875  CArray<uint64_t,2>& king8infos_backup,
876  MobilityTable &mobility_backup);
877  template<Player P>
878  void epilogueDrop(Player2Type<P>, Square to, Ptype ptype, Piece oldPiece,
879  int num, PtypeO ptypeO, int numIndex, mask_t numMask,
880  const CArray<PieceMask,2>& pin_or_open_backup,
881  const KingMobility& king_mobility_backup,
882  const CArray<PieceMask,2>& effected_mask_backup,
883  const CArray<PieceMask,2>& effected_changed_mask_backup,
884  const CArray<uint64_t,2>& king8infos_backup,
885  const MobilityTable &mobility_backup);
886  template <Player P, class Function>
887  void doUndoCaptureMove(Player2Type<P> player, Square from,Square to,
888  Piece target, int promoteMask,Function& func);
889 
890  template<Player P>
891  void prologueCapture(Player2Type<P>, Square from, Square to, Piece target,
892  int promoteMask,
893  Piece& oldPiece, PtypeO& oldPtypeO, PtypeO& capturePtypeO,
894  PtypeO& new_ptypeo, int& num0, int& num1,
895  int& num1Index, mask_t& num1Mask,
896  CArray<PieceMask,2>& pin_or_open_backup,
897  KingMobility& king_mobility_backup,
898  PieceMask& promoted_backup,
899  CArray<PieceMask,2>& effected_mask_backup,
900  CArray<PieceMask,2>& effected_changed_mask_backup,
901  CArray<uint64_t,2>& king8infos_backup,
902  MobilityTable &mobility_backup);
903 
904  template<Player P>
905  void epilogueCapture(Player2Type<P>, Square from, Square to, Piece target,
906  Piece oldPiece, PtypeO oldPtypeO, PtypeO capturePtypeO,
907  PtypeO newPtypeO, int num0, int num1,
908  int num1Index, mask_t num1Mask,
909  const CArray<PieceMask,2>& pin_or_open_backup,
910  const KingMobility& king_mobility_backup,
911  const PieceMask& promoted_backup,
912  const CArray<PieceMask,2>& effected_mask_backup,
913  const CArray<PieceMask,2>& effected_changed_mask_backup,
914  const CArray<uint64_t,2>& king8infos_backup,
915  const MobilityTable &mobility_backup);
916  //
917  template<Direction DIR>
919  PieceMask& pins, PieceMask const& onBoard,Player defense)
920  {
921  const Offset offset = DirectionTraits<DIR>::blackOffset();
922  Square sq=target-offset;
923  int num;
924  while(Piece::isEmptyNum(num=pieceAt(sq).number()))
925  sq-=offset;
926  king_mobility[defense][DIR]=static_cast<unsigned char>(sq.uintValue());
927  if(Piece::isEdgeNum(num)) return;
928  int num1=longEffectNumTable()[num][DIR];
929  if(Piece::isPieceNum(num1) && onBoard.test(num1)){
930  pins.set(num);
931  }
932  }
933  void recalcPinOpen(Square changed, Direction &lastDir, Player defense)
934  {
935  Square target=kingSquare(defense);
936 #ifdef ALLOW_KING_ABSENCE
937  if (target.isPieceStand())
938  return;
939 #endif
940  const Direction longD=Board_Table.getLongDirection<BLACK>(changed,target);
941  if(!isLong(longD) || (lastDir!=UL && longD==lastDir)) return;
942  lastDir=longD;
943  Direction shortD=longToShort(longD);
944  {
945  // reset old pins
946  Square oldPos=Square::makeDirect(king_mobility[defense][shortD]);
947  int oldNum=pieceAt(oldPos).number();
948  if(Piece::isPieceNum(oldNum))
949  pin_or_open[defense].reset(oldNum);
950  }
951  const Offset offset = Board_Table.getOffsetForBlack(longD);
952  Square sq=target-offset;
953  int num;
954  while(Piece::isEmptyNum(num=pieceAt(sq).number()))
955  sq-=offset;
956  king_mobility[defense][shortD]=static_cast<unsigned char>(sq.uintValue());
957  if(Piece::isEdgeNum(num)) return;
958  int num1=longEffectNumTable()[num][shortD];
959  if(Piece::isPieceNum(num1) && piecesOnBoard(alt(defense)).test(num1)){
960  pin_or_open[defense].set(num);
961  }
962  }
963  PieceMask makePinOpen(Square target,Player defense);
964  void makePinOpen(Player defense);
965  template<Player P>
966  void makeKing8Info();
967  };
968 
969  inline bool operator!=(const NumEffectState& s1, const NumEffectState& s2)
970  {
971  return !(s1==s2);
972  }
973  } // namespace state
974  using state::NumEffectState;
975 } // namespace osl
976 
977 template <osl::Player P, typename Function>
978 void osl::NumEffectState::
979 doUndoSimpleMove(Player2Type<P> player,
980  Square from, Square to, int promoteMask, Function& func)
981 {
982  Piece oldPiece;
983  int num;
984  PtypeO oldPtypeO, newPtypeO;
985  CArray<PieceMask,2> pin_or_open_backup;
986  KingMobility king_mobility_backup;
987  PieceMask promoted_backup;
988  CArray<PieceMask,2> effected_mask_backup;
989  CArray<PieceMask,2> effected_changed_mask_backup;
990  CArray<uint64_t,2> king8infos_backup;
991  MobilityTable mobility_backup;
992  prologueSimple(player, from, to, promoteMask, oldPiece, num, oldPtypeO, newPtypeO,
993  pin_or_open_backup,
994  king_mobility_backup,
995  promoted_backup,
996  effected_mask_backup, effected_changed_mask_backup,
997  king8infos_backup,
998  mobility_backup);
999  if (promoteMask!=0 && num < PtypeTraits<PAWN>::indexLimit)
1000  {
1001  clearPawn(P,from);
1002  changeTurn();
1003  func(to);
1004  changeTurn();
1005  setPawn(P,from);
1006  }
1007  else
1008  {
1009  changeTurn();
1010  func(to);
1011  changeTurn();
1012  }
1013  epilogueSimple(from, to, oldPiece, num, oldPtypeO, newPtypeO,
1014  pin_or_open_backup,
1015  king_mobility_backup,
1016  promoted_backup, effected_mask_backup, effected_changed_mask_backup,
1017  king8infos_backup,
1018  mobility_backup);
1019 }
1020 
1021 template <osl::Player P, typename Function>
1022 void osl::NumEffectState::doUndoDropMove(Player2Type<P> player,
1023  Square to, Ptype ptype, Function& func)
1024 {
1025  Piece oldPiece;
1026  PtypeO ptypeO;
1027  int num, numIndex;
1028  mask_t numMask;
1029  CArray<PieceMask,2> pin_or_open_backup;
1030  KingMobility king_mobility_backup;
1031  CArray<PieceMask,2> effected_mask_backup;
1032  CArray<PieceMask,2> effected_changed_mask_backup;
1033  CArray<uint64_t,2> king8infos_backup;
1034  MobilityTable mobility_backup;
1035  prologueDrop(player, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
1036  pin_or_open_backup, king_mobility_backup,
1037  effected_mask_backup,effected_changed_mask_backup,
1038  king8infos_backup,
1039  mobility_backup);
1040  if (ptype==PAWN)
1041  {
1042  setPawn(P,to);
1043  changeTurn();
1044  func(to);
1045  changeTurn();
1046  clearPawn(P,to);
1047  }
1048  else
1049  {
1050  changeTurn();
1051  func(to);
1052  changeTurn();
1053  }
1054  epilogueDrop(player, to, ptype, oldPiece, num, ptypeO, numIndex, numMask,
1055  pin_or_open_backup, king_mobility_backup,
1056  effected_mask_backup,effected_changed_mask_backup,
1057  king8infos_backup,
1058  mobility_backup);
1059 }
1060 
1061 template <osl::Player P, typename Function>
1062 void osl::NumEffectState::doUndoCaptureMove(Player2Type<P> player,
1063  Square from,Square to, Piece target,
1064  int promoteMask,Function& func)
1065 {
1066  Piece oldPiece;
1067  PtypeO oldPtypeO, capturePtypeO, newPtypeO;
1068  int num0, num1, num1Index;
1069  mask_t num1Mask;
1070  CArray<PieceMask,2> pin_or_open_backup;
1071  KingMobility king_mobility_backup;
1072  PieceMask promoted_backup;
1073  CArray<PieceMask,2> effected_mask_backup;
1074  CArray<PieceMask,2> effected_changed_mask_backup;
1075  CArray<uint64_t,2> king8infos_backup;
1076  MobilityTable mobility_backup;
1077  prologueCapture(player, from, to, target, promoteMask, oldPiece, oldPtypeO,
1078  capturePtypeO, newPtypeO, num0, num1, num1Index,num1Mask,
1079  pin_or_open_backup, king_mobility_backup,
1080  promoted_backup,
1081  effected_mask_backup, effected_changed_mask_backup,
1082  king8infos_backup,
1083  mobility_backup);
1084 
1085  changeTurn();
1086  const Ptype capturePtype=target.ptype();
1087  if (capturePtype==PAWN)
1088  {
1089  clearPawn(PlayerTraits<P>::opponent,to);
1090  if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
1091  {
1092  clearPawn(P,from);
1093  func(to);
1094  setPawn(P,from);
1095  }
1096  else
1097  {
1098  func(to);
1099  }
1100  setPawn(PlayerTraits<P>::opponent,to);
1101  }
1102  else if (promoteMask!=0 && num0<PtypeTraits<PAWN>::indexLimit)
1103  {
1104  clearPawn(P,from);
1105  func(to);
1106  setPawn(P,from);
1107  }
1108  else
1109  {
1110  func(to);
1111  }
1112  changeTurn();
1113 
1114  epilogueCapture(player, from, to, target, oldPiece, oldPtypeO, capturePtypeO, newPtypeO,
1115  num0, num1, num1Index,num1Mask,
1116  pin_or_open_backup, king_mobility_backup,
1117  promoted_backup,effected_mask_backup, effected_changed_mask_backup,
1118  king8infos_backup,
1119  mobility_backup);
1120 }
1121 
1122 template <class Action>
1123 void osl::NumEffectState::
1124 forEachEffectOfPiece(Piece piece,Action & action) const
1125 {
1126  Square pieceSquare = piece.square();
1127  switch ((int)piece.ptypeO()) {
1128  case NEW_PTYPEO(WHITE,PAWN): forEachEffectOfPiece<WHITE,PAWN,Action>(pieceSquare,action); break;
1129  case NEW_PTYPEO(WHITE,LANCE): forEachEffectOfPiece<WHITE,LANCE,Action>(pieceSquare,action); break;
1130  case NEW_PTYPEO(WHITE,KNIGHT): forEachEffectOfPiece<WHITE,KNIGHT,Action>(pieceSquare,action); break;
1131  case NEW_PTYPEO(WHITE,SILVER): forEachEffectOfPiece<WHITE,SILVER,Action>(pieceSquare,action); break;
1132  case NEW_PTYPEO(WHITE,PPAWN): forEachEffectOfPiece<WHITE,PPAWN,Action>(pieceSquare,action); break;
1133  case NEW_PTYPEO(WHITE,PLANCE): forEachEffectOfPiece<WHITE,PLANCE,Action>(pieceSquare,action); break;
1134  case NEW_PTYPEO(WHITE,PKNIGHT): forEachEffectOfPiece<WHITE,PKNIGHT,Action>(pieceSquare,action); break;
1135  case NEW_PTYPEO(WHITE,PSILVER): forEachEffectOfPiece<WHITE,PSILVER,Action>(pieceSquare,action); break;
1136  case NEW_PTYPEO(WHITE,GOLD): forEachEffectOfPiece<WHITE,GOLD,Action>(pieceSquare,action); break;
1137  case NEW_PTYPEO(WHITE,BISHOP): forEachEffectOfPiece<WHITE,BISHOP,Action>(pieceSquare,action); break;
1138  case NEW_PTYPEO(WHITE,PBISHOP): forEachEffectOfPiece<WHITE,PBISHOP,Action>(pieceSquare,action); break;
1139  case NEW_PTYPEO(WHITE,ROOK): forEachEffectOfPiece<WHITE,ROOK,Action>(pieceSquare,action); break;
1140  case NEW_PTYPEO(WHITE,PROOK): forEachEffectOfPiece<WHITE,PROOK,Action>(pieceSquare,action); break;
1141  case NEW_PTYPEO(WHITE,KING): forEachEffectOfPiece<WHITE,KING,Action>(pieceSquare,action); break;
1142  case NEW_PTYPEO(BLACK,PAWN): forEachEffectOfPiece<BLACK,PAWN,Action>(pieceSquare,action); break;
1143  case NEW_PTYPEO(BLACK,LANCE): forEachEffectOfPiece<BLACK,LANCE,Action>(pieceSquare,action); break;
1144  case NEW_PTYPEO(BLACK,KNIGHT): forEachEffectOfPiece<BLACK,KNIGHT,Action>(pieceSquare,action); break;
1145  case NEW_PTYPEO(BLACK,SILVER): forEachEffectOfPiece<BLACK,SILVER,Action>(pieceSquare,action); break;
1146  case NEW_PTYPEO(BLACK,PPAWN): forEachEffectOfPiece<BLACK,PPAWN,Action>(pieceSquare,action); break;
1147  case NEW_PTYPEO(BLACK,PLANCE): forEachEffectOfPiece<BLACK,PLANCE,Action>(pieceSquare,action); break;
1148  case NEW_PTYPEO(BLACK,PKNIGHT): forEachEffectOfPiece<BLACK,PKNIGHT,Action>(pieceSquare,action); break;
1149  case NEW_PTYPEO(BLACK,PSILVER): forEachEffectOfPiece<BLACK,PSILVER,Action>(pieceSquare,action); break;
1150  case NEW_PTYPEO(BLACK,GOLD): forEachEffectOfPiece<BLACK,GOLD,Action>(pieceSquare,action); break;
1151  case NEW_PTYPEO(BLACK,BISHOP): forEachEffectOfPiece<BLACK,BISHOP,Action>(pieceSquare,action); break;
1152  case NEW_PTYPEO(BLACK,PBISHOP): forEachEffectOfPiece<BLACK,PBISHOP,Action>(pieceSquare,action); break;
1153  case NEW_PTYPEO(BLACK,ROOK): forEachEffectOfPiece<BLACK,ROOK,Action>(pieceSquare,action); break;
1154  case NEW_PTYPEO(BLACK,PROOK): forEachEffectOfPiece<BLACK,PROOK,Action>(pieceSquare,action); break;
1155  case NEW_PTYPEO(BLACK,KING): forEachEffectOfPiece<BLACK,KING,Action>(pieceSquare,action); break;
1156  default: assert(0);
1157  }
1158 }
1159 
1160 template <osl::Player P, osl::Ptype Type, class Action>
1161 void osl::NumEffectState::
1162 forEachEffectOfPiece(Square pieceSquare,Action & action) const
1163 {
1164  forEachEffectOfPieceDir<P,Type,Action,UL>(pieceSquare,action);
1165  forEachEffectOfPieceDir<P,Type,Action,U>(pieceSquare,action);
1166  forEachEffectOfPieceDir<P,Type,Action,UR>(pieceSquare,action);
1167  forEachEffectOfPieceDir<P,Type,Action,L>(pieceSquare,action);
1168  forEachEffectOfPieceDir<P,Type,Action,R>(pieceSquare,action);
1169  forEachEffectOfPieceDir<P,Type,Action,DL>(pieceSquare,action);
1170  forEachEffectOfPieceDir<P,Type,Action,D>(pieceSquare,action);
1171  forEachEffectOfPieceDir<P,Type,Action,DR>(pieceSquare,action);
1172  forEachEffectOfPieceDir<P,Type,Action,UUL>(pieceSquare,action);
1173  forEachEffectOfPieceDir<P,Type,Action,UUR>(pieceSquare,action);
1174  forEachEffectOfPieceLongDir<P,Type,Action,LONG_UL>(pieceSquare,action);
1175  forEachEffectOfPieceLongDir<P,Type,Action,LONG_U>(pieceSquare,action);
1176  forEachEffectOfPieceLongDir<P,Type,Action,LONG_UR>(pieceSquare,action);
1177  forEachEffectOfPieceLongDir<P,Type,Action,LONG_L>(pieceSquare,action);
1178  forEachEffectOfPieceLongDir<P,Type,Action,LONG_R>(pieceSquare,action);
1179  forEachEffectOfPieceLongDir<P,Type,Action,LONG_DL>(pieceSquare,action);
1180  forEachEffectOfPieceLongDir<P,Type,Action,LONG_D>(pieceSquare,action);
1181  forEachEffectOfPieceLongDir<P,Type,Action,LONG_DR>(pieceSquare,action);
1182 }
1183 
1184 #endif /* OSL_NUM_EFFECT_STATE_H */
1185 // ;;; Local Variables:
1186 // ;;; mode:c++
1187 // ;;; c-basic-offset:2
1188 // ;;; End: