My Project
openMidEndingEval.h
Go to the documentation of this file.
1 /* openMidEndingEval.h
2  */
3 
4 #ifndef EVAL_ML_OPENMIDENDINGEVAL_H
5 #define EVAL_ML_OPENMIDENDINGEVAL_H
6 
7 #include "osl/eval/weights.h"
8 #include "osl/eval/ptypeEval.h"
10 #include "osl/eval/evalTraits.h"
11 #include "osl/eval/ptypeEval.h"
12 #include "osl/numEffectState.h"
13 #include "osl/progress.h"
14 #include "osl/bits/align16New.h"
15 #include "osl/oslConfig.h"
16 #include <cstring>
17 
18 #define USE_TEST_PROGRESS
19 // NewProgressが学習可能な場合に定義 (現在はosl側に変更はないので常に定義)
20 #define LEARN_TEST_PROGRESS
21 
22 namespace osl
23 {
24  namespace eval
25  {
26  namespace ml
27  {
28  using namespace osl::progress::ml;
30  {
31  public:
33  };
34 
36  {
38  {
100  STAGE_FEATURE_LIMIT
101  };
103  {
105  BISHOP_EXCHANGE_SILVER_KING, // recalculated_value
107  KING25_EFFECT_ATTACK, // end recalculated_value
110  PROGRESS_INDEPENDENT_FEATURE_LIMIT
111  };
112  int value;
113  int progress;
116 
117  static const char *name(ProgressIndependentFeature);
118  static const char *name(StageFeature);
119  };
120 
122 #if OSL_WORDSIZE == 32
123  : public misc::Align16New
124 #endif
125  {
126  private:
127  enum { INVALID=EvalTraits<BLACK>::MAX_VALUE+1 };
128  enum {
130  ProgressIndependentValueLimit = 4000
131  };
132  enum LoadStatus { Zero=0, Loaded, Random };
133  static volatile LoadStatus initialized_flag;
138  MultiIntPair king25_both_side,king_rook_bishop;
139  MultiIntPair piece_stand_turn, non_pawn_attacked,
140  non_pawn_attacked_ptype, piece_fork_turn;
141  MultiInt ptypey, ptypex, king_table_value;
142  MultiInt piece_stand_value, recalculated_stage_value, pawn_advance;
143  MultiInt rook_mobility, bishop_mobility, lance_mobility;
144  MultiInt knight_advance, pawn_drop, promoted_minor_piece, rook_pawn,
145  rook_effect, bishop_effect, bishop_head, nosupport, ptype_yy, king3pieces;
147  MultiInt piece_stand_combination, piece_stand_y, knight_check,
148  knight_head, pawn_ptypeo, ptype_count_value, lance_effect_piece,
149  ptype_y_pawn_y, bishop_and_king, rook_silver_knight, bishop_silver_knight;
151  CArray<PieceMask, 2> effect25; // index: owner of king
152  CArray<PieceMask, 2> effect25_supported; // index: owner of king
157  black_king_vertical, white_king_vertical;
158  // flat
163  CArray<std::pair<Square,int>, 2> knight_drop, silver_drop, bishop_drop, rook_drop;
165  int progress_independent_value, // should be renamed to piece
166  recalculated_value, piece_pair_value;
168  int black_major_count, black_gold_count;
169  int black_attack_effect, black_attack_piece,
170  white_attack_effect, white_attack_piece,
171  black_attack_supported_piece, white_attack_supported_piece;
172  int black_defense_effect, black_defense_piece,
173  white_defense_effect, white_defense_piece;
174  mutable int cache;
176  unsigned int ptypeo_mask;
177  CArray<bool, 2> can_check; // king is defense
179  static const int ROUND_UP = 2;
180  static int roundUp(int v)
181  {
182  return v & (~(ROUND_UP-1));
183  }
185  {
186  const CArray<Square,2> kings = {{
187  state.kingSquare(BLACK),
188  state.kingSquare(WHITE),
189  }};
190  gs_near_king_count.fill(0);
191  for (int i = PtypeTraits<GOLD>::indexMin;
192  i < PtypeTraits<GOLD>::indexLimit; ++i)
193  {
194  const Piece p = state.pieceOf(i);
195  if (p.isOnBoard())
196  {
197  const Square pos = p.square();
198  const int y_diff = std::abs(pos.y() - kings[p.owner()].y());
199  const int x_diff = std::abs(pos.x() - kings[p.owner()].x());
200  if (y_diff <= 2 && x_diff <= 3)
201  {
202  ++gs_near_king_count[p.owner()][std::max(x_diff, y_diff) - 1];
203  }
204  }
205  }
206  for (int i = PtypeTraits<SILVER>::indexMin;
207  i < PtypeTraits<SILVER>::indexLimit; ++i)
208  {
209  const Piece p = state.pieceOf(i);
210  if (p.isOnBoard())
211  {
212  const Square pos = p.square();
213  const int y_diff = std::abs(pos.y() - kings[p.owner()].y());
214  const int x_diff = std::abs(pos.x() - kings[p.owner()].x());
215  if (y_diff <= 2 && x_diff <= 3)
216  {
217  ++gs_near_king_count[p.owner()][std::max(x_diff, y_diff) - 1];
218  }
219  }
220  }
221  }
222  public:
223  explicit OpenMidEndingEval
224  (const NumEffectState &state=NumEffectState(),
225  bool limit_progress_independent_value=! OslConfig::hasByoyomi());
227  {
228  if (this != &src)
229  memcpy(this, &src, sizeof(OpenMidEndingEval));
230  return *this;
231  }
232  void changeTurn() { }
233  static bool initialized()
234  {
235  return initialized_flag;
236  }
237  static bool setUp(const char *filename);
238  static bool setUp();
239  static std::string defaultFilename();
241  {
242  return progress_independent_value + recalculated_value + piece_pair_value
243  + piece_pair_king_value[BLACK] + piece_pair_king_value[WHITE];
244  }
245  void debug() const;
247  {
248  return king_table_value + piece_stand_value +
249  king25_effect_each[BLACK] + king25_effect_each[WHITE] +
250  ptypex + ptypey + rook_mobility + bishop_mobility + lance_mobility +
251  rook_effect + bishop_effect +
252  piece_stand_combination + piece_stand_turn[turn] +
253  rook_pawn + pawn_drop + piece_stand_y + knight_check +
254  pawn_advance + pawn_ptypeo + promoted_minor_piece +
255  nosupport +
256  non_pawn_attacked[turn] + non_pawn_attacked_ptype[turn] +
257  ptype_yy + king3pieces + bishop_head + knight_head
258  + rook_promote_defense +
259  ptype_count_value + lance_effect_piece + ptype_y_pawn_y +
260  bishop_and_king + piece_fork_turn[turn] + rook_silver_knight + bishop_silver_knight +
261  recalculated_stage_value;
262  }
263  int openingValue() const
264  {
265  return stageValue()[0];
266  }
267  int midgameValue() const
268  {
269  return stageValue()[1];
270  }
271  int midgame2Value() const
272  {
273  return stageValue()[2];
274  }
275  int endgameValue() const
276  {
277  return stageValue()[EndgameIndex];
278  }
279  void invalidateCache() { cache=INVALID; }
280  static int progressIndependentValueAdjusted(int value, int progress,
281  int progress_max)
282  {
283  if (value > ProgressIndependentValueLimit) {
284  int diff = value - ProgressIndependentValueLimit;
285  value = ProgressIndependentValueLimit
286  + diff * progress/progress_max;
287  }
288  else if (value < -ProgressIndependentValueLimit) {
289  int diff = value + ProgressIndependentValueLimit;
290  value = -ProgressIndependentValueLimit
291  + diff * progress/progress_max;
292  }
293  return value;
294  }
296  {
297  const int progress_max = NewProgress::maxProgress(), c = progress_max/2;
298  const int progress = this->progress.progress();
299  int progress_independent = use_progress_independent_value_limit
300  ? progressIndependentValueAdjusted
301  (progressIndependentValue(), progress, progress_max)
302  : progressIndependentValue();
303  int sum = progress_independent * progress_max;
304  if (progress < c)
305  {
306  sum += openingValue() * 2*(c - progress);
307  sum += midgameValue() * 2*progress;
308  }
309  else
310  {
311  sum += midgameValue() * 2*(progress_max - progress);
312  sum += endgameValue() * 2*(progress - c);
313  }
314  return sum;
315  }
316 #ifdef EVAL_QUAD
317  int composeOpenMid2Endgame() const
318  {
319  const int progress_max = NewProgress::maxProgress();
320  const int progress = this->progress.progress();
321  const int c0 = progress_max/3, c1 = c0*2;
322 #ifndef NDEBUG
323  const int w2 = progress_max - c1;
324 #endif
325  assert(c0 == w2);
326  int progress_independent = use_progress_independent_value_limit
327  ? progressIndependentValueAdjusted
328  (progressIndependentValue(), progress, progress_max)
329  : progressIndependentValue();
330  int sum = progress_independent * c0;
331  const MultiInt stage_sum = stageValue();
332  if (progress < c0)
333  {
334  sum += stage_sum[0] * (c0 - progress);
335  sum += stage_sum[1] * progress;
336  }
337  else if (progress < c1)
338  {
339  sum += stage_sum[1] * (c1 - progress);
340  sum += stage_sum[2] * (progress-c0);
341  }
342  else
343  {
344  sum += stage_sum[2] * (progress_max - progress);
345  sum += stage_sum[3] * (progress - c1);
346  }
347  return sum;
348  }
349 #endif
350  int value() const
351  {
352  if (cache==INVALID)
353  {
354 #ifdef EVAL_QUAD
355  cache = roundUp(composeOpenMid2Endgame());
356 #else
357  cache = roundUp(composeOpenMidEndgame());
358 #endif
359  }
360  return cache;
361  }
362  const Move suggestMove(const NumEffectState& state) const
363  {
364  assert(turn == state.turn());
365  Move suggest;
366  int best_value = 0;
367  if (! rook_drop[turn].first.isPieceStand()) {
368  assert(state.hasPieceOnStand(turn, ROOK));
369  suggest = Move(rook_drop[turn].first, ROOK, turn);
370  best_value = rook_drop[turn].second;
371  }
372  assert(best_value >= 0);
373  if (bishop_drop[turn].second > best_value) {
374  assert(! bishop_drop[turn].first.isPieceStand());
375  assert(state.hasPieceOnStand(turn, BISHOP));
376  suggest = Move(bishop_drop[turn].first, BISHOP, turn);
377  best_value = bishop_drop[turn].second;
378  }
379  if (silver_drop[turn].second > best_value) {
380  assert(! silver_drop[turn].first.isPieceStand());
381  assert(state.hasPieceOnStand(turn, SILVER));
382  suggest = Move(silver_drop[turn].first, SILVER, turn);
383  best_value = silver_drop[turn].second;
384  }
385  if (knight_drop[turn].second > best_value
386  && state.hasPieceOnStand(turn, KNIGHT)) {
387  assert(! knight_drop[turn].first.isPieceStand());
388  suggest = Move(knight_drop[turn].first, KNIGHT, turn);
389  best_value = knight_drop[turn].second;
390  }
391  return suggest;
392  }
393  int expect(const NumEffectState &state, Move move) const;
394  template<Player P>
395  void updateSub(const NumEffectState &new_state, Move last_move);
396  void update(const NumEffectState &new_state, Move last_move);
397  const Progress32 progress32() const
398  {
399  return Progress32(progress.progress16(BLACK).value()
400  + progress.progress16(WHITE).value());
401  }
402  const Progress16 progress16() const { return progress.progress16(); }
403  int progressValue() const { return progress.progress(); }
404  int progressMax() const { return progress.maxProgress(); }
405  public:
406  static int infty()
407  {
408 #ifdef EVAL_QUAD
409  assert(NewProgress::maxProgress() % 3 == 0);
410  return 57984 * (NewProgress::maxProgress()/3);
411 #else
412  return 57984 * NewProgress::maxProgress();
413 #endif
414  }
415  static int captureValue(PtypeO ptypeO) {
416  assert(isValidPtypeO(ptypeO));
417  return roundUp((-PieceEval::value(ptypeO) +
418  PieceEval::value(captured(ptypeO))) * seeScale());
419  }
420  static int seeScale() {
421 #ifdef EVAL_QUAD
422  assert(NewProgress::maxProgress() % 3 == 0);
423  return (NewProgress::maxProgress()/3);
424 #else
425  return NewProgress::maxProgress();
426 #endif
427  }
428 
429  OpenMidEndingEvalDebugInfo debugInfo(const NumEffectState &state);
430  static void setRandom();
431  static void resetWeights(const int *w, size_t length);
434  return use_progress_independent_value_limit;
435  }
436  private:
437  template <class Reader>
438  static void doResetWeights(Reader& reader);
439  };
440  }
441  using ml::OpenMidEndingEval;
442  }
443  using eval::OpenMidEndingEval;
444 }
445 
446 #endif // EVAL_ML_OPENMIDENDINGEVAL_H
447 // ;;; Local Variables:
448 // ;;; mode:c++
449 // ;;; c-basic-offset:2
450 // ;;; coding:utf-8
451 // ;;; End:
void fill(const T_simple &value=T_simple())
Definition: container.h:67
圧縮していない moveの表現 .
Definition: basic_type.h:1052
利きを持つ局面
const Square square() const
Definition: basic_type.h:832
Player owner() const
Definition: basic_type.h:963
bool isOnBoard() const
Definition: basic_type.h:985
bool hasPieceOnStand(Player player, Ptype ptype) const
Definition: simpleState.h:191
Player turn() const
Definition: simpleState.h:220
const Piece pieceOf(int num) const
Definition: simpleState.h:76
Square kingSquare() const
Definition: simpleState.h:94
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
CArray< std::pair< Square, int >, 2 > bishop_drop
CArray2d< int, 2, PTYPE_SIZE > ptype_board_count
static int captureValue(PtypeO ptypeO)
void updateGoldSilverNearKing(const NumEffectState &state)
static OpenMidEndingPtypeTable Piece_Value
static volatile LoadStatus initialized_flag
CArray< PieceMask, 2 > effected_mask
CArray2d< int, 2, 3 > gs_near_king_count
CArray< PieceMask, 2 > effected_mask_for_attacked
CArray< PieceMask, 40 > attacked_mask
const Progress16 progress16() const
osl::progress::ml::NewProgress progress_t
CArray< PieceMask, 2 > effect25_supported
static int progressIndependentValueAdjusted(int value, int progress, int progress_max)
CArray< BoardMask, 2 > knight_fork_squares
OpenMidEndingEval & operator=(const OpenMidEndingEval &src)
const Progress32 progress32() const
const Move suggestMove(const NumEffectState &state) const
static int value(PtypeO ptypeO)
Definition: ptypeEval.cc:89
#define OSL_WORDSIZE
Definition: config.h:6
int max(Player p, int v1, int v2)
Definition: evalTraits.h:84
ProgressN< 16 > Progress16
Definition: progress.h:42
ProgressN< 32 > Progress32
Definition: progress.h:43
@ ROOK
Definition: basic_type.h:100
@ BISHOP
Definition: basic_type.h:99
@ KNIGHT
Definition: basic_type.h:97
@ SILVER
Definition: basic_type.h:98
bool isValidPtypeO(int ptypeO)
Definition: basic_type.cc:30
const int EndgameIndex
Definition: midgame.h:16
Player
Definition: basic_type.h:8
@ WHITE
Definition: basic_type.h:10
@ BLACK
Definition: basic_type.h:9
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
Definition: basic_type.h:264
static bool hasByoyomi()
Definition: oslConfig.cc:175
CArray< int, PROGRESS_INDEPENDENT_FEATURE_LIMIT > progress_independent_values
CArray< MultiInt, STAGE_FEATURE_LIMIT > stage_values