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 
65 Effect5x3::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 
80 Effect5x3::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 
98 Effect5x3::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);
119  updateProgressBonuses(state);
120 }
121 
122 template <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 
146 inline
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 
159 namespace 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
168  const Square d = target+DirectionPlayerTraits<D,P>::offset();
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
186  const Piece pdl = state.pieceAt(d+DirectionPlayerTraits<DL,P>::offset());
187  if (pdl.ptypeO() == newPtypeO(P,KNIGHT))
188  return count+1;
189  const Piece pdr = state.pieceAt(d+DirectionPlayerTraits<DR,P>::offset());
190  if (pdr.ptypeO() == newPtypeO(P,KNIGHT))
191  return count+1;
192  return count;
193  }
194  }
195 }
196 
197 template <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 
290 template <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 
307 Effect5x3WithBonus::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 
345 Effect5x3WithBonus::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:
osl::progress::Effect5x3WithBonus::attackEffect3
static int attackEffect3(const NumEffectState &state, Player attack, Square target)
Definition: effect5x3.cc:148
osl::SimpleState::pieceAt
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
osl::Square
Definition: basic_type.h:532
osl::container::PieceMask64::countBit
int countBit() const
Definition: pieceMask64.h:78
osl::progress::Effect5x3_Table
Effect5x3Table Effect5x3_Table
Definition: effect5x3Table.cc:13
osl::NumEffectState::piecesOnBoard
const PieceMask & piecesOnBoard(Player p) const
Definition: numEffectState.h:63
osl::eval::min
int min(Player p, int v1, int v2)
Definition: evalTraits.h:92
osl::WHITE
@ WHITE
Definition: basic_type.h:10
osl::alt
constexpr Player alt(Player player)
Definition: basic_type.h:13
osl::progress::Effect5x3WithBonus
Definition: effect5x3.h:89
osl::container::BoardMaskTable5x3Center::mask
const BoardMask & mask(Square p) const
p中心の5x3 の範囲のbitを立てたもの, centering
Definition: boardMask.h:133
osl::Centering5x3::adjustCenter
static const Square adjustCenter(Square src)
Definition: centering5x3.h:23
osl::NumEffectState::effectSetAt
const NumBitmapEffect effectSetAt(Square sq) const
Definition: numEffectState.h:258
osl::Move
圧縮していない moveの表現 .
Definition: basic_type.h:1052
osl::progress::Effect5x3::Effect5x3
Effect5x3(const NumEffectState &state)
Definition: effect5x3.cc:7
osl::Piece::ptypeO
PtypeO ptypeO() const
Definition: basic_type.h:824
osl::newPtypeO
PtypeO newPtypeO(Player player, Ptype ptype)
Definition: basic_type.h:211
osl::progress::Effect5x3WithBonus::Effect5x3WithBonus
Effect5x3WithBonus(const NumEffectState &state)
Definition: effect5x3.cc:113
osl::progress::Effect5x3WithBonus::makeProgressAreaBonus
static int makeProgressAreaBonus(const NumEffectState &state, Square king)
Definition: effect5x3.cc:292
osl::Ptype
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:84
osl::LANCE
@ LANCE
Definition: basic_type.h:96
osl::progress::Effect5x3WithBonus::updateProgressBonuses
void updateProgressBonuses(const NumEffectState &state, bool black=true, bool white=true)
Definition: effect5x3.cc:345
osl::DirectionPlayerTraits
Definition: directionTraits.h:242
osl::Piece
駒.
Definition: basic_type.h:788
osl::progress::Effect5x3WithBonus::makeEffectMask
static PieceMask makeEffectMask(const NumEffectState &state)
osl::GOLD
@ GOLD
Definition: basic_type.h:94
osl::KING
@ KING
Definition: basic_type.h:93
osl::progress::Effect5x3WithBonus::effect_mask
CArray< PieceMask, 2 > effect_mask
Definition: effect5x3.h:116
osl::progress::Effect5x3
玉の周囲5x3の領域の利きの数と持駒から計算した進行度.
Definition: effect5x3.h:27
osl::progress::Effect5x3WithBonus::countEffectPieces
int countEffectPieces(const NumEffectState &state, Player attack) const
Definition: effect5x3.cc:364
osl::progress::Effect5x3::update
void update(const NumEffectState &new_state, Move last_move)
Definition: effect5x3.cc:80
osl::BISHOP
@ BISHOP
Definition: basic_type.h:99
osl::Move::capturePtype
Ptype capturePtype() const
Definition: basic_type.h:1180
osl::progress::Effect5x3WithBonus::update
void update(const NumEffectState &new_state, Move last_move)
Definition: effect5x3.cc:307
osl::progress::Effect5x3::updateStand
static void updateStand(int &old_stand, Move last_move)
Definition: effect5x3.cc:65
osl::progress::Effect5x3WithBonus::progress_bonuses
CArray< int, 2 > progress_bonuses
Definition: effect5x3.h:115
osl::Move::isDrop
bool isDrop() const
Definition: basic_type.h:1150
osl::PAWN
@ PAWN
Definition: basic_type.h:95
effect5x3Table.h
osl::NumEffectState::hasLongEffectAt
bool hasLongEffectAt(Player P, Square to) const
あるマスにPTYPEの長い利きがあるかどうか.
Definition: numEffectState.h:346
osl::Piece::isOnBoardByOwner
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition: basic_type.h:852
osl::progress::Effect5x3WithBonus::expect
Effect5x3WithBonus expect(const NumEffectState &state, Move move) const
Definition: effect5x3.cc:332
osl::Move::from
const Square from() const
Definition: basic_type.h:1125
osl::Square::x
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
osl::NumEffectState
利きを持つ局面
Definition: numEffectState.h:34
osl::progress::Effect5x3::makeProgressStand
static int makeProgressStand(Player attack, const NumEffectState &state)
Definition: effect5x3.cc:50
osl::playerToIndex
constexpr int playerToIndex(Player player)
Definition: basic_type.h:16
osl::ROOK
@ ROOK
Definition: basic_type.h:100
osl::Square::canPromote
bool canPromote() const
Definition: basic_type.h:659
osl::SimpleState::kingSquare
Square kingSquare() const
Definition: simpleState.h:94
osl::Square::y
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
osl::container::BoardMask::anyInRange
bool anyInRange(const BoardMask &mask) const
Definition: boardMask.h:57
osl::progress::Effect5x3::expect
Effect5x3 expect(const NumEffectState &state, Move move) const
Definition: effect5x3.cc:98
osl::Piece::isEmpty
bool isEmpty() const
Definition: basic_type.h:913
osl::progress::Effect5x3WithBonus::updateStand
void updateStand(Player pl, Move m)
Definition: effect5x3.h:113
osl::Move::ptype
Ptype ptype() const
Definition: basic_type.h:1155
osl::BLACK
@ BLACK
Definition: basic_type.h:9
osl::NumEffectState::changedEffects
const BoardMask changedEffects(Player pl) const
Definition: numEffectState.h:144
osl::SILVER
@ SILVER
Definition: basic_type.h:98
osl::progress::Effect5x3Table::getAttackEffect
unsigned int getAttackEffect(Player pl, Square pos, int x, int y) const
Definition: effect5x3Table.h:105
osl::PTYPE_EMPTY
@ PTYPE_EMPTY
Definition: basic_type.h:85
osl::SimpleState::turn
Player turn() const
Definition: simpleState.h:220
osl::Player
Player
Definition: basic_type.h:8
osl::container::BoardMask::set
void set(unsigned int i)
Definition: boardMask.h:40
effect5x3.h
osl::progress::Effect5x3Table::piecesOnStand
unsigned int piecesOnStand(Ptype ptype) const
持駒のPtypeごとの寄与を表すテーブルの参照.
Definition: effect5x3Table.h:71
osl::progress::Effect5x3::stand_progresses
CArray< int, 2 > stand_progresses
Definition: effect5x3.h:71
osl::Move::to
const Square to() const
Definition: basic_type.h:1132
osl::container::BoardMask
11 x 12
Definition: boardMask.h:21
osl::PieceMask
駒番号のビットセット.
Definition: pieceMask.h:21
osl::progress::Effect5x3::makeProgressAll
static int makeProgressAll(Player defense, const NumEffectState &state, Square king)
Definition: effect5x3.cc:18
osl::NumEffectState::countEffect
int countEffect(Player player, Square target) const
利きの数を数える.
Definition: numEffectState.h:266
osl::Square::squareForBlack
const Square squareForBlack(Player player) const
Definition: basic_type.h:598
osl::SimpleState::countPiecesOnStand
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
Definition: simpleState.h:182
osl::container::Board_Mask_Table5x3_Center
const BoardMaskTable5x3Center Board_Mask_Table5x3_Center
Definition: tables.cc:121
osl::progress::Effect5x3::progresses
CArray< int, 2 > progresses
Definition: effect5x3.h:71
osl::Move::player
Player player() const
Definition: basic_type.h:1195
osl::unpromote
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition: basic_type.h:157
osl
Definition: additionalEffect.h:6
osl::KNIGHT
@ KNIGHT
Definition: basic_type.h:97
osl::progress::Effect5x3::makeProgressArea
static int makeProgressArea(Player attack, const NumEffectState &state, Square king)
Definition: effect5x3.cc:26
osl::Piece::isEdge
bool isEdge() const
Definition: basic_type.h:919