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