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"
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
22namespace osl
23{
24 namespace eval
25 {
26 namespace ml
27 {
28 using namespace osl::progress::ml;
30 {
31 public:
33 };
34
36 {
112 int value;
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:
128 enum {
130 ProgressIndependentValueLimit = 4000
131 };
132 enum LoadStatus { Zero=0, Loaded, Random };
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
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 }
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
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 }
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の表現 .
利きを持つ局面
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
Player turn() const
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
OpenMidEndingEval & operator=(const OpenMidEndingEval &src)
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
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
@ 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
static const char * name(ProgressIndependentFeature)