numEffectState.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
6 #include "osl/effect/numSimpleEffect.h"
7 #include "osl/mobility/kingMobility.h"
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 {
37 effect::NumSimpleEffectTable effects;
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);
46 typedef NumEffectState state_t;
47 public:
48 // ----------------------------------------------------------------------
49 // 0. 将棋以外の操作
50 // ----------------------------------------------------------------------
51 explicit NumEffectState(const state::SimpleState& st=SimpleState(HIRATE));
52 ~NumEffectState();
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 }
84 const checkmate::King8Info
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 }
156 Square mobilityOf(Direction d, Piece p) const
157 {
158 return mobilityOf(d, p.number());
159 }
160 Square kingMobilityAbs(Player p, Direction d) const
161 {
162 return Square::makeDirect(king_mobility[p][d]);
163 }
169 Square kingMobilityOfPlayer(Player p, Direction d) const
170 {
171 if (p == BLACK)
172 d = inverse(d);
173 return kingMobilityAbs(p, d);
174 }
179 template<Player P>
180 Direction pinnedDir(Piece p) const
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 }
187 Direction pinnedDir(Piece p) const
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>
270 const mask_t allEffectAt(Player P, Square target) const
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 }
283 const mask_t longEffectAt(Square target) const
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>
340 bool hasEffectByPtypeStrict(Player attack, Square target) const
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 {
355 BOOST_STATIC_ASSERT( (DirectionTraits<Dir>::isLong) );
356 const PieceMask& pieces_onboard=piecesOnBoard(P);
357 mask_t mask1=pieces_onboard.getMask(1);
358 mask1 &= ((PtypeDirectionTraits<LANCE,Dir>::canMove
359 ? mask_t::makeDirect(PtypeFuns<LANCE>::indexMask)
360 : mask_t::makeDirect(0))
361 | (PtypeDirectionTraits<BISHOP,Dir>::canMove
362 ? mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)
363 : mask_t::makeDirect(0))
364 | (PtypeDirectionTraits<ROOK,Dir>::canMove
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();
374 Direction dir=Board_Table.getLongDirection<BLACK>(Offset32(to,from));
375 if (dir==DirectionPlayerTraits<Dir,P>::directionByBlack)
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 }
396 bool hasEffectByNotPinnedAndKing(Player pl,Square target) const{
397 assert(target.isOnBoard());
398 PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
399 m.clearBit<KING>();
400 return m.any();
401 }
405 bool hasEffectByNotPinned(Player pl,Square target) const{
406 assert(target.isOnBoard());
407 PieceMask m=piecesOnBoard(pl)& ~pinOrOpen(pl) & effectSetAt(target);
408 return m.any();
409 }
416 bool hasMultipleEffectAt(Player player,Square target) const
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>
488 const Piece findAttackAtStrict(Player attack, Square target) const
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);
644 void makeMovePass()
645 {
646 changeTurn();
647 effects.clearChangedEffects();
648 effects.clearEffectedChanged();
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 {
795 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
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);
808 const Offset offset=DirectionPlayerTraits<Dir,P>::offset();
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>
918 void makePinOpenDir(Square target,
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: