My Project
effect5x3.cc
Go to the documentation of this file.
1/* effect5x3.cc
2 */
5
8{
9 area_progresses[BLACK]=makeProgressArea(WHITE, state, state.kingSquare(BLACK));
10 area_progresses[WHITE]=makeProgressArea(BLACK, state, state.kingSquare(WHITE));
11 stand_progresses[WHITE]=makeProgressStand(BLACK, state);
12 stand_progresses[BLACK]=makeProgressStand(WHITE, state);
13 progresses[BLACK]=area_progresses[BLACK]+stand_progresses[BLACK];
14 progresses[WHITE]=area_progresses[WHITE]+stand_progresses[WHITE];
15}
16
19 Square king)
20{
21 return makeProgressArea(alt(defense), state, king)
22 + makeProgressStand(alt(defense), state);
23}
24
27 Square king)
28{
29 const Square center = Centering5x3::adjustCenter(king);
30
31 const int min_x = center.x() - 2;
32 const int min_y = center.y() - 1;
33
34 // 利き
35 int sum_effect = 0;
36
37 for (int dx=0; dx<5; ++dx)
38 {
39 for (int dy=0; dy<3; ++dy)
40 {
41 const Square target(min_x+dx,min_y+dy);
42 sum_effect += state.countEffect(attack, target) *
43 Effect5x3_Table.getAttackEffect(attack,king,dx,dy);
44 }
45 }
46 return sum_effect / 2;
47}
48
51{
52 // 持駒
53 int sum_pieces = 0;
54 sum_pieces += state.countPiecesOnStand<PAWN>(attack)*Effect5x3Table::StandPAWN;
55 sum_pieces += state.countPiecesOnStand<LANCE>(attack)*Effect5x3Table::StandLANCE;
56 sum_pieces += state.countPiecesOnStand<KNIGHT>(attack)*Effect5x3Table::StandKNIGHT;
57 sum_pieces += state.countPiecesOnStand<SILVER>(attack)*Effect5x3Table::StandSILVER;
58 sum_pieces += state.countPiecesOnStand<GOLD>(attack)*Effect5x3Table::StandGOLD;
59 sum_pieces += state.countPiecesOnStand<BISHOP>(attack)*Effect5x3Table::StandBISHOP;
60 sum_pieces += state.countPiecesOnStand<ROOK>(attack)*Effect5x3Table::StandROOK;
61 return sum_pieces;
62}
63
65Effect5x3::updateStand(int& old_stand, Move last_move)
66{
67 if (last_move.isDrop()) {
68 const Ptype ptype = last_move.ptype();
69 old_stand -= Effect5x3_Table.piecesOnStand(ptype);
70 return;
71 }
72 const Ptype ptype = last_move.capturePtype();
73 if (ptype == PTYPE_EMPTY) {
74 return;
75 }
76 old_stand += Effect5x3_Table.piecesOnStand(unpromote(ptype));
77}
78
80Effect5x3::update(const NumEffectState& new_state, Move last_move)
81{
82 const Player pl = last_move.player();
83 updateStand(stand_progresses[alt(pl)], last_move);
84
85 const Square kb = new_state.kingSquare<BLACK>(), kw = new_state.kingSquare<WHITE>();
86 BoardMask mb = new_state.changedEffects(BLACK), mw = new_state.changedEffects(WHITE);
87 bool king_move = last_move.ptype() == KING;
88 if ((king_move && new_state.turn() == BLACK) || mb.anyInRange(Board_Mask_Table5x3_Center.mask(kw)))
89 area_progresses[WHITE]=makeProgressArea(BLACK,new_state, kw);
90 if ((king_move && new_state.turn() == WHITE) || mw.anyInRange(Board_Mask_Table5x3_Center.mask(kb)))
91 area_progresses[BLACK]=makeProgressArea(WHITE,new_state, kb);
92
93 progresses[BLACK]=area_progresses[BLACK]+stand_progresses[BLACK];
94 progresses[WHITE]=area_progresses[WHITE]+stand_progresses[WHITE];
95}
96
98Effect5x3::expect(const NumEffectState&, Move move) const
99{
100 Effect5x3 new_progress = *this;
101 if (move.capturePtype() != PTYPE_EMPTY) {
102 const Player alt_pl = alt(move.player());
103 int old = stand_progresses[alt_pl];
104 updateStand(new_progress.stand_progresses[alt_pl], move);
105 new_progress.progresses[alt_pl] += new_progress.stand_progresses[alt_pl] - old;
106 }
107 return new_progress;
108}
109
110/* ------------------------------------------------------------------------- */
111
114{
115 progress_bonuses[BLACK]=makeProgressAreaBonus<WHITE>(state, state.kingSquare<BLACK>());
116 progress_bonuses[WHITE]=makeProgressAreaBonus<BLACK>(state, state.kingSquare<WHITE>());
117 effect_mask[BLACK] = makeEffectMask<BLACK>(state);
118 effect_mask[WHITE] = makeEffectMask<WHITE>(state);
120}
121
122template <osl::Player Defense>
125{
126 const Square king =
127 state.kingSquare<Defense>();
128 const Square center =
130
131 const int min_x = center.x() - 2;
132 const int min_y = center.y() - 1;
133
134 PieceMask mask;
135 for (int dx = 0; dx < 5; ++dx)
136 {
137 for (int dy = 0; dy < 3; ++dy)
138 {
139 const Square target(min_x+dx, min_y+dy);
140 mask = mask | state.effectSetAt(target);
141 }
142 }
143 return mask;
144}
145
146inline
149{
150 const int a = state.countEffect(attack, target);
151 if (a <= 1)
152 return a;
153 if (state.countEffect(alt(attack), target) > 0
154 || state.pieceAt(target).isOnBoardByOwner(attack))
155 return 1;
156 return 2;
157}
158
159namespace osl
160{
161 namespace
162 {
163 template <Player P>
164 int countPawnLanceKnight(const NumEffectState& state, Square target)
165 {
166 // effect is max 2, pawn and lance cannot have the effect
167 // to a position at the same time so this is OK
169 const Piece pd = state.pieceAt(d);
170
171 // pawn and lance
172 int count = 0;
173 if (pd.ptypeO() == newPtypeO(P,PAWN))
174 ++count;
175 else if (pd.ptypeO() == newPtypeO(P,LANCE))
176 ++count;
177 else if (pd.isEmpty())
178 {
179 if (state.hasLongEffectAt<LANCE>(P, target))
180 ++count;
181 }
182 else if (pd.isEdge())
183 return 0;
184
185 // knight
187 if (pdl.ptypeO() == newPtypeO(P,KNIGHT))
188 return count+1;
190 if (pdr.ptypeO() == newPtypeO(P,KNIGHT))
191 return count+1;
192 return count;
193 }
194 }
195}
196
197template <osl::Player Attack, bool AlwaysPromotable, bool AlwaysNotPromotable>
200 Square center)
201{
202 const int min_x = center.x() - 2;
203 const int min_y = center.y() - 1;
204
205 // 利き
206 int sum_effect = 0;
207
208 for (int dy = 0; dy < 3; ++dy)
209 {
210 const Square target(king.x(), min_y + dy);
211 int effect = attackEffect3(state, Attack, target) * 2;
212 if (effect > 0)
213 {
214 if (! AlwaysPromotable
215 && (AlwaysNotPromotable || !target.canPromote<Attack>()) )
216 {
217 effect -= countPawnLanceKnight<Attack>(state, target);
218 assert(effect >= 0);
219 }
220 sum_effect += effect *
221 Effect5x3_Table.getAttackEffect(Attack, king, target.x() - min_x, dy) / 2;
222
223 }
224 }
225 for (int x = king.x() - 1; x >= min_x; --x)
226 {
227 int y_count = 0;
228 int sum = 0;
229 for (int dy = 0; dy < 3; ++dy)
230 {
231 const Square target(x, min_y + dy);
232 int effect = attackEffect3(state, Attack, target) * 2;
233 if (effect > 0)
234 {
235 if (! AlwaysPromotable
236 && (AlwaysNotPromotable || !target.canPromote<Attack>()) )
237 {
238 if (king.x() - x > 1)
239 effect = 0;
240 else
241 effect -= countPawnLanceKnight<Attack>(state, target);
242 assert(effect >= 0);
243 }
244 sum += effect *
245 Effect5x3_Table.getAttackEffect(Attack, king, x - min_x, dy) / 2;
246 y_count++;
247 }
248 }
249 sum_effect += sum;
250 if (y_count == 3)
251 {
252 sum_effect += sum;
253 break;
254 }
255 }
256 for (int x = king.x() + 1; x < min_x + 5; ++x)
257 {
258 int y_count = 0;
259 int sum = 0;
260 for (int dy = 0; dy < 3; ++dy)
261 {
262 const Square target(x, min_y + dy);
263 int effect = attackEffect3(state, Attack, target) * 2;
264 if (effect > 0)
265 {
266 if (! AlwaysPromotable
267 && (AlwaysNotPromotable || !target.canPromote<Attack>()) )
268 {
269 if (x - king.x() > 1)
270 effect = 0;
271 else
272 effect -= countPawnLanceKnight<Attack>(state, target);
273 assert(effect >= 0);
274 }
275 sum += effect *
276 Effect5x3_Table.getAttackEffect(Attack, king, x - min_x, dy) / 2;
277 y_count++;
278 }
279 }
280 sum_effect += sum;
281 if (y_count == 3)
282 {
283 sum_effect += sum;
284 break;
285 }
286 }
287 return sum_effect / 2;
288}
289
290template <osl::Player Attack>
293 Square king)
294{
295 const Square center = Centering5x3::adjustCenter(king);
296
297 const bool always_promotable = center.squareForBlack<Attack>().y() <= 2;
298 if (always_promotable)
299 return makeProgressAreaBonus<Attack,true,false>(state, king, center);
300 const bool always_notpromotable = center.squareForBlack<Attack>().y() >= 5;
301 if (always_notpromotable)
302 return makeProgressAreaBonus<Attack,false,true>(state, king, center);
303 return makeProgressAreaBonus<Attack,false,false>(state, king, center);
304}
305
307Effect5x3WithBonus::update(const NumEffectState& new_state, Move last_move)
308{
309 Effect5x3::update(new_state, last_move);
310
311 const Square kb = new_state.kingSquare<BLACK>(), kw = new_state.kingSquare<WHITE>();
312 BoardMask mask = new_state.changedEffects();
313 mask.set(last_move.to()); mask.set(last_move.from());
314
315 const bool update_black = mask.anyInRange(Board_Mask_Table5x3_Center.mask(kb));
316 const bool update_white = mask.anyInRange(Board_Mask_Table5x3_Center.mask(kw));
317
318 if (update_black)
319 {
320 progress_bonuses[BLACK]=makeProgressAreaBonus<WHITE>(new_state,kb);
321 effect_mask[BLACK] = makeEffectMask<BLACK>(new_state);
322 }
323 if (update_white)
324 {
325 progress_bonuses[WHITE]=makeProgressAreaBonus<BLACK>(new_state,kw);
326 effect_mask[WHITE] = makeEffectMask<WHITE>(new_state);
327 }
328 updateProgressBonuses(new_state, update_black, update_white);
329}
330
333{
334 Effect5x3WithBonus new_progress = *this;
335 if (move.capturePtype() != PTYPE_EMPTY) {
336 const Player alt_pl = alt(move.player());
337 int old = stand_progresses[playerToIndex(alt_pl)];
338 new_progress.updateStand(alt_pl, move);
339 new_progress.progresses[playerToIndex(alt_pl)] += new_progress.stand_progresses[playerToIndex(alt_pl)] - old;
340 }
341 return new_progress;
342}
343
345Effect5x3WithBonus::updateProgressBonuses(const NumEffectState& state, bool update_black, bool update_white)
346{
347 if (update_black && progress_bonuses[BLACK] != 0)
348 {
349 const int pieces = countEffectPieces(state, WHITE);
350 progress_bonuses[BLACK] =
351 std::min(pieces * pieces * 4,
352 progress_bonuses[BLACK]);
353 }
354 if (update_white && progress_bonuses[WHITE] != 0)
355 {
356 const int pieces = countEffectPieces(state, BLACK);
357 progress_bonuses[WHITE] =
358 std::min(pieces * pieces * 4,
359 progress_bonuses[WHITE]);
360 }
361}
362
365{
366 PieceMask mask = effect5x3Mask(alt(attack));
367 mask = mask & state.piecesOnBoard(attack);
368 return mask.countBit();
369}
370
371/* ------------------------------------------------------------------------- */
372// ;;; Local Variables:
373// ;;; mode:c++
374// ;;; c-basic-offset:2
375// ;;; End:
圧縮していない moveの表現 .
Ptype ptype() const
Player player() const
bool isDrop() const
Ptype capturePtype() const
const Square to() const
const Square from() const
利きを持つ局面
const NumBitmapEffect effectSetAt(Square sq) const
const BoardMask changedEffects(Player pl) const
int countEffect(Player player, Square target) const
利きの数を数える.
bool hasLongEffectAt(Player P, Square to) const
あるマスにPTYPEの長い利きがあるかどうか.
const PieceMask & piecesOnBoard(Player p) const
駒番号のビットセット.
Definition pieceMask.h:21
PtypeO ptypeO() const
Definition basic_type.h:824
bool isEmpty() const
Definition basic_type.h:913
bool isEdge() const
Definition basic_type.h:919
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition basic_type.h:852
Player turn() const
Square kingSquare() const
Definition simpleState.h:94
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
const Piece pieceAt(Square sq) const
int y() const
将棋としてのY座標を返す.
Definition basic_type.h:567
bool canPromote() const
Definition basic_type.h:659
const Square squareForBlack(Player player) const
Definition basic_type.h:598
int x() const
将棋としてのX座標を返す.
Definition basic_type.h:563
const BoardMask & mask(Square p) const
p中心の5x3 の範囲のbitを立てたもの, centering
Definition boardMask.h:133
void set(unsigned int i)
Definition boardMask.h:40
bool anyInRange(const BoardMask &mask) const
Definition boardMask.h:57
unsigned int piecesOnStand(Ptype ptype) const
持駒のPtypeごとの寄与を表すテーブルの参照.
unsigned int getAttackEffect(Player pl, Square pos, int x, int y) const
Effect5x3Table Effect5x3_Table
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
@ ROOK
Definition basic_type.h:100
@ BISHOP
Definition basic_type.h:99
@ PAWN
Definition basic_type.h:95
@ KING
Definition basic_type.h:93
@ KNIGHT
Definition basic_type.h:97
@ PTYPE_EMPTY
Definition basic_type.h:85
@ SILVER
Definition basic_type.h:98
@ GOLD
Definition basic_type.h:94
@ LANCE
Definition basic_type.h:96
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition basic_type.h:157
constexpr int playerToIndex(Player player)
Definition basic_type.h:16
Player
Definition basic_type.h:8
@ WHITE
Definition basic_type.h:10
@ BLACK
Definition basic_type.h:9
constexpr Player alt(Player player)
Definition basic_type.h:13
PtypeO newPtypeO(Player player, Ptype ptype)
Definition basic_type.h:211
static const Square adjustCenter(Square src)
int countEffectPieces(const NumEffectState &state, Player attack) const
Definition effect5x3.cc:364
void updateStand(Player pl, Move m)
Definition effect5x3.h:113
Effect5x3WithBonus(const NumEffectState &state)
Definition effect5x3.cc:113
static int attackEffect3(const NumEffectState &state, Player attack, Square target)
Definition effect5x3.cc:148
Effect5x3WithBonus expect(const NumEffectState &state, Move move) const
Definition effect5x3.cc:332
static int makeProgressAreaBonus(const NumEffectState &state, Square king)
Definition effect5x3.cc:292
void updateProgressBonuses(const NumEffectState &state, bool black=true, bool white=true)
Definition effect5x3.cc:345
static PieceMask makeEffectMask(const NumEffectState &state)
void update(const NumEffectState &new_state, Move last_move)
Definition effect5x3.cc:307
CArray< PieceMask, 2 > effect_mask
Definition effect5x3.h:116
CArray< int, 2 > progress_bonuses
Definition effect5x3.h:115
玉の周囲5x3の領域の利きの数と持駒から計算した進行度.
Definition effect5x3.h:27
static int makeProgressStand(Player attack, const NumEffectState &state)
Definition effect5x3.cc:50
CArray< int, 2 > progresses
Definition effect5x3.h:71
CArray< int, 2 > stand_progresses
Definition effect5x3.h:71
static int makeProgressArea(Player attack, const NumEffectState &state, Square king)
Definition effect5x3.cc:26
void update(const NumEffectState &new_state, Move last_move)
Definition effect5x3.cc:80
static void updateStand(int &old_stand, Move last_move)
Definition effect5x3.cc:65
Effect5x3(const NumEffectState &state)
Definition effect5x3.cc:7
Effect5x3 expect(const NumEffectState &state, Move move) const
Definition effect5x3.cc:98
static int makeProgressAll(Player defense, const NumEffectState &state, Square king)
Definition effect5x3.cc:18