All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
eval/ml/king8.cc
Go to the documentation of this file.
1 #include "osl/eval/ml/king8.h"
3 using osl::MultiInt;
5 
6 template <bool Opening>
8 template <bool Opening>
10 
15 
16 void osl::eval::ml::
17 King8Effect::setUp(const Weights &weights)
18 {
19  for (size_t i = 0; i < empty_table.size(); ++i)
20  {
21  empty_table[i] = weights.value(i);
22  }
23  for (size_t i = 0; i < defense_table.size(); ++i)
24  {
25  defense_table[i] = weights.value(i + empty_table.size());
26  }
27  for (size_t i = 0; i < empty_y_table.size(); ++i)
28  {
29  empty_y_table[i] = weights.value(i + empty_table.size() +
30  defense_table.size());
31  }
32  for (size_t i = 0; i < defense_y_table.size(); ++i)
33  {
34  defense_y_table[i] = weights.value(i + empty_table.size() +
35  defense_table.size() +
36  empty_y_table.size());
37  }
38 }
39 
41  const osl::state::NumEffectState &state)
42 {
43  int result = 0;
44  const Piece black_king = state.kingPiece<BLACK>();
45  const Piece white_king = state.kingPiece<WHITE>();
46  for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
47  {
48  const Direction dir = static_cast<Direction>(i);
49  {
50  EffectState empty, defense;
51  effectState(state, BLACK, dir, empty, defense);
52  if (empty != NOT_EMPTY)
53  {
54  result -= empty_table[index(dir, empty)];
55  result -= empty_y_table[indexY(black_king, dir, empty)];
56  }
57  if (defense != NOT_EMPTY)
58  {
59  result -= defense_table[index(dir, defense)];
60  result -= defense_y_table[indexY(black_king, dir, defense)];
61  }
62  }
63  {
64  EffectState empty, defense;
65  effectState(state, WHITE, dir, empty, defense);
66  if (empty != NOT_EMPTY)
67  {
68  result += empty_table[index(dir, empty)];
69  result += empty_y_table[indexY(white_king, dir, empty)];
70  }
71  if (defense != NOT_EMPTY)
72  {
73  result += defense_table[index(dir, defense)];
74  result += defense_y_table[indexY(white_king, dir, defense)];
75  }
76  }
77  }
78  return result;
79 }
80 
83  EffectState state)
84 {
85  return (dir * 4 + state);
86 }
87 
90  const Direction dir,
91  EffectState state)
92 {
93  const int y = ((king.owner() == BLACK) ?
94  king.square().y() : 10 - king.square().y());
95  return (dir * 4 + state) * 9 + y - 1;
96 }
97 
98 
99 
100 void osl::eval::ml::
101 King8Effect::effectState(const NumEffectState &state,
102  const Player defenseP,
103  const Direction dir,
104  EffectState &empty,
105  EffectState &defense)
106 {
107  const Square target =
108  Board_Table.nextSquare(defenseP,
109  state.kingSquare(defenseP),
110  dir);
111  if (!state.pieceAt(target).isEmpty())
112  {
113  empty = defense = NOT_EMPTY;
114  return;
115  }
116  const int attack_count = state.countEffect(alt(defenseP), target);
117  const int defense_count = state.countEffect(defenseP, target);
118  if (attack_count == 0)
119  {
120  empty = NO_EFFECT;
121  defense = NO_EFFECT;
122  }
123  else if (defense_count == 1)
124  {
125  empty = MORE_EFFECT_KING_ONLY;
126  }
127  else if (attack_count >= defense_count)
128  {
129  empty = MORE_EFFECT;
130  }
131  else
132  {
133  empty = LESS_EFFECT;
134  }
135  if (defense_count == 1 && attack_count > defense_count)
136  {
137  defense = MORE_EFFECT_KING_ONLY;
138  }
139  else if (attack_count > defense_count)
140  {
141  defense = MORE_EFFECT;
142  }
143  else
144  {
145  defense = LESS_EFFECT;
146  }
147 }
148 
149 
150 
153 {
154  EffectState operator()(const NumEffectState &state,
155  const Player defense,
156  const Direction dir) const
157  {
158  const Square target =
159  Board_Table.nextSquare(defense,
160  state.kingSquare(defense),
161  dir);
162  if (!state.pieceAt(target).isEmpty())
163  return NOT_EMPTY;
164 
165  const int attack_count = state.countEffect(alt(defense), target);
166  if (attack_count == 0)
167  return NO_EFFECT;
168  const int defense_count = state.countEffect(defense, target);
169  if (defense_count == 1)
170  return MORE_EFFECT_KING_ONLY;
171  else if (attack_count >= defense_count)
172  return MORE_EFFECT;
173  else
174  return LESS_EFFECT;
175  }
176 };
177 
180 {
181  EffectState operator()(const NumEffectState &state,
182  const Player defense,
183  const Direction dir) const
184  {
185  const Square target =
186  Board_Table.nextSquare(defense,
187  state.kingSquare(defense),
188  dir);
189  if (!state.pieceAt(target).isOnBoardByOwner(defense))
190  return NOT_EMPTY;
191 
192  const int attack_count = state.countEffect(alt(defense), target);
193  if (attack_count == 0)
194  return NO_EFFECT;
195 
196  const int defense_count = state.countEffect(defense, target);
197  if (defense_count == 1 && attack_count > defense_count)
198  return MORE_EFFECT_KING_ONLY;
199  else if (attack_count > defense_count)
200  return MORE_EFFECT;
201  else
202  return LESS_EFFECT;
203  }
204 };
205 
206 template <class MakeEffectState>
207 const osl::CArray<int,2>
208 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
209 __attribute__ ((used))
210 #endif
213 {
214  MakeEffectState f;
215  CArray<int,2> result = {{0, 0}};
216  for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
217  {
218  const Direction dir = static_cast<Direction>(i);
219  const EffectState black_effect_state = f(state, BLACK, dir);
220  if (black_effect_state != NOT_EMPTY)
221  {
222  result[0] -= table[index(dir, black_effect_state)];
223  }
224  const EffectState white_effect_state = f(state, WHITE, dir);
225  if (white_effect_state != NOT_EMPTY)
226  {
227  result[1] += table[index(dir, white_effect_state)];
228  }
229  }
230 
231  return result;
232 }
233 
234 template <class MakeEffectState>
235 const osl::CArray<int,2>
236 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
237 __attribute__ ((used))
238 #endif
241  const CArray<int,2>& last_value, const table_t& table)
242 {
243  CArray<int,2> result = last_value;
244  MakeEffectState f;
245  BoardMask mask = new_state.changedEffects();
246  mask.set(last_move.to()); mask.set(last_move.from());
247  for (int z=0; z<2; ++z)
248  {
249  const Player pl = indexToPlayer(z);
250  const Square king = new_state.kingSquare(pl);
251  bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
252  if (! update)
253  continue;
254  result[z] = 0;
255  for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
256  {
257  const Direction dir = static_cast<Direction>(i);
258  const EffectState effect_state = f(new_state, pl, dir);
259  if (effect_state != NOT_EMPTY)
260  {
261  result[z] -= table[index(dir, effect_state)];
262  }
263  }
264  if (z == 1)
265  result[1] = -result[1];
266  }
267  return result;
268 }
269 
270 template <class MakeEffectState>
271 inline
272 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
274  const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
275  const table_t& table_o, const table_t& table_e)
276 {
277  CArray<int,2> result_o = last_value_o, result_e = last_value_e;
278  MakeEffectState f;
279  BoardMask mask = new_state.changedEffects();
280  mask.set(last_move.to()); mask.set(last_move.from());
281  for (int z=0; z<2; ++z)
282  {
283  const Player pl = indexToPlayer(z);
284  const Square king = new_state.kingSquare(pl);
285  bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
286  if (! update)
287  continue;
288  result_o[z] = result_e[z] = 0;
289  for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
290  {
291  const Direction dir = static_cast<Direction>(i);
292  const EffectState effect_state = f(new_state, pl, dir);
293  if (effect_state != NOT_EMPTY)
294  {
295  result_o[z] -= table_o[index(dir, effect_state)];
296  result_e[z] -= table_e[index(dir, effect_state)];
297  }
298  }
299  if (z == 1)
300  {
301  result_o[1] = -result_o[1];
302  result_e[1] = -result_e[1];
303  }
304  }
305  return std::make_pair(result_o, result_e);
306 }
307 
308 template <bool Opening>
309 void osl::eval::ml::
311 {
312  table.fill(0);
313  for (size_t i = 0; i < weights.dimension(); ++i)
314  {
315  table[i] = weights.value(i);
316  }
317 }
318 
319 template <bool Opening>
320 const osl::CArray<int,2> osl::eval::ml::
322 {
323  return evalCommon<MakeEffectStateSimple>(state, table);
324 }
325 template <bool Opening>
326 const osl::CArray<int,2> osl::eval::ml::
328  const CArray<int,2>& last_value)
329 {
330  return evalWithUpdateCommon<MakeEffectStateSimple>
331  (new_state, last_move, last_value, table);
332 }
333 
334 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
336 evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move,
337  const CArray<int,2>& last_value_opening,
338  const CArray<int,2>& last_value_ending)
339 {
340  return evalWithUpdateCommon<MakeEffectStateSimple>
341  (new_state, last_move, last_value_opening, last_value_ending,
343 }
344 
345 
346 template <bool Opening>
347 void osl::eval::ml::
349 {
350  table.fill(0);
351  for (size_t i = 0; i < weights.dimension(); ++i)
352  {
353  table[i] = weights.value(i);
354  }
355 }
356 template <bool Opening>
357 const osl::CArray<int,2> osl::eval::ml::
359 {
360  return evalCommon<MakeEffectStateDefense>(state, table);
361 }
362 template <bool Opening>
363 const osl::CArray<int,2> osl::eval::ml::
365  const CArray<int,2>& last_value)
366 {
367  return evalWithUpdateCommon<MakeEffectStateDefense>
368  (new_state, last_move, last_value, table);
369 }
370 
371 
372 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
374 evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move,
375  const CArray<int,2>& last_value_opening,
376  const CArray<int,2>& last_value_ending)
377 {
378  return evalWithUpdateCommon<MakeEffectStateDefense>
379  (new_state, last_move, last_value_opening, last_value_ending,
381 }
382 
383 
384 
395 
406 
407 void osl::eval::ml::
409 {
410  base_table.fill(0);
411  u_table.fill(0);
412  d_table.fill(0);
413  l_table.fill(0);
414  r_table.fill(0);
415  base_defense_piece_table.fill(0);
416  u_defense_piece_table.fill(0);
417  d_defense_piece_table.fill(0);
418  l_defense_piece_table.fill(0);
419  r_defense_piece_table.fill(0);
420  for (size_t i = 0; i < ONE_DIM; ++i)
421  {
422  base_table[i] = weights.value(i);
423  u_table[i] = weights.value(i+ONE_DIM);
424  d_table[i] = weights.value(i+ONE_DIM*2);
425  l_table[i] = weights.value(i+ONE_DIM*3);
426  r_table[i] = weights.value(i+ONE_DIM*4);
427  base_defense_piece_table[i] = weights.value(i+ONE_DIM*5);
428  u_defense_piece_table[i] = weights.value(i+ONE_DIM*6);
429  d_defense_piece_table[i] = weights.value(i+ONE_DIM*7);
430  l_defense_piece_table[i] = weights.value(i+ONE_DIM*8);
431  r_defense_piece_table[i] = weights.value(i+ONE_DIM*9);
432  }
433 }
434 
435 void
437  const NumEffectState &state,
438  const Player defense,
439  const Direction dir,
440  EffectState &empty, EffectState &defense_effect)
441 {
442  empty = NOT_EMPTY;
443  defense_effect = NOT_EMPTY;
444  const Square target =
445  Board_Table.nextSquare(defense,
446  state.kingSquare(defense),
447  dir);
448  const Piece piece = state.pieceAt(target);
449  if (!target.isOnBoard() ||
450  piece.isOnBoardByOwner(alt(defense)))
451  return;
452 
453  const int attack_count = state.countEffect(alt(defense), target);
454  const int defense_count = state.countEffect(defense, target);
455 
456  if (piece.isEmpty())
457  {
458  if (attack_count == 0)
459  empty = NO_EFFECT;
460  else if (defense_count == 1)
461  empty = MORE_EFFECT_KING_ONLY;
462  else if (attack_count >= defense_count)
463  empty = MORE_EFFECT;
464  else
465  empty = LESS_EFFECT;
466  }
467  else
468  {
469  if (attack_count == 0)
470  defense_effect = NO_EFFECT;
471  else if (defense_count == 1 && attack_count > defense_count)
472  defense_effect = MORE_EFFECT_KING_ONLY;
473  else if (attack_count > defense_count)
474  defense_effect = MORE_EFFECT;
475  else
476  defense_effect = LESS_EFFECT;
477  }
478 }
479 
480 int osl::eval::ml::
482 {
483  return dir * 4 + state;
484 }
485 
486 int osl::eval::ml::
488  PieceMask /*black_mask*/, PieceMask /*white_mask*/)
489 {
490  int result = 0;
491  osl::checkmate::King8Info black_king(state.Iking8Info(BLACK));
492  const int black_liberty = black_king.liberty();
493  const bool black_u_blocked =
494  (black_liberty & ((DirectionTraits<UL>::mask |
497  const bool black_d_blocked =
498  (black_liberty & ((DirectionTraits<DL>::mask |
501  const bool black_l_blocked =
502  (black_liberty & ((DirectionTraits<UL>::mask |
505  const bool black_r_blocked =
506  (black_liberty & ((DirectionTraits<UR>::mask |
509  osl::checkmate::King8Info white_king(state.Iking8Info(WHITE));
510  const int white_liberty = white_king.liberty();
511  const bool white_u_blocked =
512  (white_liberty & ((DirectionTraits<UL>::mask |
515  const bool white_d_blocked =
516  (white_liberty & ((DirectionTraits<DL>::mask |
519  const bool white_l_blocked =
520  (white_liberty & ((DirectionTraits<UL>::mask |
523  const bool white_r_blocked =
524  (white_liberty & ((DirectionTraits<UR>::mask |
527 
528  for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
529  {
530  const Direction dir = static_cast<Direction>(i);
531  EffectState black_empty_effect_state,
532  black_defense_effect_state;
533  effectState(state, BLACK, dir,
534  black_empty_effect_state, black_defense_effect_state);
535  if (black_empty_effect_state != NOT_EMPTY)
536  {
537  const int idx = index(dir, black_empty_effect_state);
538  result -= base_table[idx];
539  if (black_u_blocked)
540  result -= u_table[idx];
541  if (black_d_blocked)
542  result -= d_table[idx];
543  if (black_l_blocked)
544  result -= l_table[idx];
545  if (black_r_blocked)
546  result -= r_table[idx];
547  }
548  if (black_defense_effect_state != NOT_EMPTY)
549  {
550  const int idx = index(dir, black_defense_effect_state);
551  result -= base_defense_piece_table[idx];
552  if (black_u_blocked)
553  result -= u_defense_piece_table[idx];
554  if (black_d_blocked)
555  result -= d_defense_piece_table[idx];
556  if (black_l_blocked)
557  result -= l_defense_piece_table[idx];
558  if (black_r_blocked)
559  result -= r_defense_piece_table[idx];
560  }
561  EffectState white_empty_effect_state,
562  white_defense_effect_state;
563  effectState(state, WHITE, dir,
564  white_empty_effect_state, white_defense_effect_state);
565  if (white_empty_effect_state != NOT_EMPTY)
566  {
567  const int idx = index(dir, white_empty_effect_state);
568  result += base_table[idx];
569  if (white_u_blocked)
570  result += u_table[idx];
571  if (white_d_blocked)
572  result += d_table[idx];
573  if (white_l_blocked)
574  result += l_table[idx];
575  if (white_r_blocked)
576  result += r_table[idx];
577  }
578  if (white_defense_effect_state != NOT_EMPTY)
579  {
580  const int idx = index(dir, white_defense_effect_state);
581  result += base_defense_piece_table[idx];
582  if (white_u_blocked)
583  result += u_defense_piece_table[idx];
584  if (white_d_blocked)
585  result += d_defense_piece_table[idx];
586  if (white_l_blocked)
587  result += l_defense_piece_table[idx];
588  if (white_r_blocked)
589  result += r_defense_piece_table[idx];
590  }
591  }
592 
593  return result;
594 }
595 
596 
601 
602 void osl::eval::ml::
604 {
605  for (int i = 0; i < ONE_DIM; ++i)
606  {
607  for (int s=0; s<NStages; ++s)
608  table[i][s] = weights.value(i + ONE_DIM*s);
609  }
610 }
611 
612 void osl::eval::ml::
614 {
615  for (int i = 0; i < ONE_DIM; ++i)
616  {
617  for (int s=0; s<NStages; ++s)
618  table[i][s] = weights.value(i + ONE_DIM*s);
619  }
620 }
621 
622 template <int Sign>
623 inline
624 void osl::eval::ml::
625 KingXBothBlocked::adjust(int index, int index_y, MultiInt &out)
626 {
627  if(Sign>0)
628  out += KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
629  else
630  out -= KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
631 }
632 
634 KingXBothBlocked::eval(const NumEffectState &state)
635 {
637  King8Info black(state.Iking8Info(BLACK));
638  if ((black.liberty() & (DirectionTraits<UL>::mask |
644  {
645  const Square black_king = state.kingSquare<BLACK>();
646  adjust<1>(index(black_king),
647  indexY<BLACK>(black_king),
648  result[BLACK]);
649  }
650 
651  King8Info white(state.Iking8Info(WHITE));
652  if ((white.liberty() & (DirectionTraits<UL>::mask |
658  {
659  const Square white_king = state.kingSquare<WHITE>();
660  adjust<-1>(index(white_king),
661  indexY<WHITE>(white_king),
662  result[WHITE]);
663  }
664 
665  return result;
666 }
667 
668 template <osl::Player P>
670  Square king, int diff)
671 {
672  const int king_x = king.x();
673  if (P == BLACK)
674  {
675  const int target_x = (king_x > 5) ? 10 - king_x : king_x;
676  int x_diff = diff;
677  if (king_x >= 6)
678  x_diff = -x_diff;
679  return target_x - 1 + ((x_diff == 1) ? 0 : 5);
680  }
681  else
682  {
683  const int target_x = (king_x > 5) ? 10 - king_x : king_x;
684  int x_diff = diff;
685  if (king_x >= 5)
686  x_diff = -x_diff;
687  return target_x - 1 + ((x_diff == 1) ? 0 : 5);
688  }
689 }
690 
691 template <osl::Player P>
693  const NumEffectState &state,
694  int diff)
695 {
696 #if 1
697  const King8Info info(state.Iking8Info(P));
698  if ((diff == 1) ^ (P == BLACK))
699  return (info.liberty() & (DirectionTraits<UR>::mask
701  | DirectionTraits<DR>::mask)) == 0;
702  assert((diff == 1 && P == BLACK) || (diff == -1 && P == WHITE));
703  return (info.liberty() & (DirectionTraits<UL>::mask
705  | DirectionTraits<DL>::mask)) == 0;
706 #else
707  const Square pos = state.kingSquare<P>();
708  const int target_x = pos.x() + diff;
709  for (int y = pos.y() - 1; y <= pos.y() + 1; ++y)
710  {
711  Square target(target_x, y);
712  Piece p(state.pieceAt(target));
713  if ((!p.isEdge()) && ! p.isOnBoardByOwner<P>() &&
714  !state.hasEffectAt<PlayerTraits<P>::opponent>(target))
715  {
716  return false;
717  }
718  }
719  return true;
720 #endif
721 }
722 
725 {
726  MultiIntPair val;
727  const Square black_king = state.kingSquare<BLACK>();
728  const Square white_king = state.kingSquare<WHITE>();
729  const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
730  if (isBlocked<BLACK>(state, 1))
731  val[b] += table[index<BLACK>(black_king, 1)];
732  if (isBlocked<BLACK>(state, -1))
733  val[b] += table[index<BLACK>(black_king, -1)];
734 
735  if (isBlocked<WHITE>(state, 1))
736  val[w] -= table[index<WHITE>(white_king, 1)];
737  if (isBlocked<WHITE>(state, -1))
738  val[w] -= table[index<WHITE>(white_king, -1)];
739  return val;
740 }
741 
744  const table_t& table)
745 {
746  MultiIntPair val;
747  const Square black_king = state.kingSquare<BLACK>();
748  const Square white_king = state.kingSquare<WHITE>();
749  const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
750  const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(state, 1);
751  const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(state, -1);
752  if (black_r_blocked)
753  val[b] += table[index<BLACK>(black_king, 1)];
754  if (black_l_blocked)
755  val[b] += table[index<BLACK>(black_king, -1)];
756 
757  const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(state, 1);
758  const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(state, -1);
759  if (white_r_blocked)
760  val[w] -= table[index<WHITE>(white_king, 1)];
761  if (white_l_blocked)
762  val[w] -= table[index<WHITE>(white_king, -1)];
763  return val;
764 }
765 
766 #if 0
767 inline
768 std::pair<osl::CArray<int,2>,osl::CArray<int,2> >
769 osl::eval::ml::
770 KingXBlockedBase::evalWithUpdate(const NumEffectState &new_state, Move last_move,
771  const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
772  const table_t& table_o, const table_t& table_e)
773 {
774  CArray<int,2> val_o = last_value_o;
775  CArray<int,2> val_e = last_value_e;
776  const Square black_king = new_state.kingSquare<BLACK>();
777  const Square white_king = new_state.kingSquare<WHITE>();
778  BoardMask mask = new_state.changedEffects();
779  mask.set(last_move.from()); mask.set(last_move.to());
780  if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king)))
781  {
782  const int b = playerToIndex(BLACK);
783  val_o[b] = val_e[b]= 0;
784  if (isBlocked<BLACK>(new_state, 1)) {
785  val_o[b] += table_o[index<BLACK>(black_king, 1)];
786  val_e[b] += table_e[index<BLACK>(black_king, 1)];
787  }
788  if (isBlocked<BLACK>(new_state, -1)) {
789  val_o[b] += table_o[index<BLACK>(black_king, -1)];
790  val_e[b] += table_e[index<BLACK>(black_king, -1)];
791  }
792  }
793  if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
794  {
795  const int w = playerToIndex(WHITE);
796  val_o[w] = val_e[w]= 0;
797  if (isBlocked<WHITE>(new_state, 1)) {
798  val_o[w] -= table_o[index<WHITE>(white_king, 1)];
799  val_e[w] -= table_e[index<WHITE>(white_king, 1)];
800  }
801  if (isBlocked<WHITE>(new_state, -1)) {
802  val_o[w] -= table_o[index<WHITE>(white_king, -1)];
803  val_e[w] -= table_e[index<WHITE>(white_king, -1)];
804  }
805  }
806  return std::make_pair(val_o, val_e);
807 }
808 #endif
809 
810 template <int Sign>
811 inline
812 void osl::eval::ml::
813 KingXBlockedYBase::adjust(int index, int index_y, MultiInt &out)
814 {
815  if(Sign>0)
816  out += KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
817  else
818  out -= KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
819 }
820 
821 inline
822 void
824 KingXBlockedYBase::evalWithUpdateBang(const NumEffectState &new_state,
825  Move last_move,
826  MultiIntPair& values)
827 {
828  const Square black_king = new_state.kingSquare<BLACK>();
829  const Square white_king = new_state.kingSquare<WHITE>();
830  BoardMask mask = new_state.changedEffects();
831  mask.set(last_move.from()); mask.set(last_move.to());
832  if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king)))
833  {
834  values[BLACK].clear();
835  const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, 1);
836  const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, -1);
837  if (black_r_blocked) {
838  adjust<1>(KingXBlockedBase::index<BLACK>(black_king, 1),
839  index<BLACK>(black_king, 1),
840  values[BLACK]);
841  }
842  if (black_l_blocked) {
843  adjust<1>(KingXBlockedBase::index<BLACK>(black_king, -1),
844  index<BLACK>(black_king, -1),
845  values[BLACK]);
846  }
847  if (black_r_blocked && black_l_blocked)
848  {
849  KingXBothBlocked::adjust<1>(KingXBothBlocked::index(black_king),
850  KingXBothBlocked::indexY<BLACK>(black_king),
851  values[BLACK]);
852  }
853  }
854  if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
855  {
856  values[WHITE].clear();
857  const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, 1);
858  const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, -1);
859  if (white_r_blocked) {
860  adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, 1),
861  index<WHITE>(white_king, 1),
862  values[WHITE]);
863  }
864  if (white_l_blocked) {
865  adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, -1),
866  index<WHITE>(white_king, -1),
867  values[WHITE]);
868  }
869  if (white_r_blocked && white_l_blocked)
870  {
872  KingXBothBlocked::indexY<WHITE>(white_king),
873  values[WHITE]);
874  }
875  }
876 }
877 
878 template <osl::Player P> inline
880  Square king, int diff)
881 {
882  const int king_x = king.x();
883  if (P == BLACK)
884  {
885  const int king_y = king.y();
886  const int target_x = (king_x > 5) ? 10 - king_x : king_x;
887  int x_diff = diff;
888  if (king_x >= 6)
889  x_diff = -x_diff;
890  return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
891  }
892  else
893  {
894  const int king_y = 10 - king.y();
895  const int target_x = (king_x > 5) ? 10 - king_x : king_x;
896  int x_diff = diff;
897  if (king_x >= 5)
898  x_diff = -x_diff;
899  return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
900  }
901 }
902 
905 
906 void osl::eval::ml::
907 KingXBlocked::setUp(const Weights &weights,int stage)
908 {
909  for (size_t i = 0; i < table.size(); ++i)
910  {
911  table[i][stage] = weights.value(i);
912  }
913 }
914 void
916 KingXBlockedBoth::evalWithUpdateBang(const NumEffectState &new_state, Move last_move,
917  MultiIntPair& last_values)
918 {
920  (new_state, last_move, last_values);
921 }
922 
923 void osl::eval::ml::
924 KingXBlockedY::setUp(const Weights &weights,int stage)
925 {
926  for (size_t i = 0; i < table.size(); ++i)
927  {
928  table[i][stage] = weights.value(i);
929  }
930 }
931 
932 
935 
937 {
938  for (int i = 0; i < ONE_DIM; ++i)
939  {
940  for (int s=0; s<NStages; ++s)
941  table[i][s] = weights.value(i + ONE_DIM*s);
942  }
943 }
944 
946 {
947  for (int i = 0; i < ONE_DIM; ++i)
948  {
949  for (int s=0; s<NStages; ++s)
950  KingXBlocked3::y_table[i][s] = weights.value(i + ONE_DIM*s);
951  }
952  for(int x=1;x<=5;x++)
953  for(int y=1;y<=9;y++)
954  for(int is_l=0;is_l<2;is_l++)
955  for(int u_blocked=0;u_blocked<2;u_blocked++)
956  for(int opp_u_blocked=0;opp_u_blocked<2;opp_u_blocked++)
957  for(int opp_blocked=0;opp_blocked<2;opp_blocked++){
958  int indexY=x - 1 + 5 * (y - 1 + 9 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1 : 0) + 2 * (opp_blocked ? 1 : 0)))));
959  int index0=x - 1 + 5 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1 : 0) + 2 * (opp_blocked ? 1 : 0))));
961  }
962 }
963 
965 KingXBlocked3::eval(const NumEffectState &state)
966 {
968  King8Info black(state.Iking8Info(BLACK));
969  if ((black.liberty() & (DirectionTraits<UL>::mask |
972  {
973  adjust<1>(
974  indexY<BLACK>(state.kingSquare<BLACK>(),
975  true,
976  (black.liberty() & DirectionTraits<U>::mask) == 0,
977  (black.liberty() & DirectionTraits<UR>::mask) == 0,
978  (black.liberty() & DirectionTraits<R>::mask) == 0),
979  result);
980  }
981  if ((black.liberty() & (DirectionTraits<UR>::mask |
984  {
985  adjust<1>(
986  indexY<BLACK>(state.kingSquare<BLACK>(),
987  false,
988  (black.liberty() & DirectionTraits<U>::mask) == 0,
989  (black.liberty() & DirectionTraits<UL>::mask) == 0,
990  (black.liberty() & DirectionTraits<L>::mask) == 0),
991  result);
992  }
993  King8Info white(state.Iking8Info(WHITE));
994  if ((white.liberty() & (DirectionTraits<UL>::mask |
997  {
998  adjust<-1>(
999  indexY<WHITE>(state.kingSquare<WHITE>(),
1000  true,
1001  (white.liberty() & DirectionTraits<U>::mask) == 0,
1002  (white.liberty() & DirectionTraits<UR>::mask) == 0,
1003  (white.liberty() & DirectionTraits<R>::mask) == 0),
1004  result);
1005  }
1006  if ((white.liberty() & (DirectionTraits<UR>::mask |
1009  {
1010  adjust<-1>(
1011  indexY<WHITE>(state.kingSquare<WHITE>(),
1012  false,
1013  (white.liberty() & DirectionTraits<U>::mask) == 0,
1014  (white.liberty() & DirectionTraits<UL>::mask) == 0,
1015  (white.liberty() & DirectionTraits<L>::mask) == 0),
1016  result);
1017  }
1018  return result;
1019 }
1020 
1021 
1022 
1024 
1025 
1026 void osl::eval::ml::
1027 AnagumaEmpty::setUp(const Weights &weights,int stage)
1028 {
1029  for (size_t i = 0; i < table.size(); ++i)
1030  {
1031  table[i][stage] = weights.value(i);
1032  }
1033 }
1034 
1035 
1037  Square king, Square target)
1038 {
1039  return std::abs(king.x() - target.x()) + std::abs(king.y() - target.y()) * 2;
1040 }
1041 
1042 template <osl::Player Defense>
1044 {
1045  MultiInt result;
1046  const Square king = state.kingSquare<Defense>();
1047  if ((king.x() == 1 || king.x() == 9) &&
1048  ((Defense == BLACK && king.y() == 9) ||
1049  (Defense == WHITE && king.y() == 1))){
1050  const int x = (king.x() == 1 ? 2 : 8);
1051  const int y = (Defense == BLACK ? 8 : 2);
1052  if(Defense==BLACK){
1053  if (state.pieceAt(Square(king.x(), y)).isEmpty())
1054  result +=table[index(king, Square(king.x(), y))];
1055  if (state.pieceAt(Square(x, y)).isEmpty())
1056  result +=table[index(king, Square(x, y))];
1057  if (state.pieceAt(Square(x, king.y())).isEmpty())
1058  result +=table[index(king, Square(x, king.y()))];
1059  }
1060  else{
1061  if (state.pieceAt(Square(king.x(), y)).isEmpty())
1062  result -=table[index(king, Square(king.x(), y))];
1063  if (state.pieceAt(Square(x, y)).isEmpty())
1064  result -=table[index(king, Square(x, y))];
1065  if (state.pieceAt(Square(x, king.y())).isEmpty())
1066  result -=table[index(king, Square(x, king.y()))];
1067  }
1068  }
1069  return result;
1070 }
1071 
1074 {
1075  return evalOne<BLACK>(state) + evalOne<WHITE>(state);
1076 }
1077 
1078 
1079 
1080 namespace osl
1081 {
1082  namespace eval
1083  {
1084  namespace ml
1085  {
1086  template class King8EffectEmptySquare<true>;
1087  template class King8EffectEmptySquare<false>;
1088  template class King8EffectDefenseSquare<true>;
1089  template class King8EffectDefenseSquare<false>;
1090  }
1091  }
1092 }
1093 // ;;; Local Variables:
1094 // ;;; mode:c++
1095 // ;;; c-basic-offset:2
1096 // ;;; End: