king8Info.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
king8Info.cc
Go to the documentation of this file.
1 /* king8Info.cc
2 */
3 #include "osl/checkmate/king8Info.h"
4 #include "osl/state/numEffectState.h"
5 #include "osl/effect_util/additionalEffect.h"
6 #include "osl/effect_util/pin.h"
7 #include <bitset>
8 #include <iostream>
9
10 #ifndef MINIMAL
11 std::ostream& osl::checkmate::operator<<(std::ostream& os, King8Info info)
12 {
13 typedef std::bitset<8> bs_t;
14 os << bs_t(info.moveCandidate2()) << " "
15 << bs_t(info.libertyCandidate()) << " "
16 << bs_t(info.liberty()) << " "
17 << bs_t(info.dropCandidate());
18 return os;
19 }
20 #endif
21 namespace osl
22 {
23 namespace
24 {
34 template<Player P> inline
35 bool
36 #ifdef __GNUC__
37 __attribute__ ((pure))
38 #endif
39 hasEnoughEffect(NumEffectState const& state,Square target,Square pos, const PieceMask& pinned,
40 const PieceMask& on_board_defense,
41 Direction dir)
42 {
43 assert(state.kingSquare(P)==target);
44 assert(pos.isOnBoard());
45 PieceMask pieceMask = state.effectSetAt(pos)&on_board_defense;
46 if(pieceMask.none()) return false;
47 PieceMask pieceMask1=pieceMask&~pinned;
48 if(pieceMask1.any()) return true;
49 pieceMask&=pinned;
50 assert(pieceMask.any());
51 do {
52 int num=pieceMask.takeOneBit();
53 Piece p=state.pieceOf(num);
54 assert(p.isOnBoardByOwner(P));
55 Square pos1=p.square();
56 assert(Board_Table.getShortOffset(Offset32(pos,target))
57 == pos-target);
58 Direction dir1=Board_Table.getShort8<P>(target,pos1);
59 if(dir1==dir) return true;
60 } while(pieceMask.any());
61 return false;
62 }
63 }
64 }
65
66 template<osl::Player P,osl::Direction Dir>
67 uint64_t osl::checkmate::
68 King8Info::hasEffectMask(NumEffectState const& state,Square target, PieceMask pinned,
69 PieceMask on_board_defense)
70 {
71 const Player altP=PlayerTraits<P>::opponent;
72 Square pos=target-DirectionPlayerTraits<Dir,P>::offset();
73 Piece p=state.pieceAt(pos);
74 if(p.isEdge())
75 return 0ull;
76 if(!state.hasEffectAt(P,pos)){
77 if(p.canMoveOn<altP>()){ // 自分の駒か空白
78 if(p.isEmpty())
79 return 0x1000000000000ull+(0x100010100ull<<static_cast<int>(Dir));
80 else
81 return 0x1000000000000ull+(0x10100ull<<static_cast<int>(Dir));
82 }
83 else // 相手の駒
84 return 0ull;
85 }
86 const bool has_enough_effect = hasEnoughEffect<altP>(state,target,pos,pinned,on_board_defense,Dir);
87 if(has_enough_effect){
88 if(p.canMoveOn<altP>()){
89 if(p.isEmpty())
90 return 0x10100010000ull<<static_cast<int>(Dir);
91 else
92 return 0x10000ull<<static_cast<int>(Dir);
93 }
94 else
95 return 0x10000000000ull<<static_cast<int>(Dir);
96 }
97 else{
98 if(p.isEmpty())
99 return 0x10101010001ull<<static_cast<int>(Dir);
100 else if(p.isOnBoardByOwner<P>())
101 return 0x10000ull<<static_cast<int>(Dir);
102 else
103 return 0x10001000000ull<<static_cast<int>(Dir);
104 }
105 }
106
107 template<osl::Player P>
108 const osl::checkmate::King8Info
109 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
110 __attribute__ ((noinline))
111 #endif
112 osl::checkmate::King8Info::make(NumEffectState const& state,Square target, PieceMask pinned)
113 {
114 PieceMask on_board_defense=state.piecesOnBoard(alt(P));
115 on_board_defense.reset(KingTraits<PlayerTraits<P>::opponent>::index);
116 uint64_t canMoveMask=
117 hasEffectMask<P,UR>(state,target,pinned,on_board_defense)+
118 hasEffectMask<P,R>(state,target,pinned,on_board_defense)+
119 hasEffectMask<P,DR>(state,target,pinned,on_board_defense)+
120 hasEffectMask<P,U>(state,target,pinned,on_board_defense)+
121 hasEffectMask<P,D>(state,target,pinned,on_board_defense)+
122 hasEffectMask<P,UL>(state,target,pinned,on_board_defense)+
123 hasEffectMask<P,L>(state,target,pinned,on_board_defense)+
124 hasEffectMask<P,DL>(state,target,pinned,on_board_defense);
125 mask_t longMask=state.longEffectAt(target,P);
126 while(longMask.any()){
127 int num=longMask.takeOneBit()+PtypeFuns<LANCE>::indexNum*32;
128 Piece attacker=state.pieceOf(num);
129 Direction d=
130 Board_Table.getShort8<P>(target,attacker.square());
131 if((canMoveMask&(0x100<<d))!=0){
132 canMoveMask-=((0x100<<d)+0x1000000000000ull);
133 }
134 }
135 return King8Info(canMoveMask);
136 }
137
138 template <osl::Player P>
139 const osl::checkmate::King8Info
140 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
141 __attribute__ ((noinline))
142 #endif
143 osl::checkmate::
144 King8Info::make(NumEffectState const& state, Square target)
145 {
146 return make<P>(state,target,state.pin(alt(P)));
147 }
148
149 const osl::checkmate::King8Info osl::checkmate::
150 King8Info::make(Player attack, NumEffectState const& state)
151 {
152 const Square king=state.kingSquare(alt(attack));
153 if (attack == BLACK)
154 return make<BLACK>(state, king);
155 else
156 return make<WHITE>(state, king);
157 }
158
159 const osl::checkmate::King8Info osl::checkmate::
160 King8Info::makeWithPin(Player attack, NumEffectState const& state,
161 const PieceMask& pins)
162 {
163 const Square king=state.kingSquare(alt(attack));
164 if (attack == BLACK)
165 return make<BLACK>(state, king, pins);
166 else
167 return make<WHITE>(state, king, pins);
168 }
169
170 osl::checkmate::EdgeTable::EdgeTable()
171 {
172 edge_mask.fill(~(0xfull << 48));
173 for (int x=1; x<=9; ++x) {
174 for (int y=1; y<=9; ++y) {
175 Square king(x,y);
176 for (int d=DIRECTION_MIN; d<=SHORT8_DIRECTION_MAX; ++d) {
177 Square target = king+Board_Table.getOffset(BLACK, Direction(d));
178 if (target.x() <= 1 || target.x() >= 9 || target.y() <=1 || target.y() >=9)
179 edge_mask[BLACK][king.index()] &= ~(0x100ull<<d);
180 target = king+Board_Table.getOffset(WHITE, Direction(d));
181 if (target.x() <= 1 || target.x() >= 9 || target.y() <=1 || target.y() >=9)
182 edge_mask[WHITE][king.index()] &= ~(0x100ull<<d);
183 }
184 }
185 }
186 }
187
188 /* ------------------------------------------------------------------------- */
189 // ;;; Local Variables:
190 // ;;; mode:c++
191 // ;;; c-basic-offset:2
192 // ;;; End:
193