All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
king8Info.cc
Go to the documentation of this file.
1 /* king8Info.cc
2  */
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 {
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>
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>
140 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
141 __attribute__ ((noinline))
142 #endif
144 King8Info::make(NumEffectState const& state, Square target)
145 {
146  return make<P>(state,target,state.pin(alt(P)));
147 }
148 
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 
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 
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