All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
progressEval.cc
Go to the documentation of this file.
1 /* progressEval.cc
2  */
7 #include "osl/oslConfig.h"
8 #include <boost/filesystem/operations.hpp>
9 #include <iostream>
10 #include <cstdio>
11 
14  == 0);
15 #ifndef MINIMAL
16 template <class Opening>
17 osl::CArray<int, osl::PTYPEO_SIZE> osl::eval::ProgressEvalGeneral<Opening>::capture_values;
18 
19 template <class Opening>
20 int osl::eval::
21 ProgressEvalGeneral<Opening>::expect(const NumEffectState& state, Move move) const
22 {
23  if (move.isPass())
24  return value();
25  progress_t new_progress = current_progress.expect(state, move);
26  return composeValue(opening_eval.expect(state, move),
27  endgame_eval.expect(state, move),
28  progress16(), new_progress.progress16(BLACK),
29  new_progress.progress16(WHITE),
30  defense_effect.progress16(BLACK),
31  defense_effect.progress16(WHITE),
32  minor_piece_bonus.value(progress16(),
33  progress16bonus(BLACK),
34  progress16bonus(WHITE)),
35  progress_independent_bonus,
36  progress_dependent_bonus);
37 }
38 
39 template <class Opening>
40 void osl::eval::
42 {
43  // read weights if exists
44  std::string filename;
45  if (filename_given)
46  filename = filename_given;
47  else {
48  filename = OslConfig::home();
49  filename += "/data/progresseval.txt";
50  }
51  if (boost::filesystem::exists(filename.c_str())) {
52  if (OslConfig::verbose())
53  std::cerr << "loading " << filename << "\n";
54  CArray<int, AdjustableDimension> w;
55  FILE *fp = fopen(filename.c_str(), "r");
56  for (size_t i=0; i<w.size(); ++i) {
57  if (fscanf(fp, "%d", &w[i]) != 1) {
58  std::cerr << filename << " read failed " << i << "\n";
59  break;
60  }
61  }
62  fclose(fp);
63  resetWeights(&w[0]);
64  }
65 
66  // others
67  for (int i=0; i<PTYPEO_SIZE; ++i) {
68  // 序盤を使用
69  const PtypeO ptypeo = static_cast<PtypeO>(i+PTYPEO_MIN);
70  capture_values[i] = composeValue(opening_eval_t::captureValue(ptypeo), 0,
71  Progress16(0), Progress16(0), Progress16(0),
72  Progress16(0), Progress16(0), 0, 0, 0);
73  }
74 }
75 
76 template <class Opening>
77 void osl::eval::
79 {
80  opening_eval_t::resetWeights(w);
81  endgame_eval_t::resetWeights(w+PTYPE_SIZE);
82 }
83 
84 template <class Opening>
87  : opening_eval(state), endgame_eval(state),
88  current_progress(state), defense_effect(state),
89  minor_piece_bonus(state), major_pieces(0),
90  cache(INVALID)
91 {
92  for (int i = PtypeTraits<ROOK>::indexMin;
93  i < PtypeTraits<ROOK>::indexLimit; ++i)
94  {
95  if (state.pieceOf(i).owner() == osl::BLACK)
96  ++major_pieces;
97  }
98  for (int i = PtypeTraits<BISHOP>::indexMin;
99  i < PtypeTraits<BISHOP>::indexLimit; ++i)
100  {
101  if (state.pieceOf(i).owner() == osl::BLACK)
102  ++major_pieces;
103  }
104  can_check_pieces.fill(0);
105  // knight and pawn are intentionally omitted
106  initializeCheckPiece<BLACK, ROOK>(state);
107  initializeCheckPiece<BLACK, BISHOP>(state);
108  initializeCheckPiece<BLACK, GOLD>(state);
109  initializeCheckPiece<BLACK, SILVER>(state);
110  initializeCheckPiece<BLACK, LANCE>(state);
111  initializeCheckPiece<WHITE, ROOK>(state);
112  initializeCheckPiece<WHITE, BISHOP>(state);
113  initializeCheckPiece<WHITE, GOLD>(state);
114  initializeCheckPiece<WHITE, SILVER>(state);
115  initializeCheckPiece<WHITE, LANCE>(state);
123  attack_bonus[BLACK] = calculateAttackBonusEach<WHITE>(state);
124  attack_bonus[WHITE] = calculateAttackBonusEach<BLACK>(state);
126  progress_dependent_bonus += attackBonusScale(attack_bonus[WHITE], BLACK);
127  progress_dependent_bonus += calculatePinBonus(state);
130  progress_independent_bonus += calculateEnterKingBonus<BLACK>(state);
131  progress_independent_bonus += calculateEnterKingBonus<WHITE>(state);
132  progress_independent_bonus += calculateMiddleKingBonus<BLACK>(state);
133  progress_independent_bonus += calculateMiddleKingBonus<WHITE>(state);
134  assert(initialized());
135 }
136 
137 template <class Opening>
138 template<osl::Player P, osl::Ptype PTYPE>
139 void osl::eval::
141  const NumEffectState &state)
142 {
143  if (state.hasPieceOnStand<PTYPE>(P))
144  {
145  int count = state.countPiecesOnStand(P, PTYPE);
146  initializeCheckPieceDir<P, PTYPE, UL, LONG_UL>(state, count);
147  initializeCheckPieceDir<P, PTYPE, U, LONG_U>(state, count);
148  initializeCheckPieceDir<P, PTYPE, UR, LONG_UR>(state, count);
149  initializeCheckPieceDir<P, PTYPE, L, LONG_L>(state, count);
150  initializeCheckPieceDir<P, PTYPE, R, LONG_R>(state, count);
151  initializeCheckPieceDir<P, PTYPE, DL, LONG_DL>(state, count);
152  initializeCheckPieceDir<P, PTYPE, D, LONG_D>(state, count);
153  initializeCheckPieceDir<P, PTYPE, DR, LONG_DR>(state, count);
154  }
155 }
156 
157 template <class Opening>
158 template<osl::Player P, osl::Ptype PTYPE, osl::Direction Dir, osl::Direction LongDir>
159 void osl::eval::
161  const NumEffectState &,
162  int count)
163 {
166  can_check_pieces[P][Dir] = count;
167 }
168 
169 template <class Opening>
170 int osl::eval::
172 {
173  using namespace osl::mobility;
174  int val=0;
175  for(int i=PtypeTraits<ROOK>::indexMin;
176  i<PtypeTraits<ROOK>::indexLimit;++i){
177  Piece p=state.pieceOf(i);
178  if(p.isOnBoardByOwner<BLACK>()){
179  int vc= RookMobility::countVerticalAll(BLACK,state,p);
180  int hc= RookMobility::countHorizontalAll(BLACK,state,p);
181  if(p.isPromoted()){
184  }
185  else{
188  }
189  }
190  else if(p.isOnBoardByOwner<WHITE>()){
191  int vc= RookMobility::countVerticalAll(WHITE,state,p);
192  int hc= RookMobility::countHorizontalAll(WHITE,state,p);
193  if(p.isPromoted()){
196  }
197  else{
200  }
201  }
202  }
203  return val;
204 }
205 
206 template <class Opening>
207 int osl::eval::
209 {
210  using namespace osl::mobility;
211  int val=0;
213  i<PtypeTraits<BISHOP>::indexLimit;++i){
214  Piece p=state.pieceOf(i);
215  if(p.isOnBoardByOwner<BLACK>()){
216  int c= BishopMobility::countAll(BLACK,state,p);
217  if(p.isPromoted())
218  val+=MobilityTable::pbishop[c];
219  else
220  val+=MobilityTable::bishop[c];
221  }
222  else if(p.isOnBoardByOwner<WHITE>()){
223  int c= BishopMobility::countAll(WHITE,state,p);
224  if(p.isPromoted())
225  val-=MobilityTable::pbishop[c];
226  else
227  val-=MobilityTable::bishop[c];
228  }
229  }
230  return val;
231 }
232 
233 template <class Opening>
234 int osl::eval::
236 {
237  using namespace osl::mobility;
238  int val=0;
240  i<PtypeTraits<LANCE>::indexLimit;++i){
241  Piece p=state.pieceOf(i);
242  if(p.isOnBoardByOwner<BLACK>() && !p.isPromoted()){
243  int c= LanceMobility::countAll(BLACK,state,p);
244  val+=MobilityTable::lance[c];
245  }
246  else if(p.isOnBoardByOwner<WHITE>() && !p.isPromoted()){
247  int c= LanceMobility::countAll(WHITE,state,p);
248  val-=MobilityTable::lance[c];
249  }
250  }
251  return val;
252 }
253 
254 template <class Opening> inline
255 int osl::eval::
257 {
258  using namespace osl::mobility;
259  int val=rook_mobility + bishop_mobility + lance_mobility;
260  return val*128/100 * 12;
261 }
262 
263 template <class Opening>
264 void osl::eval::
266  const NumEffectState& new_state, Move last_move)
267 {
268  if (last_move.isPass())
269  return;
270  const Ptype captured = last_move.capturePtype();
271  if (last_move.isDrop())
272  {
273  const Ptype ptype = last_move.ptype();
274  if (ptype == ROOK)
275  {
276  --can_check_pieces[playerToIndex(last_move.player())][U];
277  --can_check_pieces[playerToIndex(last_move.player())][D];
278  --can_check_pieces[playerToIndex(last_move.player())][L];
279  --can_check_pieces[playerToIndex(last_move.player())][R];
280  }
281  else if (ptype == BISHOP)
282  {
283  --can_check_pieces[playerToIndex(last_move.player())][UL];
284  --can_check_pieces[playerToIndex(last_move.player())][DL];
285  --can_check_pieces[playerToIndex(last_move.player())][UR];
286  --can_check_pieces[playerToIndex(last_move.player())][DR];
287  }
288  if (ptype == GOLD)
289  {
290  --can_check_pieces[playerToIndex(last_move.player())][U];
291  --can_check_pieces[playerToIndex(last_move.player())][D];
292  --can_check_pieces[playerToIndex(last_move.player())][L];
293  --can_check_pieces[playerToIndex(last_move.player())][R];
294  --can_check_pieces[playerToIndex(last_move.player())][UL];
295  --can_check_pieces[playerToIndex(last_move.player())][UR];
296  }
297  else if (ptype == SILVER)
298  {
299  --can_check_pieces[playerToIndex(last_move.player())][U];
300  --can_check_pieces[playerToIndex(last_move.player())][UL];
301  --can_check_pieces[playerToIndex(last_move.player())][DL];
302  --can_check_pieces[playerToIndex(last_move.player())][UR];
303  --can_check_pieces[playerToIndex(last_move.player())][DR];
304  }
305  if (ptype == LANCE)
306  {
307  --can_check_pieces[playerToIndex(last_move.player())][U];
308  }
309  }
310 
311  if (captured != PTYPE_EMPTY)
312  {
313  const Ptype captured_base = unpromote(captured);
314  if (isMajor(captured_base))
315  {
316  if (last_move.player() == BLACK)
317  ++major_pieces;
318  else
319  --major_pieces;
320  }
321  if (captured_base == ROOK)
322  {
323  ++can_check_pieces[playerToIndex(last_move.player())][U];
324  ++can_check_pieces[playerToIndex(last_move.player())][D];
325  ++can_check_pieces[playerToIndex(last_move.player())][L];
326  ++can_check_pieces[playerToIndex(last_move.player())][R];
327  }
328  else if (captured_base == BISHOP)
329  {
330  ++can_check_pieces[playerToIndex(last_move.player())][UL];
331  ++can_check_pieces[playerToIndex(last_move.player())][DL];
332  ++can_check_pieces[playerToIndex(last_move.player())][UR];
333  ++can_check_pieces[playerToIndex(last_move.player())][DR];
334  }
335  if (captured_base == GOLD)
336  {
337  ++can_check_pieces[playerToIndex(last_move.player())][U];
338  ++can_check_pieces[playerToIndex(last_move.player())][D];
339  ++can_check_pieces[playerToIndex(last_move.player())][L];
340  ++can_check_pieces[playerToIndex(last_move.player())][R];
341  ++can_check_pieces[playerToIndex(last_move.player())][UL];
342  ++can_check_pieces[playerToIndex(last_move.player())][UR];
343  }
344  else if (captured_base == SILVER)
345  {
346  ++can_check_pieces[playerToIndex(last_move.player())][U];
347  ++can_check_pieces[playerToIndex(last_move.player())][UL];
348  ++can_check_pieces[playerToIndex(last_move.player())][DL];
349  ++can_check_pieces[playerToIndex(last_move.player())][UR];
350  ++can_check_pieces[playerToIndex(last_move.player())][DR];
351  }
352  if (captured_base == LANCE)
353  {
354  ++can_check_pieces[playerToIndex(last_move.player())][U];
355  }
356  }
357  opening_eval.update(new_state, last_move);
358  endgame_eval.update(new_state, last_move);
359  current_progress.update(new_state, last_move);
360  defense_effect.update(new_state, last_move);
361  minor_piece_bonus.update(new_state, last_move);
362 
363  if (new_state.longEffectChanged<ROOK>())
364  rook_mobility = calculateMobilityBonusRook(new_state);
365  if (new_state.longEffectChanged<BISHOP>())
366  bishop_mobility = calculateMobilityBonusBishop(new_state);
367  if (new_state.longEffectChanged<LANCE>())
368  lance_mobility = calculateMobilityBonusLance(new_state);
369 
370  progress_independent_bonus = calculateMobilityBonus();
371  progress_independent_bonus += calculateAttackRooks(new_state);
372  progress_independent_bonus += calculateSilverPenalty(new_state);
373  progress_independent_bonus += calculateGoldPenalty(new_state);
374 
375  {
376  bool capture_or_drop = last_move.isDrop() || last_move.capturePtype() != PTYPE_EMPTY;
377  const Square kb = new_state.kingSquare<BLACK>(), kw = new_state.kingSquare<WHITE>();
378  BoardMask mask = new_state.changedEffects();
379  mask.set(last_move.from()); mask.set(last_move.to());
380  if ((capture_or_drop && new_state.turn() == BLACK)
381  || mask.anyInRange(Board_Mask_Table3x3.mask(kb)))
382  attack_bonus[BLACK] = calculateAttackBonusEach<WHITE>(new_state);
383  if ((capture_or_drop && new_state.turn() == WHITE)
384  || mask.anyInRange(Board_Mask_Table3x3.mask(kw)))
385  attack_bonus[WHITE] = calculateAttackBonusEach<BLACK>(new_state);
386  }
387  progress_dependent_bonus = attackBonusScale(attack_bonus[BLACK], WHITE);
388  progress_dependent_bonus += attackBonusScale(attack_bonus[WHITE], BLACK);
389  progress_dependent_bonus += calculatePinBonus(new_state);
390  progress_independent_bonus += calculateKnightCheck(new_state);
391  progress_independent_bonus += calculateRookRankBonus(new_state);
392  progress_independent_bonus += calculateEnterKingBonus<BLACK>(new_state);
393  progress_independent_bonus += calculateEnterKingBonus<WHITE>(new_state);
394  progress_independent_bonus += calculateMiddleKingBonus<BLACK>(new_state);
395  progress_independent_bonus += calculateMiddleKingBonus<WHITE>(new_state);
396  invalidateCache();
397 }
398 
399 template <class Opening>
400 int osl::eval::
402  const NumEffectState& state) const
403 {
404  const Piece black_king = state.kingPiece<BLACK>();
405  const Piece white_king = state.kingPiece<WHITE>();
406  int bonus = 0;
407  PieceMask white_mask = pin_mask[WHITE] = state.pin(WHITE);
408  PieceMask black_mask = pin_mask[BLACK] = state.pin(BLACK);
409  while (white_mask.any())
410  {
411  const Piece piece = state.pieceOf(white_mask.takeOneBit());
412  bonus -= endgame_eval.valueOf(
413  black_king, white_king,
414  piece) / 4;
415  }
416 
417  while (black_mask.any())
418  {
419  const Piece piece = state.pieceOf(black_mask.takeOneBit());
420  bonus -= endgame_eval.valueOf(
421  black_king, white_king,
422  piece) / 4;
423  }
424 
425  return bonus * progress16().value() / 16;
426 }
427 
428 template <class Opening>
429 int osl::eval::
431  const NumEffectState& state) const
432 {
433  int rooks = 0;
434  for(int i = PtypeTraits<ROOK>::indexMin;
435  i < PtypeTraits<ROOK>::indexLimit; ++i)
436  {
437  const Piece rook = state.pieceOf(i);
438  if (rook.isOnBoard() && rook.square().canPromote(rook.owner()) &&
439  state.kingPiece(alt(rook.owner())).square().canPromote(rook.owner()))
440  {
441  if (rook.owner() == BLACK)
442  ++rooks;
443  else
444  --rooks;
445  }
446  }
447  if (rooks == 2)
449  else if (rooks == -2)
451 
452  return 0;
453 }
454 
455 template <class Opening>
456 int osl::eval::
458  const NumEffectState& state) const
459 {
460  return attackBonusScale(calculateAttackBonusEach<BLACK>(state), BLACK) +
461  attackBonusScale(calculateAttackBonusEach<WHITE>(state), WHITE);
462 }
463 
464 template <class Opening>
465 template <osl::Player Attack, osl::Direction Dir>
466 int osl::eval::
468  const NumEffectState& state) const
469 {
470  const Player defense = PlayerTraits<Attack>::opponent;
471  const Square king = state.kingSquare<defense>();
472 
474  int result = 0;
475 
476  const Piece p = state.pieceAt(target);
477  if (! p.isEdge() && (Dir != UUR || Attack != BLACK || p.isOnBoard()))
478  {
479  int effect_diff = (state.countEffect(Attack, target) -
480  state.countEffect(PlayerTraits<Attack>::opponent, target));
481  if ((effect_diff >= 0 && p.isEmpty()) ||
482  (effect_diff >= 1 && !p.isEmpty() &&
483  p.owner() ==alt(Attack)))
484  {
485  if (Dir == UL || Dir == U || Dir == UR)
486  result = PtypeEvalTraits<PAWN>::val * 3 * 16;
487  else if (Dir == L || Dir == R)
488  result = (PtypeEvalTraits<PAWN>::val * 1 +
489  PtypeEvalTraits<PAWN>::val / 2) * 16;
490  else
491  result = PtypeEvalTraits<PAWN>::val * 1 * 16;
492 
493  if ((effect_diff > 0 &&
494  (target.canPromote<Attack>() ||
495  state.hasEffectByPtype<GOLD>(Attack,target) ||
496  state.hasEffectByPtype<SILVER>(Attack,target) ||
497  state.hasEffectByPtype<ROOK>(Attack,target) ||
498  state.hasEffectByPtype<BISHOP>(Attack,target))) ||
499  (p.isEmpty() &&
500  can_check_pieces[Attack][Dir] > 0))
501  result += PtypeEvalTraits<PAWN>::val * 16;
502  }
503  }
504 
505  if (Attack == BLACK)
506  return result;
507  else
508  return -result;
509 }
510 
511 // P is attacking player
512 template <class Opening>
513 template <osl::Player P>
514 int osl::eval::
516  const NumEffectState& state) const
517 {
518  int result = 0;
519  result += calculateAttackBonusOne<P, UL>(state);
520  result += calculateAttackBonusOne<P, U>(state);
521  result += calculateAttackBonusOne<P, UR>(state);
522  result += calculateAttackBonusOne<P, L>(state);
523  result += calculateAttackBonusOne<P, R>(state);
524  result += calculateAttackBonusOne<P, DL>(state);
525  result += calculateAttackBonusOne<P, D>(state);
526  result += calculateAttackBonusOne<P, DR>(state);
527  return result;
528 }
529 
530 template <class Opening>
531 int osl::eval::
533  const NumEffectState &state) const
534 {
535  int result = 0;
536  const int bonus = PtypeEvalTraits<PAWN>::val / 4 * 16;
537  for (int i = PtypeTraits<SILVER>::indexMin;
538  i < PtypeTraits<SILVER>::indexLimit; ++i)
539  {
540  const Piece silver = state.pieceOf(i);
541  if (!silver.isOnBoard() || silver.isPromoted())
542  continue;
543 
544  if (silver.square().y() >= 4 && silver.square().y() <= 6)
545  {
546  Square dl = Board_Table.nextSquare(silver.owner(),
547  silver.square(), DL);
548  Square dr = Board_Table.nextSquare(silver.owner(),
549  silver.square(), DR);
550  if ((!dl.isOnBoard() ||
551  state.pieceAt(dl).isOnBoardByOwner(silver.owner()) ||
552  state.hasEffectAt(alt(silver.owner()), dl)) &&
553  (!dr.isOnBoard() ||
554  state.pieceAt(dr).isOnBoardByOwner(silver.owner()) ||
555  state.hasEffectAt(alt(silver.owner()), dr)))
556  {
557  if (silver.owner() == BLACK)
558  result -= bonus;
559  else
560  result += bonus;
561  }
562  }
563 
564  }
565  return result;
566 }
567 
568 template <class Opening>
569 int osl::eval::
571  const NumEffectState &state) const
572 {
573  int result = 0;
574  const int bonus = PtypeEvalTraits<PAWN>::val / 4 * 16;
575  for (int i = PtypeTraits<GOLD>::indexMin;
576  i < PtypeTraits<GOLD>::indexLimit; ++i)
577  {
578  const Piece gold = state.pieceOf(i);
579  if (!gold.isOnBoard())
580  continue;
581 
582  if (gold.square().y() >= 4 && gold.square().y() <= 6)
583  {
584  Square d = Board_Table.nextSquare(gold.owner(),
585  gold.square(), D);
586  if ((state.pieceAt(d).isOnBoardByOwner(gold.owner()) ||
587  state.hasEffectAt(alt(gold.owner()), d)))
588  {
589  if (gold.owner() == BLACK)
590  result -= bonus;
591  else
592  result += bonus;
593  }
594  }
595 
596  }
597  return result;
598 }
599 
600 template <class Opening>
601 int osl::eval::
603  const NumEffectState& state) const
604 {
605  return calculateKnightCheckEach<BLACK>(state) +
606  calculateKnightCheckEach<WHITE>(state);
607 }
608 
609 // P is attacking player
610 template <class Opening>
611 template <osl::Player P>
612 int osl::eval::
614  const NumEffectState& state) const
615 {
616  const int bonus = (P == BLACK ? 1 : -1) *
618  const Square king = state.kingSquare<PlayerTraits<P>::opponent>();
619  const Square up = king +
621  if (!state.hasEffectAt<PlayerTraits<P>::opponent>(king)
622  && ! state.pieceAt(up).isEdge())
623  {
624  const Square ur =
626  if (! state.pieceAt(ur).isEdge() &&
627  state.pieceAt(ur).isEmpty() &&
628  !state.hasEffectAt<PlayerTraits<P>::opponent>(ur) &&
629  (state.hasPieceOnStand<KNIGHT>(P) ||
630  state.hasEffectByPtype<KNIGHT>(P, ur)))
631  {
632  if (state.hasPieceOnStand<GOLD>(P))
633  return bonus;
634  else
635  return bonus / 2;
636  }
637 
638  const Square ul =
640  if (! state.pieceAt(ul).isEdge() &&
641  state.pieceAt(ul).isEmpty() &&
642  !state.hasEffectAt<PlayerTraits<P>::opponent>(ul) &&
643  (state.hasPieceOnStand<KNIGHT>(P) ||
644  state.hasEffectByPtype<KNIGHT>(P, ul)))
645  {
646  if (state.hasPieceOnStand<GOLD>(P))
647  return bonus;
648  else
649  return bonus / 2;
650  }
651  }
652  return 0;
653 }
654 
655 // P is defense player
656 template <class Opening>
657 template <osl::Player P>
658 int osl::eval::
660  const NumEffectState& state) const
661 {
662  const Square king = state.kingSquare<P>();
663 
664  if ((P == BLACK && king.y() > 4) ||
665  (P == WHITE && king.y() < 6))
666  {
667  return 0;
668  }
669 
670  // If not the last rank, check one rank above
671  if ((P == BLACK && king.y() >= 2) ||
672  (P == WHITE && king.y() <= 8))
673  {
674  const int y = P == BLACK ? king.y() - 1 : king.y() + 1;
675  const int min_x = std::max(1, king.x() - 1);
676  const int max_x = std::min(9, king.x() + 1);
677  bool found_opening = false;
678  for (int x = min_x; x <= max_x; ++x)
679  {
680  Square pos(x, y);
681  Piece piece = state.pieceAt(pos);
682  if (piece.isEmpty())
683  {
684  if (!state.hasEffectAt<PlayerTraits<P>::opponent>(pos))
685  found_opening = true;
686  else if (state.countEffect(P, pos) <=
687  state.countEffect(alt(P), pos))
688  return 0;
689  }
690  else if (piece.owner() == alt(P))
691  {
692  return 0;
693  }
694  else if (piece.owner() == P)
695  {
696  if (state.countEffect(P, pos) <
697  state.countEffect(alt(P), pos))
698  return 0;
699  }
700  else
701  abort();
702  }
703  if (!found_opening)
704  return 0;
705  }
706 
708 }
709 
710 // P is defense player
711 template <class Opening>
712 template <osl::Player P>
713 int osl::eval::
715  const NumEffectState& state) const
716 {
717  const Square king = state.kingSquare<P>();
718 
719  if ((P == BLACK && king.y() >= 6 && major_pieces == 4) ||
720  (P == WHITE && king.y() <= 4 && major_pieces == 0))
721  {
723  }
724  return 0;
725 }
726 
727 template<class Opening>
728 int osl::eval::
730  const NumEffectState& state) const
731 {
732  int bonus = 0;
733  for (int i = PtypeTraits<ROOK>::indexMin;
734  i < PtypeTraits<ROOK>::indexLimit; ++i)
735  {
736  const Piece rook = state.pieceOf(i);
737  const Player owner = rook.owner();
738  const int target_y = owner == BLACK ? 3 : 7;
739  const int inbetween_y = owner == BLACK ? 4 : 6;
740  if (rook.isOnBoard() && !rook.square().canPromote(owner))
741  {
742  const Piece rank5 = state.pieceAt(Square(rook.square().x(), 5));
743  const Piece rank4 = state.pieceAt(Square(rook.square().x(),
744  inbetween_y));
745  const Square rank3_pos(rook.square().x(), target_y);
746  if (state.hasEffectByPtype<SILVER>(
747  owner,
748  Square(rook.square().x(),
749  inbetween_y)) &&
750  !rank5.isOnBoardByOwner(alt(owner)) &&
751  !state.pieceAt(rank3_pos).isOnBoardByOwner(owner) &&
752  state.countEffect(alt(owner),
753  Square(rook.square().x(), target_y)) <= 1 &&
754  state.countEffect(owner,
755  Square(rook.square().x(), inbetween_y)) >=
756  state.countEffect(alt(owner),
757  Square(rook.square().x(), inbetween_y)))
758  {
759  if (rook.owner() == BLACK)
760  bonus += PtypeEvalTraits<PAWN>::val * 2 * 16;
761  else
762  bonus -= PtypeEvalTraits<PAWN>::val * 2 * 16;
763  }
764  else if (((rank5.isOnBoardByOwner(owner) &&
765  rank5.ptype() == PAWN &&
766  state.hasEffectByPiece(rook, rank5.square())) ||
767  (rank4.isOnBoardByOwner(owner) &&
768  rank4.ptype() == PAWN &&
769  state.hasEffectByPiece(rook, rank4.square()))) &&
770  !state.hasEffectAt(alt(owner),
771  rank3_pos) &&
772  state.countEffect(alt(owner),
773  Square(rook.square().x(),
774  inbetween_y)) <= 1)
775  {
776  if (rook.owner() == BLACK)
777  bonus += PtypeEvalTraits<PAWN>::val * 2 * 16;
778  else
779  bonus -= PtypeEvalTraits<PAWN>::val * 2 * 16;
780  }
781  else if (state.hasEffectByPiece(rook, rank3_pos) &&
782  !state.hasEffectAt(alt(owner), rank3_pos) &&
783  !state.isPawnMaskSet(owner, rook.square().x()))
784  {
785  if (rook.owner() == BLACK)
786  bonus += PtypeEvalTraits<PAWN>::val * 16;
787  else
788  bonus -= PtypeEvalTraits<PAWN>::val * 16;
789  }
790  }
791  }
792  return bonus;
793 }
794 
795 template <class Opening>
796 void osl::eval::
797 ProgressEvalGeneral<Opening>::setValues(const SimpleState& state,
798  Progress16 progress16,
799  PieceValues& out)
800 {
801  PieceValues opening, endgame;
802  const NumEffectState nstate(state);
803  const progress_t progress(nstate);
804  const defense_t defense_effect(nstate);
805  const MinorPieceBonus minor_piece_bonus(state);
806  opening_eval_t::setValues(state, opening);
807  endgame_eval_t::setValues(state, endgame);
808  for (int i=0; i<Piece::SIZE; ++i)
809  {
810  out[i] = composeValue(opening[i] & (~1), endgame[i] & (~1), progress16,
811  progress.progress16(BLACK),
812  progress.progress16(WHITE),
813  defense_effect.progress16(BLACK),
814  defense_effect.progress16(WHITE),
815  minor_piece_bonus.value(progress16,
816  progress.progress16bonus(BLACK),
817  progress.progress16bonus(WHITE)), 0, 0);
818  }
819 }
820 
821 template <class Opening>
822 void osl::eval::
823 ProgressEvalGeneral<Opening>::setValues(const SimpleState& state, PieceValues& out)
824 {
825  const NumEffectState nstate(state);
826  const progress_t progress(nstate);
827  setValues(state, progress.progress16(), out);
828 }
829 
830 template <class Opening>
832 ProgressEvalGeneral<Opening>::debugInfo(const NumEffectState& state) const
833 {
834  ProgressDebugInfo debug_info;
835  debug_info.eval = value();
836  debug_info.opening = openingValue();
837  debug_info.endgame = endgameValue();
838  debug_info.progress = current_progress.progress16().value();
839  debug_info.progress_bonus = attackDefenseBonus();
840  debug_info.progress_independent_bonus = progress_independent_bonus;
841  debug_info.progress_dependent_bonus = progress_dependent_bonus;
842  debug_info.minor_piece_bonus = minorPieceValue();
843 
844  debug_info.black_danger = current_progress.progress16bonus(BLACK).value();
845  debug_info.white_danger = current_progress.progress16bonus(WHITE).value();
846  debug_info.black_defense = defense_effect.progress16(BLACK).value();
847  debug_info.white_defense = defense_effect.progress16(WHITE).value();
848 
849  debug_info.mobility_bonus = calculateMobilityBonus();
850  debug_info.two_rook_bonus = calculateAttackRooks(state);
851  debug_info.knight_check_bonus = calculateKnightCheck(state);
852  debug_info.rook_rank_bonus = calculateRookRankBonus(state);
853  debug_info.enter_king_bonus = calculateEnterKingBonus<BLACK>(state) +
854  calculateEnterKingBonus<WHITE>(state);
855  debug_info.middle_king_bonus = calculateMiddleKingBonus<BLACK>(state) +
856  calculateMiddleKingBonus<WHITE>(state);
857  debug_info.silver_penalty = calculateSilverPenalty(state);
858  debug_info.gold_penalty = calculateGoldPenalty(state);
859 
860  debug_info.king8_attack_bonus = calculateAttackBonus(state);
861  debug_info.pin_bonus = calculatePinBonus(state);
862 
863  debug_info.minor_piece_bonus_info =
864  minor_piece_bonus.debugInfo(progress16(),
865  progress16bonus(BLACK),
866  progress16bonus(WHITE));
867 
868  return debug_info;
869 }
870 
871 namespace osl
872 {
873  namespace eval
874  {
876  }
877 #ifndef DFPNSTATONE
878  template void
879  EffectUtil::findThreat<eval::ProgressEval>(const NumEffectState& state,
880  Square position,
881  PtypeO ptypeo,
882  PieceVector& out);
883 #endif
884 }
885 
886 #endif
887 /* ------------------------------------------------------------------------- */
888 // ;;; Local Variables:
889 // ;;; mode:c++
890 // ;;; c-basic-offset:2
891 // ;;; coding:utf-8
892 // ;;; End: