My Project
see.cc
Go to the documentation of this file.
1/* see.cc
2 */
3#include "osl/eval/see.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
21void osl::eval::See::
22FindEffectMore::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
28template <osl::Player P>
30See::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
64template <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
110template <osl::Player P>
112See::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
236template <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
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
275 Square target,
276 Square from,
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なら長い利きがある
size_t size() const
Definition container.h:243
void push_back(const T &e)
Definition container.h:204
圧縮していない moveの表現 .
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
Player player() const
const Square to() const
const Square from() const
利きを持つ局面
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 を求める.
const Piece pieceOnBoard(Square sq) const
const Piece pieceAt(Square sq) const
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
const PtypeEvalTable Ptype_Eval_Table
Definition tables.cc:103
@ 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