All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
kingTable.cc
Go to the documentation of this file.
3 using osl::MultiInt;
4 
7 
9 KingPieceRelative::setUp(const Weights &weights, int stage)
10 {
11  for (int i = PTYPE_PIECE_MIN; i <= PTYPE_MAX; ++i)
12  {
13  for (int y = 0; y <= 16; ++y)
14  {
15  for (int x = 0; x <= 8; ++x)
16  {
17  const int distance = x * 17 + y;
18  attack_table[i][distance][stage] =
19  weights.value((i - PTYPE_PIECE_MIN) * 17 * 9 + distance);
20  defense_table[i][distance][stage] =
21  weights.value((i - PTYPE_PIECE_MIN) * 17 * 9 + distance + TABLE_DIM);
22  }
23  }
24  }
25 }
26 
28 KingPieceRelative::eval(const NumEffectState &state)
29 {
30  MultiInt value;
31  const Square b_king = state.kingSquare(BLACK);
32  const Square w_king = state.kingSquare(WHITE);
33  for (int i = 0; i < osl::Piece::SIZE; ++i)
34  {
35  const osl::Piece piece = state.pieceOf(i);
36  if (!piece.isOnBoard())
37  continue;
38  const Ptype ptype = piece.ptype();
39  const Square position = piece.square();
40  if (piece.owner() == BLACK)
41  {
42  const int attack_index = index(state, BLACK,position, w_king);
43  const int defense_index = index(state, BLACK,position, b_king);
44  value += attack_table[ptype][attack_index];
45  value += defense_table[ptype][defense_index];
46  }
47  else
48  {
49  const int attack_index = index(state, WHITE,position, b_king);
50  const int defense_index = index(state, WHITE,position, w_king);
51  value -= attack_table[ptype][attack_index];
52  value -= defense_table[ptype][defense_index];
53  }
54  }
55  return value;
56 }
57 
58 template<osl::Player P>
60 KingPieceRelative::evalWithUpdate(const NumEffectState &state,
61  Move moved, MultiInt const& last_value)
62 {
63  if (moved.isPass())
64  return last_value;
65 
66  if (moved.ptype() == osl::KING)
67  {
68  return eval(state);
69  }
70 
71  MultiInt value(last_value);
72  if (!moved.isDrop())
73  {
74  const PtypeO ptypeO = moved.oldPtypeO();
75  const int attack_index = index(state, ptypeO, moved.from(), false);
76  const int defense_index = index(state,ptypeO, moved.from(), true);
77  if (P == BLACK)
78  {
79  value -= attack_table[moved.oldPtype()][attack_index];
80  value -= defense_table[moved.oldPtype()][defense_index];
81  }
82  else
83  {
84  value += attack_table[moved.oldPtype()][attack_index];
85  value += defense_table[moved.oldPtype()][defense_index];
86  }
87  }
88  {
89  const int attack_index = index(state, moved.ptypeO(), moved.to(), false);
90  const int defense_index = index(state, moved.ptypeO(), moved.to(), true);
91  if (P == BLACK)
92  {
93  value += attack_table[moved.ptype()][attack_index];
94  value += defense_table[moved.ptype()][defense_index];
95  }
96  else
97  {
98  value -= attack_table[moved.ptype()][attack_index];
99  value -= defense_table[moved.ptype()][defense_index];
100  }
101  }
102  const Ptype captured = moved.capturePtype();
103  if (captured != PTYPE_EMPTY)
104  {
105  const PtypeO ptypeO = moved.capturePtypeO();
106  const int attack_index = index(state, ptypeO, moved.to(), false);
107  const int defense_index = index(state,ptypeO, moved.to(), true);
108  if (P == BLACK)
109  {
110  value += attack_table[captured][attack_index];
111  value += defense_table[captured][defense_index];
112  }
113  else
114  {
115  value -= attack_table[captured][attack_index];
116  value -= defense_table[captured][defense_index];
117  }
118  }
119  return value;
120 }
121 
122 
125 
126 void osl::eval::ml::
128 {
129  for (int i = 0; i < ONE_DIM; ++i)
130  {
131  for (int s=0; s<NStages; ++s)
132  table[i][s] = weights.value(i + ONE_DIM*s);
133  }
134 }
135 
136 template <int Sign> inline
137 void osl::eval::ml::
139 {
140  if(Sign>0)
141  out += table[attack] + table[defense];
142  else
143  out -= table[attack] + table[defense];
144 }
145 
147 KingPieceRelativeNoSupport::eval(const NumEffectState &state)
148 {
150  const CArray<Square, 2> kings = {{
151  state.kingSquare(BLACK),
152  state.kingSquare(WHITE),
153  }};
154  PieceMask black = (~state.effectedMask(BLACK)) & state.piecesOnBoard(BLACK);
155  black.reset(KingTraits<BLACK>::index);
156  while (black.any())
157  {
158  const Piece piece = state.pieceOf(black.takeOneBit());
159  const int index_attack = index(BLACK, kings[WHITE],
160  piece);
161  const int index_defense = index(BLACK, kings[BLACK],
162  piece) + ONE_DIM / 2;
163  adjust<1>(index_attack, index_defense, result);
164  }
165  PieceMask white = (~state.effectedMask(WHITE)) & state.piecesOnBoard(WHITE);
166  white.reset(KingTraits<WHITE>::index);
167  while (white.any())
168  {
169  const Piece piece = state.pieceOf(white.takeOneBit());
170  const int index_attack = index(WHITE, kings[BLACK],
171  piece);
172  const int index_defense = index(WHITE, kings[WHITE],
173  piece) + ONE_DIM / 2;
174  adjust<-1>(index_attack, index_defense, result);
175  }
176  return result;
177 }
178 
181  const NumEffectState &state,
182  Move moved,
183  const CArray<PieceMask, 2> &effected_mask,
184  const MultiInt &last_values)
185 {
186  if (moved.ptype() == KING)
187  return eval(state);
188 
189  const CArray<PieceMask, 2> new_mask = {{
190  state.effectedMask(BLACK),
191  state.effectedMask(WHITE)
192  }};
193  const CArray<Square, 2> kings = {{
194  state.kingSquare<BLACK>(),
195  state.kingSquare<WHITE>(),
196  }};
197 
198  MultiInt result(last_values);
199  const Piece p = state.pieceAt(moved.to());
200  if (!moved.isDrop())
201  {
202  if (!effected_mask[p.owner()].test(p.number()))
203  {
204  const int index_attack =
205  index(p.owner(), kings[alt(p.owner())],
206  moved.oldPtype(), moved.from());
207  const int index_defense =
208  index(p.owner(), kings[p.owner()], moved.oldPtype(),
209  moved.from()) + ONE_DIM / 2;
210  if (p.owner() == BLACK)
211  adjust<-1>(index_attack, index_defense, result);
212  else
213  adjust<1>(index_attack, index_defense, result);
214  }
215  }
216  const Ptype captured = moved.capturePtype();
217  if (captured != PTYPE_EMPTY)
218  {
219  PieceMask captured_mask =
220  effected_mask[moved.player()] & (~state.piecesOnBoard(BLACK)) &
221  (~state.piecesOnBoard(WHITE));
222 
223  if (!effected_mask[alt(moved.player())].test(captured_mask.takeOneBit()))
224  {
225  const int index_attack =
226  index(alt(p.owner()), kings[p.owner()],
227  captured, moved.to());
228  const int index_defense =
229  index(alt(p.owner()), kings[alt(p.owner())], captured,
230  moved.to()) + ONE_DIM / 2;
231  if (p.owner() == BLACK)
232  adjust<1>(index_attack, index_defense, result);
233  else
234  adjust<-1>(index_attack, index_defense, result);
235  }
236  }
237  if (!new_mask[p.owner()].test(p.number()))
238  {
239  const int index_attack =
240  index(p.owner(), kings[alt(p.owner())],
241  moved.ptype(), moved.to());
242  const int index_defense =
243  index(p.owner(), kings[p.owner()], moved.ptype(),
244  moved.to()) + ONE_DIM / 2;
245  if (p.owner() == BLACK)
246  adjust<1>(index_attack, index_defense, result);
247  else
248  adjust<-1>(index_attack, index_defense, result);
249  }
250  PieceMask onboard_black = state.piecesOnBoard(BLACK);
251  onboard_black.reset(KingTraits<BLACK>::index);
252  // old 0, new, 1
253  PieceMask black_old = (~effected_mask[0]) & new_mask[0] & onboard_black;
254  black_old.reset(p.number());
255  while (black_old.any())
256  {
257  const Piece piece = state.pieceOf(black_old.takeOneBit());
258  const int index_attack =
259  index(BLACK, kings[WHITE], piece);
260  const int index_defense =
261  index(BLACK, kings[BLACK], piece) + ONE_DIM / 2;
262  adjust<-1>(index_attack, index_defense, result);
263  }
264  // old 1, new 0
265  PieceMask black_new = effected_mask[0] & (~new_mask[0]) & onboard_black;
266  black_new.reset(p.number());
267  while (black_new.any())
268  {
269  const Piece piece = state.pieceOf(black_new.takeOneBit());
270  const int index_attack =
271  index(BLACK, kings[WHITE], piece);
272  const int index_defense =
273  index(BLACK, kings[BLACK], piece) + ONE_DIM / 2;
274  adjust<1>(index_attack, index_defense, result);
275  }
276 
277  // old 0, new, 1
278  PieceMask onboard_white = state.piecesOnBoard(WHITE);
279  onboard_white.reset(KingTraits<WHITE>::index);
280  PieceMask white_old = (~effected_mask[1]) & new_mask[1] & onboard_white;
281  white_old.reset(p.number());
282  while (white_old.any())
283  {
284  const Piece piece = state.pieceOf(white_old.takeOneBit());
285  const int index_attack =
286  index(WHITE, kings[BLACK], piece);
287  const int index_defense =
288  index(WHITE, kings[WHITE], piece) + ONE_DIM / 2;
289  adjust<1>(index_attack, index_defense, result);
290  }
291  // old 1, new 0
292  PieceMask white_new = effected_mask[1] & (~new_mask[1]) & onboard_white;
293  white_new.reset(p.number());
294  while (white_new.any())
295  {
296  const Piece piece = state.pieceOf(white_new.takeOneBit());
297  const int index_attack =
298  index(WHITE, kings[BLACK], piece);
299  const int index_defense =
300  index(WHITE, kings[WHITE], piece) + ONE_DIM / 2;
301  adjust<-1>(index_attack, index_defense, result);
302  }
303 
304  return result;
305 }
306 
307 
309 
311 {
312  for (int i = 0; i < ONE_DIM; ++i)
313  {
314  for (int s=0; s<NStages; ++s)
315  table[i][s] = weights.value(i + ONE_DIM*s);
316  }
317 }
318 
319 template <int Sign>
320 inline
321 void osl::eval::ml::
322 PtypeYY::adjust(int black, int white, MultiInt &out)
323 {
324  if(Sign>0)
325  out += table[black] - table[white];
326  else
327  out -= table[black] - table[white];
328 }
329 
331 PtypeYY::eval(const NumEffectState &state)
332 {
334  const CArray<Square,2> kings = {{
335  state.kingSquare(BLACK),
336  state.kingSquare(WHITE),
337  }};
338  for (int i = 0; i < Piece::SIZE; ++i)
339  {
340  const Piece p = state.pieceOf(i);
341  if (!p.isOnBoard())
342  continue;
343  const int black_index = index<BLACK>(p, kings[BLACK]);
344  const int white_index = index<WHITE>(p, kings[WHITE]);
345  adjust<1>(black_index, white_index, result);
346  }
347 
348  return result;
349 }
350 
352  const NumEffectState& state,
353  Move moved,
354  const MultiInt &last_values)
355 {
356  if (moved.ptype() == KING && moved.to().y() != moved.from().y())
357  {
358  return eval(state);
359  }
360  MultiInt result(last_values);
361  if (!moved.isDrop())
362  {
363  const int index_black = index<BLACK>(moved.oldPtypeO(), moved.from(),
364  state.kingSquare<BLACK>());
365  const int index_white = index<WHITE>(moved.oldPtypeO(), moved.from(),
366  state.kingSquare<WHITE>());
367  adjust<-1>(index_black, index_white, result);
368  }
369  Ptype captured = moved.capturePtype();
370  if (captured != PTYPE_EMPTY)
371  {
372  const PtypeO ptypeO = newPtypeO(alt(moved.player()), captured);
373  const int index_black = index<BLACK>(ptypeO, moved.to(),
374  state.kingSquare<BLACK>());
375  const int index_white = index<WHITE>(ptypeO, moved.to(),
376  state.kingSquare<WHITE>());
377  adjust<-1>(index_black, index_white, result);
378  }
379 
380  {
381  const int index_black = index<BLACK>(moved.ptypeO(), moved.to(),
382  state.kingSquare<BLACK>());
383  const int index_white = index<WHITE>(moved.ptypeO(), moved.to(),
384  state.kingSquare<WHITE>());
385  adjust<1>(index_black, index_white, result);
386  }
387  return result;
388 }
389 
390 
393 
394 void osl::eval::ml::
396 {
397  table.fill(0);
398  for (size_t i = 0; i < weights.dimension(); ++i)
399  {
400  table[i] = weights.value(i);
401  }
402 }
403 
405  const osl::state::NumEffectState &state,
406  const osl::Player attack,
407  int &effect,
408  int &piece)
409 {
410  const Square king = state.kingSquare(alt(attack));
411  const int min_x = std::max(1, king.x() - 2);
412  const int max_x = std::min(9, king.x() + 2);
413  const int min_y = std::max(1, king.y() - 2);
414  const int max_y = std::min(9, king.y() + 2);
415 
416  PieceMask mask;
417  int count = 0;
418  for (int y = min_y; y <= max_y; ++y)
419  {
420  for (int x = min_x; x <= max_x; ++x)
421  {
422  const Square target(x, y);
423  count += state.countEffect(attack, target);
424  mask |= state.effectSetAt(target);
425  }
426  }
427  effect = std::min(255, count);
428  mask = mask & state.piecesOnBoard(attack);
429  piece = std::min(16, mask.countBit());
430 }
431 
432 int osl::eval::ml::King25Effect::index(int effect, int piece_count)
433 {
434  return effect + 128 * piece_count;
435 }
436 
438  const osl::state::NumEffectState &state)
439 {
440  int black_effect, black_piece, white_effect, white_piece;
441  countEffectAndPieces(state, osl::BLACK, black_effect, black_piece);
442  countEffectAndPieces(state, osl::WHITE, white_effect, white_piece);
443  return table[index(black_effect, black_piece)] - table[index(white_effect, white_piece)];
444 }
445 
446 
451 
453 {
454  for (int i = 0; i < ONE_DIM; ++i)
455  {
456  for (int s=0; s<NStages; ++s)
457  table[i][s] = weights.value(i + ONE_DIM*s);
458  }
459 }
460 
462 {
463  for (int i = 0; i < ONE_DIM; ++i)
464  {
465  for (int s=0; s<NStages; ++s)
466  table[i][s] = weights.value(i + ONE_DIM*s);
467  }
468 }
469 
470 
475 
477 {
478  for (int i = 0; i < ONE_DIM; ++i)
479  {
480  for (int s=0; s<NStages; ++s)
481  table[i][s] = weights.value(i + ONE_DIM*s);
482  }
483 }
484 
486 {
487  for (int i = 0; i < ONE_DIM; ++i)
488  {
489  for (int s=0; s<NStages; ++s)
490  table[i][s] = weights.value(i + ONE_DIM*s);
491  }
492 }
493 
494 
499 
500 void osl::eval::ml::
502 {
503  attack_table.fill(0);
504  defense_table.fill(0);
505  for (size_t i = 0; i < DIM/2; ++i)
506  {
507  attack_table[i] = weights.value(i);
508  defense_table[i] = weights.value(i+DIM/2);
509  }
510 }
511 
512 template <osl::Player Attack>
513 void
515  const osl::state::NumEffectState &state,
516  PieceMask& mask,
517  PieceMask& supported_mask,
518  int &attack_effect,
519  int &attack_piece,
520  int &defense_effect,
521  int &defense_piece,
522  int &attack_piece_supported,
523  CArray<int, 5> &verticals,
524  CArray<int, 5> &king_verticals)
525 {
526  king_verticals.fill(0);
527  const Player Defense = PlayerTraits<Attack>::opponent;
528  const Square king = state.kingSquare(Defense);
529  const int min_x = std::max(1, king.x() - 2);
530  const int max_x = std::min(9, king.x() + 2);
531  const int min_y = std::max(1, king.y() - 2);
532  const int max_y = std::min(9, king.y() + 2);
533  int mask_all=(1<<5)-1;
534  verticals.fill(mask_all);
535  const int y_mask_base=(1 << (Defense == BLACK ? (min_y-king.y()) + 2 : -(max_y-king.y()) + 2));
536  if(Defense==BLACK)
537  mask_all ^= ((1<<(max_y-king.y()+3))-y_mask_base);
538  else
539  mask_all ^= ((1<<(king.y()-min_y+3))-y_mask_base);
540  mask.resetAll();
541  int attack_count = 0;
542  int defense_count = 0;
543  for (int x = min_x; x <= max_x; ++x)
544  {
545  int vertical_x=mask_all;
546  int king_vertical_x = 0;
547  if(Defense==BLACK){
548  int y_mask=y_mask_base;
549  for (int y = min_y; y <= max_y; ++y, y_mask+=y_mask)
550  {
551  const Square target(x, y);
552  const int count = state.countEffect(Attack, target);
553  defense_count += state.countEffect(alt(Attack), target);
554  mask |= state.effectSetAt(target);
555  if(count>0){
556  attack_count += count;
557  vertical_x |= y_mask;
558  }
559  const Piece piece = state.pieceAt(target);
560  if (count == 0 &&
561  (piece.isEmpty() || piece.owner() == Attack))
562  {
563  king_vertical_x |= y_mask;
564  }
565  }
566  }
567  else{
568  int y_mask=y_mask_base;
569  for (int y = max_y; y >= min_y; --y, y_mask+=y_mask)
570  {
571  const Square target(x, y);
572  const int count = state.countEffect(Attack, target);
573  defense_count += state.countEffect(alt(Attack), target);
574  mask |= state.effectSetAt(target);
575  if(count>0){
576  attack_count += count;
577  vertical_x |= y_mask;
578  }
579  const Piece piece = state.pieceAt(target);
580  if (count == 0 &&
581  (piece.isEmpty() || piece.owner() == Attack))
582  {
583  king_vertical_x |= y_mask;
584  }
585  }
586  }
587  const int x_diff = king.x() - x;
588  verticals[(Defense == BLACK ? 2 - x_diff : 2 + x_diff)] = vertical_x;
589  king_verticals[(Defense == BLACK ? 2 - x_diff : 2 + x_diff)] =
590  king_vertical_x;
591  }
592  attack_effect = std::min(127, attack_count);
593  defense_effect = std::min(127, defense_count);
594  PieceMask attack_mask = mask & state.piecesOnBoard(Attack);
595  attack_piece = std::min(16, attack_mask.countBit());
596  PieceMask defense_mask = mask & state.piecesOnBoard(alt(Attack));
597  defense_piece = std::min(16, defense_mask.countBit());
598  supported_mask = attack_mask & state.effectedMask(Attack);
599  attack_piece_supported = std::min(16, supported_mask.countBit());
600 }
601 
602 
607 
608 void osl::eval::ml::
610 {
611  attack_table.fill(0);
612  defense_table.fill(0);
613  for (size_t i = 0; i < DIM/2; ++i)
614  {
615  attack_table[i] = weights.value(i);
616  defense_table[i] = weights.value(i+DIM/2);
617  }
618 }
619 
620 
621 
622 void osl::eval::ml::
623 King25EmptySquareNoEffect::setUpBase(const Weights &weights, CArray<int, 15>& table)
624 {
625  table.fill(0);
626  for (size_t i = 0; i < weights.dimension(); ++i)
627  {
628  table[i] = weights.value(i);
629  }
630 }
631 
632 template <osl::Player defense>
633 int osl::eval::ml::
634 King25EmptySquareNoEffect::evalOne(const NumEffectState &state, const CArray<int, 15>& table)
635 {
636  int result = 0;
637  const Piece king_piece = state.kingPiece<defense>();
638  const Square king = king_piece.square();
639  const int min_x = std::max(1, king.x() - 2);
640  const int max_x = std::min(9, king.x() + 2);
641  const int min_y = std::max(1, king.y() - 2);
642  const int max_y = std::min(9, king.y() + 2);
643 
644  PieceMask pieces=state.piecesOnBoard(defense);
645  pieces.reset(KingTraits<defense>::index);
646 
647  for (int x = min_x; x <= max_x; ++x)
648  {
649  for (int y = min_y; y <= max_y; ++y)
650  {
651  Square target(x, y);
652  if (state.pieceAt(target).isEmpty()
653  && ! /*state.hasEffectNotBy(defense, king_piece, target)*/
654  (pieces & state.effectSetAt(target)).any())
655  {
656  if (defense == BLACK)
657  result += table[index(x - king.x(), y - king.y())];
658  else
659  result -= table[index(king.x() - x, king.y() - y)];
660  }
661  }
662  }
663  return result;
664 }
665 
666 template <osl::Player defense>
667 std::pair<int,int> osl::eval::ml::
668 King25EmptySquareNoEffect::evalOne(const NumEffectState &state,
669  const CArray<int, 15>& opening, const CArray<int, 15>& ending)
670 {
671  int result_o = 0, result_e = 0;
672  const Piece king_piece = state.kingPiece<defense>();
673  const Square king = king_piece.square();
674  const int min_x = std::max(1, king.x() - 2);
675  const int max_x = std::min(9, king.x() + 2);
676  const int min_y = std::max(1, king.y() - 2);
677  const int max_y = std::min(9, king.y() + 2);
678 
679  PieceMask pieces=state.piecesOnBoard(defense);
680  pieces.reset(KingTraits<defense>::index);
681 
682  for (int x = min_x; x <= max_x; ++x)
683  {
684  for (int y = min_y; y <= max_y; ++y)
685  {
686  Square target(x, y);
687  if (state.pieceAt(target).isEmpty()
688  && ! /*state.hasEffectNotBy(defense, king_piece, target)*/
689  (pieces & state.effectSetAt(target)).any())
690  {
691  if (defense == BLACK)
692  {
693  result_o += opening[index(x - king.x(), y - king.y())];
694  result_e += ending[index(x - king.x(), y - king.y())];
695  }
696  else
697  {
698  result_o -= opening[index(king.x() - x, king.y() - y)];
699  result_e -= ending[index(king.x() - x, king.y() - y)];
700  }
701  }
702  }
703  }
704  return std::make_pair(result_o, result_e);
705 }
706 
707 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
708 King25EmptySquareNoEffect::eval(const NumEffectState &state,
709  const CArray<int, 15>& opening, const CArray<int, 15>& ending)
710 {
711  std::pair<int,int> b = evalOne<BLACK>(state, opening, ending);
712  std::pair<int,int> w = evalOne<WHITE>(state, opening, ending);
713  CArray<int,2> result_o = {{ b.first, w.first }};
714  CArray<int,2> result_e = {{ b.second, w.second }};
715  return std::make_pair(result_o, result_e);
716 }
717 
718 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
719 King25EmptySquareNoEffect::evalWithUpdate(const NumEffectState &state, Move last_move,
720  const CArray<int, 15>& opening, const CArray<int, 15>& ending,
721  const CArray<int, 2>& last_opening_value,
722  const CArray<int, 2>& last_ending_value)
723 {
724  BoardMask mb = state.changedEffects(BLACK), mw = state.changedEffects(WHITE);
725  mb.set(Square(last_move.to())); mb.set(Square(last_move.from()));
726  mw.set(Square(last_move.to())); mw.set(Square(last_move.from()));
727  const Square kb = state.kingSquare<BLACK>(), kw = state.kingSquare<WHITE>();
728  const bool update_black = mb.anyInRange(Board_Mask_Table5x5.mask(kb));
729  const bool update_white = mw.anyInRange(Board_Mask_Table5x5.mask(kw));
730  std::pair<int,int> b = update_black
731  ? evalOne<BLACK>(state, opening, ending)
732  : std::make_pair(last_opening_value[0], last_ending_value[0]);
733  std::pair<int,int> w = update_white
734  ? evalOne<WHITE>(state, opening, ending)
735  : std::make_pair(last_opening_value[1], last_ending_value[1]);
736  CArray<int,2> result_o = {{ b.first, w.first }};
737  CArray<int,2> result_e = {{ b.second, w.second }};
738  return std::make_pair(result_o, result_e);
739 }
740 
741 
746 
747 const osl::CArray<int,2> osl::eval::ml::
748 King25EmptySquareNoEffectOpening::eval(const NumEffectState &state)
749 {
750  CArray<int, 2> result = {{ evalOne<BLACK>(state, table), evalOne<WHITE>(state, table) }};
751  return result;
752 }
753 
754 const osl::CArray<int,2> osl::eval::ml::
755 King25EmptySquareNoEffectEnding::eval(const NumEffectState &state)
756 {
757  CArray<int, 2> result = {{ evalOne<BLACK>(state, table), evalOne<WHITE>(state, table) }};
758  return result;
759 }
760 
761 
762 
763 template <int Stage>
766 
767 template <int Stage>
768 void osl::eval::ml::
770 {
771  for (size_t i = 0; i < weights.dimension(); ++i)
772  {
773  table[i] = weights.value(i);
774  }
775 }
776 
777 template <int Stage>
778 template <osl::Player Defense>
781  const NumEffectState &state,
782  Square target)
783 {
784  if (!state.hasEffectAt(alt(Defense), target))
785  {
786  return static_cast<EffectState>(std::min(2, state.countEffect(Defense, target)));
787  }
788  const int diff = state.countEffect(Defense, target) -
789  state.countEffect(alt(Defense), target);
790  return static_cast<EffectState>(std::max(-2, std::min(2, diff)) + ATTACK_DIFF_0);
791 }
792 
793 template <int Stage>
794 template <osl::Player Defense>
796  const NumEffectState &state, Square king,
797  Square target)
798 {
799  const Piece piece = state.pieceAt(target);
800  // [0, 2]
801  const int rel_x = std::abs(king.x() - target.x());
802  // [-2, +2]
803  const int rel_y = (target.y() - king.y()) * (Defense == BLACK ? 1 : -1);
804  int piece_owner;
805  if (piece.isEmpty())
806  piece_owner = 0;
807  else if (piece.owner() == Defense)
808  piece_owner = 1;
809  else
810  piece_owner = 2;
811 
812  int val = rel_y + 2 + rel_x * 5 +
813  effectState<Defense>(state, target) * 5 * 3 +
814  piece_owner * 5 * 3 * 8;
815  return val;
816 }
817 
818 template <int Stage>
819 template <osl::Player Defense>
821  const NumEffectState &state)
822 {
823  int result = 0;
824  const Square king = state.kingSquare<Defense>();
825  const int min_x = std::max(1, king.x() - 2);
826  const int max_x = std::min(9, king.x() + 2);
827  const int min_y = std::max(1, king.y() - 2);
828  const int max_y = std::min(9, king.y() + 2);
829  for (int x = min_x; x <= max_x; ++x)
830  {
831  for (int y = min_y; y <= max_y; ++y)
832  {
833  Square target(x, y);
834  result += table[index<Defense>(state, king, target)];
835  }
836  }
837  if (Defense == BLACK)
838  return result;
839  else
840  return -result;
841 }
842 
843 template <int Stage>
844 int osl::eval::ml::
845 King25EffectEach<Stage>::eval(const NumEffectState &state)
846 {
847  return evalOne<BLACK>(state) + evalOne<WHITE>(state);
848 }
849 
860 
861 void osl::eval::ml::
863 {
864  for (size_t i = 0; i < weights.dimension(); ++i)
865  {
866  King25EffectEachBoth::table[i][0] = weights.value(i);
867  }
868 }
869 
870 void osl::eval::ml::
872 {
873  for (size_t i = 0; i < weights.dimension(); ++i)
874  {
875  King25EffectEachBoth::table[i][1] = weights.value(i);
876  }
877 }
878 
879 void osl::eval::ml::
881 {
882  for (size_t i = 0; i < weights.dimension(); ++i)
883  {
884  King25EffectEachBoth::table[i][2] = weights.value(i);
885  }
886 }
887 
888 void osl::eval::ml::
890 {
891  for (size_t i = 0; i < weights.dimension(); ++i)
892  {
894  }
895 }
896 void osl::eval::ml::
898 {
899  for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
900  for(int x_diff_2=0;x_diff_2<5;x_diff_2++)
901  for(int es=0;es<8;es++)
902  for(int po=0;po<3;po++)
903  for(int king_x_1=0;king_x_1<5;king_x_1++){
904  int oldIndex=(rel_y_2+x_diff_2*5+es*5*5+po*5*5*8)*5+king_x_1;
905  int newIndex=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*king_x_1)));
906  for (int s=0; s<NStages; ++s)
907  King25EffectEachBoth::x_table[newIndex][s] = weights.value(oldIndex + X_DIM*s);
908  }
909  for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
910  for(int rel_x=0;rel_x<3;rel_x++)
911  for(int es=0;es<8;es++)
912  for(int po=0;po<3;po++)
913  for(int king_y_1=0;king_y_1<9;king_y_1++){
914  int oldIndex=(rel_y_2+rel_x*5+es*5*3+po*5*3*8)*9+king_y_1;
915  int newIndex=po+3*(es+8*(rel_y_2+5*(rel_x+3*king_y_1)));
916  for (int s=0; s<NStages; ++s)
917  King25EffectEachBoth::y_table[newIndex][s] = weights.value(oldIndex+ X_DIM * EvalStages + Y_DIM*s)+King25EffectEachBoth::table[oldIndex/9][s];
918  }
919  for(int d_effect=0;d_effect<16;d_effect++){
920  for(int a_effect=0;a_effect<16;a_effect++){
921  if(a_effect==0){
922  King25EffectEachBoth::effect_state_table[a_effect*16+d_effect]=3*(std::min(2, d_effect));
923  }
924  else{
925  int diff=d_effect-a_effect;
926  King25EffectEachBoth::effect_state_table[a_effect*16+d_effect]=
927  3*(std::max(-2, std::min(2, diff)) + ATTACK_DIFF_0);
928  }
929  }
930  }
931 }
932 
933 void osl::eval::ml::
935 {
936  for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
937  for(int x_diff_2=0;x_diff_2<5;x_diff_2++){
938  int rel_x=std::abs(x_diff_2-2);
939  for(int es=0;es<8;es++)
940  for(int po=0;po<3;po++)
941  for(int king_x_1=0;king_x_1<5;king_x_1++)
942  for (int king_y_1=0;king_y_1<9;king_y_1++) {
943  int oldIndex=((rel_y_2+x_diff_2*5+es*5*5+po*5*5*8)*9+king_y_1)*5 + king_x_1;
944  int newIndexX=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*king_x_1)));
945  int newIndexY=po+3*(es+8*(rel_y_2+5*(rel_x+3*king_y_1)));
946  int newIndex=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*(king_x_1+5*king_y_1))));
947  for (int s=0; s<NStages; ++s)
948  King25EffectEachBoth::xy_table[newIndex][s] = weights.value(oldIndex + ONE_DIM*s)+King25EffectEachBoth::x_table[newIndexX][s]+King25EffectEachBoth::y_table[newIndexY][s];
949  }
950  }
951 }
952 
953 template <osl::Player Defense>
954 int
956  const NumEffectState &state, Square target)
957 {
958  NumBitmapEffect effect=state.effectSetAt(target);
959  const int d_effect=effect.countEffect(Defense);
960  const int a_effect=effect.countEffect(PlayerTraits<Defense>::opponent);
961  return effect_state_table[a_effect*16+d_effect];
962 }
963 
964 template <osl::Player Defense>
966  const NumEffectState &state,
967  Square target, int &index_xy,
968  int rel_y, int king_x, int king_y, int x_diff)
969 {
970  const Piece piece = state.pieceAt(target);
971  // piece_owner: 0 - empty, 1 - defense, 2 - attack
972  int piece_owner;
973  PtypeO ptypeO=piece.ptypeO();
974  if(Defense==BLACK){
975 #ifdef __INTEL_COMPILER
976  piece_owner = (unsigned int)((int)(ptypeO)>>30);
977  piece_owner &= 0x2;
978  piece_owner |= (ptypeO+14)>>4;
979 #else
980  piece_owner=((ptypeO+14)>>4)|(((unsigned int)ptypeO>>30)&0x2);
981 #endif
982  }
983  else{
984  piece_owner=(((ptypeO+14)>>3)&0x2)|((unsigned int)ptypeO>>31);
985  }
986  assert(piece_owner >= 0 && piece_owner < 3);
987  int effect_state_index = effectStateIndex3<Defense>(state, target);
988 
989  index_xy=piece_owner+effect_state_index+3*(8*((rel_y+2)+5*((x_diff+2)+5*(king_x-1+5*(king_y-1)))));
990 }
991 
992 template <osl::Player Defense>
994  const NumEffectState &state, MultiInt &out)
995 {
996  out.clear();
997  const Square king = state.kingSquare<Defense>();
998  const int min_dx = std::max(1, king.x() - 2)-king.x();
999  const int max_dx = std::min(9, king.x() + 2)-king.x();
1000  const int min_dy = std::max(1, king.y() - 2)-king.y();
1001  const int max_dy = std::min(9, king.y() + 2)-king.y();
1002  const int king_x = (king.x() > 5 ? 10 - king.x() : king.x());
1003  const int king_y = (Defense == BLACK ? king.y() : 10 - king.y());
1004  if ((Defense == BLACK && king.x() >= 6) ||
1005  (Defense == WHITE && king.x() >= 5)){
1006  for (int dx = min_dx; dx <= max_dx; ++dx)
1007  {
1008  // [0, 2]
1009  // const int rel_x = std::abs(dx);
1010  // [-2, 2]
1011  int x_diff = dx;
1012  for (int dy = min_dy; dy <= max_dy; ++dy)
1013  {
1014  const Square target(king.x()+dx, king.y()+dy);
1015  // [-2, +2]
1016  const int rel_y = dy * (Defense == BLACK ? 1 : -1);
1017  int index_xy;
1018  index<Defense>(state, target, index_xy,
1019  rel_y,king_x,king_y,x_diff);
1020  out += xy_table[index_xy];
1021  }
1022  }
1023  }
1024  else {
1025  for (int dx = min_dx; dx <= max_dx; ++dx)
1026  {
1027  // [0, 2]
1028  // const int rel_x = std::abs(dx);
1029  // [-2, 2]
1030  int x_diff = -dx;
1031  for (int dy = min_dy; dy <= max_dy; ++dy)
1032  {
1033  const Square target(king.x()+dx, king.y()+dy);
1034  // [-2, +2]
1035  const int rel_y = dy * (Defense == BLACK ? 1 : -1);
1036  int index_xy;
1037  index<Defense>(state, target, index_xy,
1038  rel_y,king_x,king_y,x_diff);
1039  out += xy_table[index_xy];
1040  }
1041  }
1042  }
1043  if (Defense != BLACK)
1044  {
1045  out = -out;
1046  }
1047 }
1048 
1049 void osl::eval::ml::
1050 King25EffectEachBoth::eval(const NumEffectState &state,
1051  MultiIntPair &out)
1052 {
1053  evalOne<BLACK>(state, out[BLACK]);
1054  evalOne<WHITE>(state, out[WHITE]);
1055 }
1056 
1057 void
1059  const NumEffectState &state, Move last_move,
1060  MultiIntPair &values)
1061 {
1062  BoardMask mb = state.changedEffects(BLACK), mw = state.changedEffects(WHITE);
1063  mb.set(Square(last_move.to())); mb.set(Square(last_move.from()));
1064  mw.set(Square(last_move.to())); mw.set(Square(last_move.from()));
1065  const Square kb = state.kingSquare<BLACK>(), kw = state.kingSquare<WHITE>();
1066  const bool update_black = mb.anyInRange(Board_Mask_Table5x5.mask(kb)) ||
1067  mw.anyInRange(Board_Mask_Table5x5.mask(kb));
1068  const bool update_white = mw.anyInRange(Board_Mask_Table5x5.mask(kw)) ||
1069  mb.anyInRange(Board_Mask_Table5x5.mask(kw));
1070  if (update_black)
1071  {
1072  evalOne<BLACK>(state, values[BLACK]);
1073  }
1074  if (update_white)
1075  {
1076  evalOne<WHITE>(state, values[WHITE]);
1077  }
1078 }
1079 
1080 
1081 template <bool Opening>
1083 
1084 template <bool Opening>
1085 void osl::eval::ml::
1087 {
1088  for (size_t i = 0; i < weights.dimension(); ++i)
1089  {
1090  table[i] = weights.value(i);
1091  }
1092 }
1093 
1094 template <bool Opening>
1095 template <osl::Player player>
1097  Square target)
1098 {
1099  int x, target_x;
1100  if ((player == BLACK && king.x() >= 6) ||
1101  (player == WHITE && king.x() >= 5))
1102  {
1103  x = 10 - king.x();
1104  target_x = 10 - target.x();
1105  }
1106  else
1107  {
1108  x = king.x();
1109  target_x = target.x();
1110  }
1111  const int y = (player == BLACK ? king.y() : 10 - king.y());
1112  const int target_y = (player == BLACK ? target.y() : 10 - target.y());
1113 
1114  return target_y - y + 2 + (target_x - x + 2 ) * 5 + (y - 1) * 5 * 5
1115  + (x - 1) * 5 * 5 * 9;
1116 }
1117 
1118 template <bool Opening>
1119 template <osl::Player Defense>
1121  const osl::state::NumEffectState &state)
1122 {
1123  int result = 0;
1124  const Square king = state.kingSquare<Defense>();
1125  const int min_x = std::max(1, king.x() - 2);
1126  const int max_x = std::min(9, king.x() + 2);
1127  const int min_y = std::max(1, king.y() - 2);
1128  const int max_y = std::min(9, king.y() + 2);
1129  for (int x = min_x; x <= max_x; ++x)
1130  {
1131  for (int y = min_y; y <= max_y; ++y)
1132  {
1133  Square target(x, y);
1134  if (target.isOnBoard() && state.pieceAt(target).isEmpty())
1135  {
1136  result += table[index<Defense>(king, target)];
1137  }
1138  }
1139  }
1140  if (Defense == BLACK)
1141  return result;
1142  else
1143  return -result;
1144 }
1145 
1146 template <bool Opening>
1148  const osl::state::NumEffectState &state)
1149 {
1150  return evalOne<BLACK>(state) + evalOne<WHITE>(state);
1151 }
1152 
1153 template <bool Opening>
1155  const osl::state::NumEffectState &state, osl::Move moved,
1156  int last_value)
1157 {
1158  if (moved.ptype() == osl::KING)
1159  {
1160  return eval(state);
1161  }
1162  const osl::Square self_king = state.kingSquare(moved.player());
1163  const osl::Square opp_king = state.kingSquare(alt(moved.player()));
1164  int result = last_value;
1165 
1166  if (!moved.isDrop())
1167  {
1168  const Square from = moved.from();
1169  if (std::abs(self_king.x() - from.x()) <= 2 &&
1170  std::abs(self_king.y() - from.y()) <= 2)
1171  {
1172  result += table[index(self_king, moved.from(), moved.player())] *
1173  (moved.player() == BLACK ? 1 : -1);
1174  }
1175 
1176  if (std::abs(opp_king.x() - from.x()) <= 2 &&
1177  std::abs(opp_king.y() - from.y()) <= 2)
1178  {
1179  result -= table[index(opp_king, from, alt(moved.player()))] *
1180  (moved.player() == BLACK ? 1 : -1);
1181  }
1182  }
1183 
1184  Ptype captured = moved.capturePtype();
1185  if (captured == PTYPE_EMPTY)
1186  {
1187  const Square to = moved.to();
1188  if (std::abs(self_king.x() - to.x()) <= 2 &&
1189  std::abs(self_king.y() - to.y()) <= 2)
1190  {
1191  result -= table[index(self_king, to, moved.player())] *
1192  (moved.player() == BLACK ? 1 : -1);
1193  }
1194  if (std::abs(opp_king.x() - to.x()) <= 2 &&
1195  std::abs(opp_king.y() - to.y()) <= 2)
1196  {
1197  result += table[index(opp_king, to, alt(moved.player()))] *
1198  (moved.player() == BLACK ? 1 : -1);
1199  }
1200  }
1201  return result;
1202 
1203 }
1204 
1205 osl::CArray<MultiInt, 3072> osl::eval::ml::King3Pieces::table;
1206 osl::CArray<MultiInt, 15360> osl::eval::ml::King3Pieces::x_table;
1207 osl::CArray<MultiInt, 27648> osl::eval::ml::King3Pieces::y_table;
1208 
1210 {
1211  for (int i = 0; i < ONE_DIM; ++i)
1212  {
1213  for (int s=0; s<NStages; ++s)
1214  table[i][s] = weights.value(i + ONE_DIM*s);
1215  }
1216 }
1217 
1219 {
1220  for (int i = 0; i < X_DIM; ++i)
1221  {
1222  for (int s=0; s<NStages; ++s)
1223  King3Pieces::x_table[i][s] = weights.value(i + ONE_DIM*s);
1224  }
1225  for (int i = 0; i < Y_DIM; ++i)
1226  {
1227  for (int s=0; s<NStages; ++s)
1228  King3Pieces::y_table[i][s] = weights.value(i + ONE_DIM*s + X_DIM);
1229  }
1230 }
1231 
1232 template <osl::Player King>
1233 void osl::eval::ml::King3Pieces::evalOne(const NumEffectState &state,
1234  MultiInt &result)
1235 {
1236  const Square king = state.kingSquare<King>();
1237  const int vertical_index =
1238  index<King, VERTICAL>(
1239  state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
1240  state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
1241  const int vertical_index_x =
1242  indexX<King, VERTICAL>(
1243  king,
1244  state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
1245  state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
1246  const int vertical_index_y =
1247  indexY<King, VERTICAL>(
1248  king,
1249  state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
1250  state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
1251  const int horizontal_index =
1252  index<King, HORIZONTAL>(
1253  state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
1254  state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
1255  const int horizontal_index_x =
1256  indexX<King, HORIZONTAL>(
1257  king,
1258  state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
1259  state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
1260  const int horizontal_index_y =
1261  indexY<King, HORIZONTAL>(
1262  king,
1263  state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
1264  state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
1265  const int diagonal_index1 =
1266  index<King, DIAGONAL>(
1267  state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
1268  state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
1269  const int diagonal_index2 =
1270  index<King, DIAGONAL>(
1271  state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
1272  state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
1273  const int diagonal_index1_x =
1274  indexX<King, DIAGONAL>(
1275  king,
1276  state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
1277  state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
1278  const int diagonal_index2_x=
1279  indexX<King, DIAGONAL>(
1280  king,
1281  state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
1282  state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
1283  const int diagonal_index1_y =
1284  indexY<King, DIAGONAL>(
1285  king,
1286  state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
1287  state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
1288  const int diagonal_index2_y =
1289  indexY<King, DIAGONAL>(
1290  king,
1291  state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
1292  state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
1293  const MultiInt v = value(vertical_index, horizontal_index,
1294  diagonal_index1, diagonal_index2,
1295  vertical_index_x, horizontal_index_x,
1296  diagonal_index1_x, diagonal_index2_x,
1297  vertical_index_y , horizontal_index_y,
1298  diagonal_index1_y, diagonal_index2_y);
1299  if (King == BLACK)
1300  {
1301  result += v;
1302  }
1303  else
1304  {
1305  result -= v;
1306  }
1307 }
1308 
1309 MultiInt
1310 osl::eval::ml::King3Pieces::eval(const NumEffectState &state)
1311 {
1312  MultiInt result;
1313  evalOne<BLACK>(state, result);
1314  evalOne<WHITE>(state, result);
1315  return result;
1316 }
1317 
1318 MultiInt
1320  const NumEffectState &state,
1321  Move last_move,
1322  MultiInt &last_value)
1323 {
1324  const CArray<Square,2> kings = {{
1325  state.kingSquare(BLACK),
1326  state.kingSquare(WHITE),
1327  }};
1328  if ((std::abs(last_move.to().x() - kings[0].x()) <= 1 &&
1329  std::abs(last_move.to().y() - kings[0].y()) <= 1) ||
1330  (std::abs(last_move.to().x() - kings[1].x()) <= 1 &&
1331  std::abs(last_move.to().y() - kings[1].y()) <= 1))
1332  return eval(state);
1333  if (!last_move.isDrop())
1334  {
1335  if ((std::abs(last_move.from().x() - kings[0].x()) <= 1 &&
1336  std::abs(last_move.from().y() - kings[0].y()) <= 1) ||
1337  (std::abs(last_move.from().x() - kings[1].x()) <= 1 &&
1338  std::abs(last_move.from().y() - kings[1].y()) <= 1))
1339  return eval(state);
1340  }
1341  return last_value;
1342 }
1343 
1344 
1345 
1348 
1351 
1352 
1357 
1359 {
1360  static CArray<MultiInt, 3240> old_table;
1361  for (int i = 0; i < ONE_DIM; ++i)
1362  {
1363  for (int s=0; s<NStages; ++s)
1364  old_table[i][s] = weights.value(i + ONE_DIM*s);
1365  }
1366  for(int king_x=0;king_x<5;king_x++)
1367  for(int king_y=0;king_y<9;king_y++)
1368  for(int dir=0;dir<8;dir++)
1369  for(int mobility=0;mobility<9;mobility++){
1370  int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
1371  int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
1372  for (int s=0; s<NStages; ++s)
1373  table[newIndex][s]=old_table[oldIndex][s];
1374  }
1375 }
1376 
1377 void osl::eval::ml::
1379 {
1380  static CArray<MultiInt, 3240> old_table;
1381  for (int i = 0; i < ONE_DIM; ++i)
1382  {
1383  for (int s=0; s<NStages; ++s)
1384  old_table[i][s] = weights.value(i + ONE_DIM*s);
1385  }
1386  for(int king_x=0;king_x<5;king_x++)
1387  for(int king_y=0;king_y<9;king_y++)
1388  for(int dir=0;dir<8;dir++)
1389  for(int mobility=0;mobility<9;mobility++){
1390  int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
1391  int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
1392  for (int s=0; s<NStages; ++s)
1393  KingMobility::rook_table[newIndex][s]=old_table[oldIndex][s];
1394  }
1395 }
1396 
1397 void osl::eval::ml::
1399 {
1400  static CArray<MultiInt, 3240> old_table;
1401  for (int i = 0; i < ONE_DIM; ++i)
1402  {
1403  for (int s=0; s<NStages; ++s)
1404  old_table[i][s] = weights.value(i + ONE_DIM*s);
1405  }
1406  for(int king_x=0;king_x<5;king_x++)
1407  for(int king_y=0;king_y<9;king_y++)
1408  for(int dir=0;dir<8;dir++)
1409  for(int mobility=0;mobility<9;mobility++){
1410  int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
1411  int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
1412  for (int s=0; s<NStages; ++s)
1413  KingMobility::bishop_table[newIndex][s]=old_table[oldIndex][s];
1414  }
1415  for(int i=0;i<3240;i++){
1419  KingMobility::bishop_table[i]+=KingMobility::table[i];
1420  }
1421 }
1422 
1423 template <osl::Player P>
1425 KingMobility::evalOne(const NumEffectState &state)
1426 {
1427  MultiInt result;
1428  const Square king = state.kingSquare<P>();
1429  const int king_x = (king.x() > 5 ? 10 - king.x() : king.x()) - 1;
1430  const int king_y = (P == BLACK ? king.y() : 10 - king.y()) - 1;
1431  int indexBase=9*8*(king_y+9*king_x);
1432  if(P==BLACK){
1433  if (state.hasPieceOnStand<ROOK>(alt(P)))
1434  {
1435  if(state.hasPieceOnStand<BISHOP>(alt(P))){
1436  result =
1437  rook_bishop_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1438  rook_bishop_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1439  rook_bishop_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1440  rook_bishop_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1441  rook_bishop_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1442  rook_bishop_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1443  rook_bishop_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1444  rook_bishop_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
1445  }
1446  else{
1447  result =
1448  rook_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1449  rook_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1450  rook_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1451  rook_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1452  rook_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1453  rook_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1454  rook_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1455  rook_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
1456  }
1457  }
1458  else if(state.hasPieceOnStand<BISHOP>(alt(P))){
1459  result =
1460  bishop_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1461  bishop_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1462  bishop_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1463  bishop_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1464  bishop_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1465  bishop_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1466  bishop_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1467  bishop_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
1468  }
1469  else{
1470  result =
1471  table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1472  table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1473  table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1474  table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1475  table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1476  table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1477  table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1478  table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
1479  }
1480  }
1481  else{
1482  if (state.hasPieceOnStand<ROOK>(alt(P)))
1483  {
1484  if(state.hasPieceOnStand<BISHOP>(alt(P))){
1485  result = -(
1486  rook_bishop_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1487  rook_bishop_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1488  rook_bishop_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1489  rook_bishop_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1490  rook_bishop_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1491  rook_bishop_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1492  rook_bishop_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1493  rook_bishop_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
1494  }
1495  else{
1496  result = -(
1497  rook_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1498  rook_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1499  rook_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1500  rook_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1501  rook_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1502  rook_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1503  rook_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1504  rook_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
1505  }
1506  }
1507  else if(state.hasPieceOnStand<BISHOP>(alt(P))){
1508  result = -(
1509  bishop_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1510  bishop_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1511  bishop_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1512  bishop_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1513  bishop_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1514  bishop_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1515  bishop_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1516  bishop_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
1517  }
1518  else{
1519  result = -(
1520  table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
1521  table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
1522  table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
1523  table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
1524  table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
1525  table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
1526  table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
1527  table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
1528  }
1529  }
1530  return result;
1531 }
1532 
1534 KingMobility::eval(const NumEffectState &state)
1535 {
1536  MultiInt result = evalOne<BLACK>(state) + evalOne<WHITE>(state);
1537  return result;
1538 }
1539 
1540 
1542 
1544 {
1545  CArray<MultiInt, 2925> old_table;
1546  for (int i = 0; i < ONE_DIM; ++i)
1547  {
1548  for (int s=0; s<NStages; ++s)
1549  old_table[i][s] = weights.value(i + ONE_DIM*s);
1550  }
1551  for(int king_x=0;king_x<5;king_x++)
1552  for(int king_y=0;king_y<9;king_y++)
1553  for(int mobility=0;mobility<=32;mobility++){
1554  int oldIndex=king_x+5*(king_y+9*(mobility+8));
1555  int newIndex=mobility+33*(king_y+9*king_x);
1556  for (int s=0; s<NStages; ++s)
1557  table[newIndex]=old_table[oldIndex];
1558  }
1559 }
1560 
1561 template <osl::Player P>
1563 KingMobilitySum::evalOne(const NumEffectState &state)
1564 {
1565  MultiInt result;
1566  const Square king = state.kingSquare<P>();
1567  int sum=state.kingMobilityAbs(P, UL).y()+state.kingMobilityAbs(P, U).y()+
1568  state.kingMobilityAbs(P, UR).y()+state.kingMobilityAbs(P, R).x()-
1569  state.kingMobilityAbs(P, DL).y()-state.kingMobilityAbs(P, D).y()-
1570  state.kingMobilityAbs(P, DR).y()-state.kingMobilityAbs(P, L).x();
1571  const int king_x = (king.x() > 5 ? 10 - king.x() : king.x()) - 1;
1572  const int king_y = (P == BLACK ? king.y() : 10 - king.y()) - 1;
1573  int mobility=sum-8;
1574  result = table[mobility+33*(king_y+9*king_x)];
1575  if (P == BLACK)
1576  {
1577  return result;
1578  }
1579  else
1580  {
1581  return -result;
1582  }
1583 }
1584 
1586 KingMobilitySum::eval(const NumEffectState &state)
1587 {
1588  MultiInt result = evalOne<BLACK>(state) + evalOne<WHITE>(state);
1589  return result;
1590 }
1591 
1592 
1599 
1601 {
1602  for (int i = 0; i < ONE_DIM; ++i)
1603  {
1604  for (int s=0; s<NStages; ++s)
1605  table[i][s] = weights.value(i + ONE_DIM*s);
1606  }
1607 }
1608 
1610 {
1611  for (int i = 0; i < ONE_DIM; ++i)
1612  {
1613  for (int s=0; s<NStages; ++s)
1614  King25BothSide::x_table[i][s] = weights.value(i + ONE_DIM*s);
1615  }
1616 }
1617 
1619 {
1620  for (int i = 0; i < ONE_DIM; ++i)
1621  {
1622  for (int s=0; s<NStages; ++s)
1623  King25BothSide::y_table[i][s] = weights.value(i + ONE_DIM*s);
1624  }
1625  for(int king_y=1;king_y<=9;king_y++)
1626  for(int effect1=0;effect1<32;effect1++)
1627  for(int effect2=0;effect2<32;effect2++)
1628  for(int i=0;i<8;i++){
1629  int index0=effect1 + 32 * (effect2 + 32 * i);
1630  int index1=king_y - 1 + 9 *(effect1 + 32 * (effect2 + 32 * i));
1632  }
1633 }
1634 
1635 template<osl::Player P>
1637 King25BothSide::evalOne(const NumEffectState &state,
1638  const CArray<int, 5> &effects)
1639 {
1640  const Square king=state.kingSquare<P>();
1641  const int king_y = (P==BLACK ? king.y() : 10 - king.y());
1642  const int king_x = (king.x() >= 6 ? 10 - king.x() : king.x());
1643  if ((P== BLACK && king.x() > 5) || (P==WHITE && king.x() < 5)){
1644  return
1645  x_table[indexX(king_x,effects[2],effects[0],(2*3)+1)]+ // (0,2)
1646  y_table[indexY(king_y,effects[0],effects[2],(0*3)+0)]+
1647  x_table[indexX(king_x,effects[3],effects[0],(1*3)+2)]+ // (0,3)
1648  y_table[indexY(king_y,effects[0],effects[3],(0*3)+1)]+
1649  x_table[indexX(king_x,effects[4],effects[0],(0*3)+2)]+ // (0,4)
1650  y_table[indexY(king_y,effects[0],effects[4],(0*3)+2)]+
1651  x_table[indexX(king_x,effects[2],effects[1],(2*3)+0)]+ // (1,2)
1652  y_table[indexY(king_y,effects[1],effects[2],(1*3)+0)]+
1653  x_table[indexX(king_x,effects[3],effects[1],(1*3)+1)]+ // (1,3)
1654  y_table[indexY(king_y,effects[1],effects[3],(1*3)+1)]+
1655  x_table[indexX(king_x,effects[4],effects[1],(0*3)+1)]+ // (1,4)
1656  y_table[indexY(king_y,effects[1],effects[4],(1*3)+2)]+
1657  x_table[indexX(king_x,effects[3],effects[2],(1*3)+0)]+ // (2,3)
1658  y_table[indexY(king_y,effects[2],effects[3],(2*3)+0)]+
1659  x_table[indexX(king_x,effects[4],effects[2],(0*3)+0)]+ // (2,4)
1660  y_table[indexY(king_y,effects[2],effects[4],(2*3)+1)];
1661  }
1662  else{
1663  return
1664  x_table[indexX(king_x,effects[0],effects[2],(0*3)+0)]+ // (0,2)
1665  y_table[indexY(king_y,effects[0],effects[2],(0*3)+0)]+
1666  x_table[indexX(king_x,effects[0],effects[3],(0*3)+1)]+ // (0,3)
1667  y_table[indexY(king_y,effects[0],effects[3],(0*3)+1)]+
1668  x_table[indexX(king_x,effects[0],effects[4],(0*3)+2)]+ // (0,4)
1669  y_table[indexY(king_y,effects[0],effects[4],(0*3)+2)]+
1670  x_table[indexX(king_x,effects[1],effects[2],(1*3)+0)]+ // (1,2)
1671  y_table[indexY(king_y,effects[1],effects[2],(1*3)+0)]+
1672  x_table[indexX(king_x,effects[1],effects[3],(1*3)+1)]+ // (1,3)
1673  y_table[indexY(king_y,effects[1],effects[3],(1*3)+1)]+
1674  x_table[indexX(king_x,effects[1],effects[4],(1*3)+2)]+ // (1,4)
1675  y_table[indexY(king_y,effects[1],effects[4],(1*3)+2)]+
1676  x_table[indexX(king_x,effects[2],effects[3],(2*3)+0)]+ // (2,3)
1677  y_table[indexY(king_y,effects[2],effects[3],(2*3)+0)]+
1678  x_table[indexX(king_x,effects[2],effects[4],(2*3)+1)]+ // (2,4)
1679  y_table[indexY(king_y,effects[2],effects[4],(2*3)+1)];
1680  }
1681 }
1682 
1684 King25BothSide::eval(const NumEffectState &state,
1685  const CArray<int, 5> &black,
1686  const CArray<int, 5> &white)
1687 {
1688  return evalOne<BLACK>(state,black)-evalOne<WHITE>(state,white);
1689 }
1690 
1695 
1697 {
1698  for (int i = 0; i < ONE_DIM; ++i)
1699  {
1700  for (int s=0; s<NStages; ++s)
1701  table[i][s] = weights.value(i + ONE_DIM*s);
1702  }
1703 }
1704 
1706 {
1707  for (int i = 0; i < ONE_DIM; ++i)
1708  {
1709  for (int s=0; s<NStages; ++s)
1710  King25Effect3::y_table[i][s] = weights.value(i + ONE_DIM*s);
1711  }
1712 }
1713 
1714 template <osl::Player Attack>
1716 King25Effect3::evalOne(const NumEffectState &state,
1717  PieceMask king25)
1718 {
1719  king25 = king25 & state.piecesOnBoard(Attack);
1720  const PieceMask promoted_mask = (king25 & state.promotedPieces());
1721  const bool with_knight =
1722  (king25 & ~state.promotedPieces()).template selectBit<KNIGHT>().any();
1723  king25.clearBit<KNIGHT>();
1724  king25.clearBit<LANCE>();
1725  king25.clearBit<PAWN>();
1726  king25 = king25 | promoted_mask;
1727  const int piece_count = std::min(9, king25.countBit());
1728  const int stand_count = std::min(9,
1729  state.countPiecesOnStand<ROOK>(Attack) +
1730  state.countPiecesOnStand<BISHOP>(Attack) +
1731  state.countPiecesOnStand<GOLD>(Attack) +
1732  state.countPiecesOnStand<SILVER>(Attack));
1733  const bool stand_with_knight = state.hasPieceOnStand<KNIGHT>(Attack);
1734  const Player Defense = PlayerTraits<Attack>::opponent;
1735  PieceMask attacked =
1736  state.effectedMask(Attack) & state.piecesOnBoard(Defense);
1737  attacked.clearBit<KNIGHT>();
1738  attacked.clearBit<LANCE>();
1739  attacked.clearBit<PAWN>();
1740  PieceMask attacking;
1741  while (attacked.any())
1742  {
1743  const Piece piece = state.pieceOf(attacked.takeOneBit());
1744  attacking = attacking | state.effectSetAt(piece.square());
1745  }
1746  attacking = (attacking & state.piecesOnBoard(Attack) & ~king25);
1747  const int attacked_count = std::min(5, attacking.countBit());
1748  if (Attack == BLACK)
1749  {
1750  return table[index(piece_count, with_knight,
1751  stand_count, stand_with_knight, attacked_count)] +
1752  y_table[indexY(piece_count, with_knight,
1753  stand_count, stand_with_knight, attacked_count,
1754  state.kingSquare<WHITE>().y())];
1755  }
1756  else
1757  {
1758  return -(table[index(piece_count, with_knight,
1759  stand_count, stand_with_knight, attacked_count)] +
1760  y_table[indexY(piece_count, with_knight,
1761  stand_count, stand_with_knight, attacked_count,
1762  10 - state.kingSquare<BLACK>().y())]);
1763  }
1764 }
1765 
1767 King25Effect3::eval(const NumEffectState &state,
1768  const CArray<PieceMask, 2> &king25_mask)
1769 {
1770  return evalOne<BLACK>(state, king25_mask[WHITE]) +
1771  evalOne<WHITE>(state, king25_mask[BLACK]);
1772 }
1773 
1774 
1781 
1783 {
1784  for (int i = 0; i < ONE_DIM; ++i)
1785  {
1786  for (int s=0; s<NStages; ++s)
1787  table[i][s] = weights.value(i + ONE_DIM*s);
1788  }
1789 }
1790 
1792 {
1793  for (int i = 0; i < ONE_DIM; ++i)
1794  {
1795  for (int s=0; s<NStages; ++s)
1796  King25Mobility::x_table[i][s] = weights.value(i + ONE_DIM*s);
1797  }
1798 }
1799 
1801 {
1802  for (int i = 0; i < ONE_DIM; ++i)
1803  {
1804  for (int s=0; s<NStages; ++s)
1805  King25Mobility::y_table[i][s] = weights.value(i + ONE_DIM*s);
1806  }
1807 }
1808 
1810 King25Mobility::eval(const NumEffectState &state,
1811  const CArray<int, 5> &black,
1812  const CArray<int, 5> &white)
1813 {
1814  const CArray<Square,2> kings = {{
1815  state.kingSquare<BLACK>(),
1816  state.kingSquare<WHITE>(),
1817  }};
1818  MultiInt result;
1819  for (size_t i = 1; i < black.size(); ++i)
1820  {
1821  result += (table[index(black[i - 1], black[i], i - 1)] +
1822  x_table[indexX<BLACK>(kings[BLACK],
1823  black[i - 1], black[i], i - 1)] +
1824  y_table[indexY<BLACK>(kings[BLACK],
1825  black[i - 1], black[i], i - 1)]);
1826  result -= (table[index(white[i - 1], white[i], i - 1)] +
1827  x_table[indexX<WHITE>(kings[WHITE],
1828  white[i - 1], white[i], i - 1)] +
1829  y_table[indexY<WHITE>(kings[WHITE],
1830  white[i - 1], white[i], i - 1)]);
1831  }
1832  return result;
1833 }
1834 
1835 
1840 
1842 {
1843  for (int i = 0; i < ONE_DIM; ++i)
1844  {
1845  for (int s=0; s<NStages; ++s)
1846  table[i][s] = weights.value(i + ONE_DIM*s);
1847  }
1848 }
1849 
1851 {
1852  for (int i = 0; i < ONE_DIM; ++i)
1853  {
1854  for (int s=0; s<NStages; ++s)
1855  King25EffectCountCombination::y_table[i][s] = weights.value(i + ONE_DIM*s);
1856  }
1857 }
1858 
1859 template <osl::Player Attack>
1861 King25EffectCountCombination::evalOne(const NumEffectState &state,
1862  PieceMask king25)
1863 {
1864  const Player Defense = PlayerTraits<Attack>::opponent;
1865  PieceMask attack = king25 & state.piecesOnBoard(Attack);
1866  PieceMask defense =
1867  king25 & state.piecesOnBoard(Defense);
1868  const PieceMask attack_promoted_mask = (attack & state.promotedPieces());
1869  const PieceMask defense_promoted_mask = (defense & state.promotedPieces());
1870  attack.clearBit<KNIGHT>();
1871  attack.clearBit<LANCE>();
1872  attack.clearBit<PAWN>();
1873  attack = attack | attack_promoted_mask;
1874  defense.clearBit<KNIGHT>();
1875  defense.clearBit<LANCE>();
1876  defense.clearBit<PAWN>();
1877  defense = defense | defense_promoted_mask;
1878  const int attack_count = std::min(9,
1879  attack.countBit() +
1880  state.countPiecesOnStand<ROOK>(Attack) +
1881  state.countPiecesOnStand<BISHOP>(Attack) +
1882  state.countPiecesOnStand<GOLD>(Attack) +
1883  state.countPiecesOnStand<SILVER>(Attack));
1884  const int defense_count = std::min(9,
1885  defense.countBit() +
1886  state.countPiecesOnStand<ROOK>(Defense) +
1887  state.countPiecesOnStand<BISHOP>(Defense) +
1888  state.countPiecesOnStand<GOLD>(Defense) +
1889  state.countPiecesOnStand<SILVER>(Defense));
1890  const int y = (Attack == BLACK ? state.kingSquare<Defense>().y() :
1891  10 - state.kingSquare<Defense>().y());
1892  MultiInt result = table[attack_count + 10 * defense_count] +
1893  y_table[y - 1 + 9 * (attack_count + 10 * defense_count)];
1894  if (Attack == BLACK)
1895  return result;
1896  else
1897  return -result;
1898 }
1899 
1901 King25EffectCountCombination::eval(const NumEffectState &state,
1902  const CArray<PieceMask, 2> &king25_mask)
1903 {
1904  return evalOne<BLACK>(state, king25_mask[WHITE]) +
1905  evalOne<WHITE>(state, king25_mask[BLACK]);
1906 }
1907 
1908 
1909 osl::CArray<int, 18*81*(45*2)*3> osl::eval::ml::BishopExchangeSilverKing::table;
1910 void osl::eval::ml::
1912 {
1913  for (size_t i=0; i<weights.dimension(); ++i)
1914  table[i] = weights.value(i);
1915 }
1916 
1917 int osl::eval::ml::
1918 BishopExchangeSilverKing::eval(const NumEffectState &state)
1919 {
1920  if (state.promotedPieces().any())
1921  return 0;
1922  PieceMask stand_all = state.standMask(BLACK) | state.standMask(WHITE);
1923  stand_all.clearBit<BISHOP>();
1924  stand_all.clearBit<PAWN>();
1925  if (stand_all.any())
1926  return 0;
1927  if (state.nth<BISHOP>(0).owner() == state.nth<BISHOP>(1).owner())
1928  return 0;
1929  if (state.nth<BISHOP>(0).isOnBoard() != state.nth<BISHOP>(1).isOnBoard())
1930  return 0;
1931  int offset = 0;
1932  if (state.nth<BISHOP>(0).isOnBoard()) {
1933  offset += BISHOP_ONE_DIM;
1934  if (state.hasEffectByPiece(state.nth<BISHOP>(0),
1935  state.nth<BISHOP>(1).square()))
1936  offset += BISHOP_ONE_DIM;
1937  }
1938  return evalOne<BLACK>(state, offset) + evalOne<WHITE>(state, offset);
1939 }
1940 
1941 template <osl::Player KingOwner>
1942 int osl::eval::ml::
1943 BishopExchangeSilverKing::evalOne(const NumEffectState &state, int offset)
1944 {
1945  Square king = state.kingSquare(KingOwner);
1946  int king_index = indexKing(king.squareForBlack(alt(KingOwner))); // rotate if king is black
1947  if (king_index < 0)
1948  return 0;
1949  CArray<Piece,2> rook = {{
1950  state.nth<ROOK>(0), state.nth<ROOK>(1),
1951  }};
1952  if (rook[0].owner() == rook[1].owner())
1953  return 0;
1954  if (rook[0].owner() == KingOwner)
1955  std::swap(rook[0], rook[1]);
1956  int rook_index0 = indexKing(rook[0].square().squareForBlack(KingOwner)); // rotate if attaking rook is black
1957  if (rook_index0 < 0)
1958  return 0;
1959  int rook_index1 = indexKing(rook[1].square().squareForBlack(alt(KingOwner))); // rotate if defending rook is black
1960  if (rook_index1 < 0)
1961  return 0;
1962  FixedCapacityVector<Square, 4> silver;
1963  for (int i=0; i<state.nthLimit<SILVER>(); ++i) {
1964  Piece p = state.nth<SILVER>(i);
1965  assert(p.isOnBoard());
1966  if (p.owner() == KingOwner)
1967  continue;
1968  silver.push_back(p.square().squareForBlack(KingOwner)); // rotate if silver is black
1969  }
1970  if (silver.size() != 2 || silver[0].x() == silver[1].x())
1971  return 0;
1972  int silver_index
1973  = indexSilver((silver[0].x() > silver[1].x()) ? silver[0] : silver[1]);
1974  int index = offset + (king_index*81+silver_index)*90;
1975  return table[index + rook_index0] * playerToMul(KingOwner)
1976  + table[index + 45 + rook_index1] * playerToMul(KingOwner);
1977 }
1978 
1979 
1980 
1981 
1982 template <osl::Player KingOwner>
1983 int osl::eval::ml::
1984 EnterKingDefense::evalOne(const NumEffectState &state)
1985 {
1986  Square king = state.kingSquare(KingOwner);
1987  if (king.y() < 4 || king.y() > 6) // target: [4,6]
1988  return 0;
1989  CArray2d<int, 2, 2> count = {{{ 0 }}};
1990  for (int x=std::max(1, king.x()-2); x<=std::min(9, king.x()+2); ++x) {
1991  for (int y=king.y()-2*playerToMul(KingOwner); 1; y-=playerToMul(KingOwner)) {
1992  const Piece p = state.pieceAt(Square(x, y));
1993  if (p.isEdge())
1994  break;
1995  if (p.isEmpty())
1996  continue;
1997  count[p.owner() == KingOwner][p.ptype() == PAWN]++;
1998  }
1999  }
2000  const int c = king.squareForBlack(KingOwner).y() - 4;
2001  return table[c*(std::min(7, count[0][0]))] * playerToMul(KingOwner)
2002  + table[c*(8 +std::min(7, count[0][1]))] * playerToMul(KingOwner)
2003  + table[c*(16+std::min(7, count[1][0]))] * playerToMul(KingOwner)
2004  + table[c*(24+std::min(7, count[1][1]))] * playerToMul(KingOwner);
2005 }
2006 
2007 int osl::eval::ml::
2008 EnterKingDefense::eval(const NumEffectState &state)
2009 {
2010  return evalOne<BLACK>(state) + evalOne<WHITE>(state);
2011 }
2012 
2013 osl::CArray<int, (8+8+8+8)*3> osl::eval::ml::EnterKingDefense::table;
2014 void osl::eval::ml::
2016 {
2017  for (size_t i=0; i<weights.dimension(); ++i)
2018  table[i] = weights.value(i);
2019 }
2020 
2021 
2022 
2023 namespace osl
2024 {
2025  namespace eval
2026  {
2027  namespace ml
2028  {
2029  template MultiInt KingPieceRelative::
2030  evalWithUpdate<BLACK>(const NumEffectState &state,
2031  Move moved, MultiInt const& last_value);
2032  template MultiInt KingPieceRelative::
2033  evalWithUpdate<WHITE>(const NumEffectState &state,
2034  Move moved, MultiInt const& last_value);
2035 
2036  template class King25EffectEach<0>;
2037  template class King25EffectEach<1>;
2038  template class King25EffectEach<2>;
2039  template class King25EmptyAbs<true>;
2040  template class King25EmptyAbs<false>;
2041 
2042  template void King25EffectBoth::countEffectAndPiecesBoth<BLACK>(const NumEffectState&, PieceMask&, PieceMask&, int&, int&, int&, int&, int&, CArray<int, 5>&, CArray<int, 5>&);
2043  template void King25EffectBoth::countEffectAndPiecesBoth<WHITE>(const NumEffectState&, PieceMask&, PieceMask&, int&, int&, int&, int&, int&, CArray<int, 5>&, CArray<int, 5>&);
2044  }
2045  }
2046 }
2047 
2048 // ;;; Local Variables:
2049 // ;;; mode:c++
2050 // ;;; c-basic-offset:2
2051 // ;;; End: