My Project
see.cc
Go to the documentation of this file.
1 /* see.cc
2  */
3 #include "osl/eval/see.h"
4 #include "osl/eval/ptypeEval.h"
6 
8 {
9  PtypeOSquareVector *direct;
10  PtypeOSquareVector *more;
11  Square target;
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 
22 FindEffectMore::store(Piece p)
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>
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<alt(P),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>
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<alt(P),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>
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;
123  const Player Opponent = alt(P);
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>
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 = Ptype_Eval_Table.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 
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:
const Offset getShortOffsetNotKnight(Offset32 offset32) const
Longの利きの可能性のあるoffsetの場合は, 反復に使う offsetを Knight以外のShortの利きのoffsetの場合はそれ自身を返す.
Definition: boardTable.h:119
bool hasEffect() const
短い利きがあるか,間がemptyなら長い利きがある
Definition: effectContent.h:34
size_t size() const
Definition: container.h:243
void push_back(const T &e)
Definition: container.h:204
圧縮していない moveの表現 .
Definition: basic_type.h:1052
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
Definition: basic_type.h:1162
Player player() const
Definition: basic_type.h:1195
const Square to() const
Definition: basic_type.h:1132
const Square from() const
Definition: basic_type.h:1125
利きを持つ局面
bool pinnedCanMoveTo(Piece p, Square to) const
pinされた駒pがtoに動けるか? pinに関係がなければtoへ動けるという前提
void forEachEffect(const PieceMask &pieces, Square sq, Action &action) const
int countEffect(Player player, Square target) const
利きの数を数える.
bool isAlmostValidMove(Move move) const
合法手かどうかを簡単に検査する.局面に依存するチェックのみ. ルール上指せない手である可能性がある場合は,isValidMove を用いる.
Piece pinAttacker(Piece pinned) const
Pのpinされた駒から,そのpinの原因となっている長い利きを持つ駒を得る.
差が uniqになるような座標の差分.
Definition: offset32.h:17
座標の差分
Definition: basic_type.h:430
bool zero() const
Definition: basic_type.h:502
駒番号のビットセット.
Definition: pieceMask.h:21
void set(int num)
Definition: pieceMask.h:48
bool test(int num) const
Definition: pieceMask.h:45
PtypeO ptypeO() const
Definition: basic_type.h:824
const Square square() const
Definition: basic_type.h:832
Player owner() const
Definition: basic_type.h:963
bool isPiece() const
Definition: basic_type.h:953
int number() const
Definition: basic_type.h:828
void sort()
駒の価値の小さい順に並び替える
Definition: container.cc:74
const EffectContent getEffect(PtypeO ptypeo, Square from, Square to) const
fromにいるptypeoがtoに利きを持つか?
Definition: ptypeTable.h:112
Piece nextPiece(Square cur, Offset diff) const
diff方向にあるPiece を求める.
Definition: simpleState.h:208
const Piece pieceOnBoard(Square sq) const
Definition: simpleState.h:170
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
bool isPieceStand() const
Definition: basic_type.h:576
bool canPromote() const
Definition: basic_type.h:659
int captureValue(PtypeO ptypeO) const
ownerのptypeOがcaptureされた時の評価値の増減
Definition: ptypeEval.h:50
int diffWithMove(const NumEffectState &, Move move) const
Definition: ptypeEval.h:54
int promoteValue(PtypeO ptypeO) const
ptypeOにpromoteした時の評価値の増減
Definition: ptypeEval.h:43
int max(Player p, int v1, int v2)
Definition: evalTraits.h:84
const PtypeEvalTable Ptype_Eval_Table
Definition: tables.cc:103
move_action::Store store_t
@ KING
Definition: basic_type.h:93
const PtypeTable Ptype_Table
Definition: tables.cc:97
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
Definition: basic_type.h:147
const BoardTable Board_Table
Definition: tables.cc:95
Offset32Base< 8, 9 > Offset32
Definition: offset32.h:63
Player
Definition: basic_type.h:8
@ BLACK
Definition: basic_type.h:9
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
constexpr Player alt(Player player)
Definition: basic_type.h:13
PtypeO newPtypeO(Player player, Ptype ptype)
Definition: basic_type.h:211
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない.
Definition: basic_type.h:173
PtypeOSquareVector に格納
void doAction(Piece p, Square)
Definition: see.cc:17
PtypeOSquareVector * direct
Definition: see.cc:9
void doActionPtype(Piece p)
Definition: see.cc:15
const NumEffectState * state
Definition: see.cc:12
PtypeOSquareVector * more
Definition: see.cc:10
void store(Piece p)
Definition: see.cc:22
static void findEffectPiecesAfterMove(const NumEffectState &state, Move move, PtypeOSquareVector &my_pieces, PtypeOSquareVector &op_pieces)
Definition: see.cc:66
static int seeInternal(const NumEffectState &state, Move move, const PieceMask &my_pin, const PieceMask &op_pin, const PtypeEvalTable &table)
Definition: see.cc:237
static void findEffectPieces(const NumEffectState &state, Square effect_to, PtypeOSquareVector &my_pieces, PtypeOSquareVector &op_pieces)
Definition: see.cc:30
static int see(const NumEffectState &state, Move move, const PieceMask &my_pin=PieceMask(), const PieceMask &op_pin=PieceMask(), const PtypeEvalTable *table=0)
Definition: see.cc:261
static int computeValue(const NumEffectState &state, Move move, PtypeOSquareVector &my_pieces, PtypeOSquareVector &op_pieces, const PieceMask &my_pin, const PieceMask &op_pin, const PtypeEvalTable &table)
PtypeOSquareVector をもとに取り返し値を計算する
Definition: see.cc:112
static void findAdditionalPieces(const NumEffectState &state, Player attack, Square target, Square direct_attack_from, PtypeOSquareVector &out)
Definition: see.cc:274