All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
see.cc
Go to the documentation of this file.
1 /* see.cc
2  */
3 #include "osl/eval/see.h"
4 #include "osl/eval/pieceEval.h"
6 
8 {
9  PtypeOSquareVector *direct;
10  PtypeOSquareVector *more;
12  const NumEffectState *state;
13 
14  template<Player P,Ptype Type>
15  void doActionPtype(Piece p) { store(p); }
16  template<Player P>
17  void doAction(Piece p, Square) { store(p);}
18  void store(Piece p);
19 };
20 
23 {
24  direct->push_back(std::make_pair(p.ptypeO(), p.square()));
25  findAdditionalPieces(*state, p.owner(), target, p.square(), *more);
26 }
27 
28 template <osl::Player P>
29 void osl::eval::
30 See::findEffectPieces(const NumEffectState& state, Square effect_to,
31  PtypeOSquareVector& my_pieces,
32  PtypeOSquareVector& op_pieces)
33 {
35  store_t op_pieces_store(&op_pieces, effect_to);
36  state.forEachEffect<PlayerTraits<P>::opponent,store_t>(effect_to, op_pieces_store);
37  if (op_pieces.empty())
38  return;
39  op_pieces.sort();
40  if ((int)op_pieces.size() <= state.countEffect(P, effect_to))
41  {
42  store_t my_pieces_store(&my_pieces, effect_to);
43  state.forEachEffect<P,store_t>(effect_to, my_pieces_store); // ignore my_pin
44  my_pieces.sort();
45  return;
46  }
47  PtypeOSquareVector my_pieces_more;
48  FindEffectMore action = { &my_pieces, &my_pieces_more, effect_to, &state };
49  state.forEachEffect<P,FindEffectMore>(effect_to, action); // ignore my_pin
50  my_pieces.sort();
51  // sort my_pieces_more ?
52  my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
53 
54  if (op_pieces.size() <= my_pieces.size())
55  return;
56  my_pieces_more.clear();
57  // gather shadow efect
58  for (size_t i=0; i<op_pieces.size(); ++i) {
59  findAdditionalPieces(state, P, effect_to, op_pieces[i].second, my_pieces_more);
60  }
61  my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
62 }
63 
64 template <osl::Player P>
65 void osl::eval::
66 See::findEffectPiecesAfterMove(const NumEffectState& state, Move move,
67  PtypeOSquareVector& my_pieces,
68  PtypeOSquareVector& op_pieces)
69 {
70  const Square from=move.from();
71  const Square to=move.to();
72 
74  store_t op_pieces_store(&op_pieces, to);
75  state.forEachEffect<PlayerTraits<P>::opponent,store_t>(to, op_pieces_store);
76  if (op_pieces.empty())
77  return;
78  op_pieces.sort();
79 
80  const Piece moved = state.pieceOnBoard(from);
81  PieceMask ignore; // here do not use my_pin to get optimistic result
82  ignore.set(moved.number());
83  if ((int)op_pieces.size() < state.countEffect(P, to))
84  {
85  store_t my_pieces_store(&my_pieces, to);
86  state.forEachEffect<P,store_t>(to, my_pieces_store, ignore);
87  my_pieces.sort();
88  return;
89  }
90 
91  PtypeOSquareVector my_pieces_more;
92  findAdditionalPieces(state, move.player(), to, moved.square(), my_pieces_more);
93 
94  FindEffectMore action = { &my_pieces, &my_pieces_more, to, &state };
95  state.forEachEffect<P,FindEffectMore>(to, action, ignore);
96  my_pieces.sort();
97  // sort my_pieces_more ?
98  my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
99 
100  if (op_pieces.size() < my_pieces.size())
101  return;
102  my_pieces_more.clear();
103  // gather shadow efect
104  for (size_t i=0; i<op_pieces.size(); ++i) {
105  findAdditionalPieces(state, P, to, op_pieces[i].second, my_pieces_more);
106  }
107  my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
108 }
109 
110 template <osl::Player P>
111 int osl::eval::
112 See::computeValue(const NumEffectState& state, Move move,
113  PtypeOSquareVector& my_pieces,
114  PtypeOSquareVector& op_pieces,
115  const PieceMask& my_pin, const PieceMask& op_pin,
116  const eval::PtypeEvalTable& table)
117 {
118  Square target=move.to(), move_from=move.from();
119  PtypeO ptypeO=move.ptypeO();
120 
121  int val = 0;
122  CArray<int,Piece::SIZE> vals;
123  const Player Opponent = PlayerTraits<P>::opponent;
124  size_t i;
125  int c=0;
126  bool op_deleted=false, my_deleted=false;
127  for (i=0;i<op_pieces.size();i++,c++)
128  {
129  if(c>10) break; // avoid infinite loop
130  {
131  Square from=op_pieces[i].second;
132  Piece p=state.pieceAt(from);
133  int num=p.number();
134  if(num==KingTraits<Opponent>::index && my_deleted) break;
135  assert(p.owner()==Opponent);
136  if(op_pin.test(num) && !state.pinnedCanMoveTo<Opponent>(p,target) &&
137  ptypeO!=newPtypeO(P,KING)){
138  Piece attacker=state.pinAttacker<Opponent>(p);
139  assert(attacker.owner()==P);
140  Square attacker_sq=attacker.square();
141  if(attacker_sq != move_from){
142  size_t j=0;
143  for(;j<my_pieces.size();j++) if(my_pieces[j].second==attacker_sq) break;
144  if(i<=j){
145  if(j==my_pieces.size() || op_pieces.size()<=j+1 ){
146  for(size_t k=i;k<op_pieces.size()-1;k++)
147  op_pieces[k]=op_pieces[k+1];
148  op_pieces.pop_back();
149  op_deleted=true;
150  }
151  else{
152  std::pair<PtypeO,Square> v=op_pieces[i];
153  for(size_t k=i;k<=j;k++)
154  op_pieces[k]=op_pieces[k+1];
155  op_pieces[j+1]=v;
156  }
157  i--;
158  continue;
159  }
160  }
161  // pin move?
162  }
163  }
164  vals[i*2]=val;
165  // opponent moves
166  val+=table.captureValue(ptypeO);
167  {
168  ptypeO = op_pieces[i].first;
169  const bool promotable = canPromote(ptypeO)
170  && (target.canPromote<Opponent>()
171  || op_pieces[i].second.canPromote<Opponent>());
172  if (promotable)
173  {
174  ptypeO=promote(ptypeO);
175  val+=table.promoteValue(ptypeO);
176  }
177  }
178  vals[i*2+1]=val;
179  // my moves
180  retry:
181  if (i>=my_pieces.size()){
182  break;
183  }
184  {
185  Square from=my_pieces[i].second;
186  Piece p=state.pieceAt(from);
187  int num=p.number();
188  assert(p.owner()==P);
189  if(num==KingTraits<P>::index && op_deleted) break;
190  if(my_pin.test(num) && !state.pinnedCanMoveTo<P>(p,target) &&
191  ptypeO!=newPtypeO(Opponent,KING)){
192  Piece attacker=state.pinAttacker<P>(p);
193  assert(attacker.owner()==Opponent);
194  Square attacker_sq=attacker.square();
195  size_t j=0;
196  for(;j<op_pieces.size();j++) if(op_pieces[j].second==attacker_sq) break;
197  if(i<j){
198  if(j==op_pieces.size() || my_pieces.size()<=j ){
199  for(size_t k=i;k<my_pieces.size()-1;k++)
200  my_pieces[k]=my_pieces[k+1];
201  my_pieces.pop_back();
202  my_deleted=true;
203  }
204  else{
205  std::pair<PtypeO,Square> v=my_pieces[i];
206  for(size_t k=i;k<j;k++)
207  my_pieces[k]=my_pieces[k+1];
208  my_pieces[j]=v;
209  }
210  goto retry;
211  }
212  // pin move?
213  }
214  }
215  val+=table.captureValue(ptypeO);
216  {
217  ptypeO=my_pieces[i].first;
218  const bool promotable = canPromote(ptypeO)
219  && (target.canPromote<P>()
220  || my_pieces[i].second.canPromote<P>());
221  if (promotable)
222  {
223  ptypeO=promote(ptypeO);
224  val+=table.promoteValue(ptypeO);
225  }
226  }
227  }
228  for (int j=i-1;j>=0;j--)
229  {
230  val=EvalTraits<P>::max(val,vals[j*2+1]);
231  val=EvalTraits<Opponent>::max(val,vals[j*2]);
232  }
233  return val;
234 }
235 
236 template <osl::Player P>
237 int osl::eval::See::seeInternal(const NumEffectState& state, Move move,
238  const PieceMask& my_pin, const PieceMask& op_pin,
239  const eval::PtypeEvalTable& table)
240 {
241  assert(state.isAlmostValidMove(move));
242 
243  const Square from=move.from();
244  const Square to=move.to();
245  PtypeOSquareVector my_pieces, op_pieces;
246  int val=0;
247  if (from.isPieceStand())
248  {
249  findEffectPieces<P>(state, to, my_pieces, op_pieces);
250  }
251  else
252  {
253  val = PieceEval::diffWithMove(state,move);
254  findEffectPiecesAfterMove<P>(state, move, my_pieces, op_pieces);
255  }
256  if (op_pieces.empty())
257  return val;
258  return val + computeValue<P>(state, move, my_pieces, op_pieces, my_pin, op_pin, table);
259 }
260 
261 int osl::eval::See::see(const NumEffectState& state, Move move,
262  const PieceMask& my_pin, const PieceMask& op_pin,
263  const eval::PtypeEvalTable *table)
264 {
265  if (! table)
266  table = &Ptype_Eval_Table;
267  if (move.player() == BLACK)
268  return seeInternal<BLACK>(state, move, my_pin, op_pin, *table);
269  else
270  return -seeInternal<WHITE>(state, move, my_pin, op_pin, *table);
271 }
272 
273 void osl::eval::
274 See::findAdditionalPieces(const NumEffectState& state, Player attack,
275  Square target,
276  Square from,
277  PtypeOSquareVector& out)
278 {
279  const Offset32 diff32 = Offset32(from, target);
280  const Offset step = Board_Table.getShortOffsetNotKnight(diff32);
281  if (step.zero())
282  return;
283  // 利きが8方向の場合
284  Piece candidate=state.nextPiece(from, step);
285  if (! candidate.isPiece())
286  return;
287  const Offset32 diff_reverse = Offset32(target,candidate.square());
288  for (; candidate.isPiece();
289  candidate=state.nextPiece(candidate.square(), step))
290  {
291  if (candidate.owner() != attack)
292  return;
293  const EffectContent effect
294  = Ptype_Table.getEffect(candidate.ptypeO(), diff_reverse);
295  if (! effect.hasEffect())
296  return;
297  out.push_back(std::make_pair(candidate.ptypeO(), candidate.square()));
298  }
299 }
300 
301 /* ------------------------------------------------------------------------- */
302 // ;;; Local Variables:
303 // ;;; mode:c++
304 // ;;; c-basic-offset:2
305 // ;;; End: