My Project
minorPiece.cc
Go to the documentation of this file.
1 #include "osl/eval/minorPiece.h"
2 #include "osl/additionalEffect.h"
3 #include <iostream>
4 using osl::MultiInt;
5 
7 {
8  for (size_t i = 0; i < ONE_DIM; ++i)
9  {
10  for (int s=0; s<NStages; ++s)
11  PawnDropBoth::x_table[i][s] = weights.value(i+ONE_DIM*s);
12  }
13 }
14 ␌
37 
38 void osl::eval::ml::PawnDrop::setUp(const Weights &weights,int stage)
39 {
40  for (int i = 0; i < ONE_DIM; ++i)
41  {
42  PawnDropBoth::defense_table[i][stage] = weights.value(i);
43  PawnDropBoth::attack_table[i][stage] = weights.value(i + ONE_DIM);
44  }
45 }
46 
47 void osl::eval::ml::PawnDropY::setUp(const Weights &weights,int stage)
48 {
49  for (int i = 0; i < ONE_DIM; ++i)
50  {
51  PawnDropBoth::attack_y_table[i][stage] = weights.value(i);
52  PawnDropBoth::defense_y_table[i][stage] = weights.value(i + ONE_DIM);
53  }
54 }
55 
57 {
58  for (int i = 0; i < ONE_DIM; ++i)
59  {
60  for (int s=0; s<NStages; ++s)
61  PawnDropBoth::stand_table[i][s] = weights.value(i + ONE_DIM*s);
62  }
63 }
64 
66 {
67  for (int i = 0; i < ONE_DIM; ++i)
68  {
69  for (int s=0; s<NStages; ++s)
70  PawnDropBoth::x_stand_table[i][s] = weights.value(i + ONE_DIM*s);
71  }
72 }
74 {
75  for (int i = 0; i < ONE_DIM; ++i)
76  {
77  for (int s=0; s<NStages; ++s)
78  PawnDropBoth::y_stand_table[i][s] = weights.value(i + ONE_DIM*s);
79  }
80 }
81 
83 {
84  for (int i = 0; i < ONE_DIM; ++i)
85  {
86  for (int s=0; s<NStages; ++s)
87  PawnDropBoth::drop_non_drop_table[i][s] = weights.value(i + ONE_DIM*s);
88  }
89 }
90 
92 {
93  for (int i = 0; i < ONE_DIM; ++i)
94  {
95  for (int s=0; s<NStages; ++s)
96  PawnDropBoth::state_king_relative_table[i][s] = weights.value(i + ONE_DIM*s);
97  }
98 }
99 
101  const NumEffectState &state)
102 {
103  osl::MultiInt result;
104  CArray<Square, 2> kings = {{state.kingSquare<BLACK>(),
105  state.kingSquare<WHITE>()}};
106  CArray<Piece, 2> king_piece = {{state.kingPiece<BLACK>(),
107  state.kingPiece<WHITE>()}};
108  CArray<bool, 2> has_pawn = {{state.hasPieceOnStand<PAWN>(BLACK),
109  state.hasPieceOnStand<PAWN>(WHITE)}};
110  for (int x = 1; x <= 9; ++x)
111  {
112  const bool black_on_board = state.isPawnMaskSet<BLACK>(x);
113  const bool white_on_board = state.isPawnMaskSet<WHITE>(x);
114  if (!black_on_board)
115  {
116  const int attack_index = index(kings[WHITE], x);
117  const int defense_index = index(kings[BLACK], x);
118  const int attack_index_x =
119  indexX<true>(king_piece[WHITE], x);
120  const int defense_index_x =
121  indexX<false>(king_piece[BLACK], x);
122  const int attack_index_y = indexY<WHITE>(king_piece[WHITE], x);
123  const int defense_index_y = indexY<BLACK>(king_piece[BLACK], x);
124  result += value(attack_index, defense_index,
125  attack_index_y, defense_index_y,
126  attack_index_x, defense_index_x);
127  if (has_pawn[BLACK])
128  {
129  result += standValue(attack_index, defense_index,
130  attack_index_y, defense_index_y,
131  attack_index_x, defense_index_x);
132  }
133  }
134  if (!white_on_board)
135  {
136  const int attack_index = index(kings[BLACK], x);
137  const int defense_index = index(kings[WHITE], x);
138  const int attack_index_x =
139  indexX<true>(king_piece[BLACK], x);
140  const int defense_index_x =
141  indexX<false>(king_piece[WHITE], x);
142  const int attack_index_y = indexY<BLACK>(king_piece[BLACK], x);
143  const int defense_index_y = indexY<WHITE>(king_piece[WHITE], x);
144  result -= value(attack_index, defense_index,
145  attack_index_y, defense_index_y,
146  attack_index_x, defense_index_x);
147  if (has_pawn[WHITE])
148  {
149  result -= standValue(attack_index, defense_index,
150  attack_index_y, defense_index_y,
151  attack_index_x, defense_index_x);
152  }
153  }
154  const int index_x = (x > 5 ? 10 - x : x);
155  if (black_on_board && white_on_board)
156  {
157  result +=
158  state_king_relative_table[std::abs(kings[BLACK].x() - x) +
159  BOTH_ON_BOARD * 9];
160  result -=
161  state_king_relative_table[std::abs(kings[WHITE].x() - x) +
162  BOTH_ON_BOARD * 9];
163  }
164  else if (black_on_board && !white_on_board)
165  {
166  result += drop_non_drop_table[index_x - 1];
167  result -= drop_non_drop_table[index_x - 1 + 5];
168  result +=
169  state_king_relative_table[std::abs(kings[BLACK].x() - x) +
170  SELF_ON_BOARD * 9];
171  result -=
172  state_king_relative_table[std::abs(kings[WHITE].x() - x) +
173  OPP_ON_BOARD * 9];
174  }
175  else if (!black_on_board && white_on_board)
176  {
177  result += drop_non_drop_table[index_x - 1 + 5];
178  result -= drop_non_drop_table[index_x - 1];
179  result +=
180  state_king_relative_table[std::abs(kings[BLACK].x() - x) +
181  OPP_ON_BOARD * 9];
182  result -=
183  state_king_relative_table[std::abs(kings[WHITE].x() - x) +
184  SELF_ON_BOARD * 9];
185  }
186  else
187  {
188  result +=
189  state_king_relative_table[std::abs(kings[BLACK].x() - x) +
190  BOTH_ON_STAND * 9];
191  result -=
192  state_king_relative_table[std::abs(kings[WHITE].x() - x) +
193  BOTH_ON_STAND * 9];
194  }
195  }
196  return result;
197 }
198 
199 ␌
200 
202 
204 NoPawnOnStand::setUp(const Weights &weights,int stage)
205 {
206  weight[stage] = weights.value(0);
207 }
208 
209 ␌
210 
212 
214 PawnAdvance::setUp(const Weights &weights,int stage)
215 {
216  for (size_t i = 0; i < weights.dimension(); ++i) {
217  table[i][stage] = weights.value(i);
218  }
219 }
220 
222  const NumEffectState &state)
223 {
224  MultiInt result;
225  for (int i = PtypeTraits<PAWN>::indexMin;
226  i < PtypeTraits<PAWN>::indexLimit; ++i)
227  {
228  const Piece pawn = state.pieceOf(i);
229  if (pawn.isOnBoard() && !pawn.isPromoted() &&
230  cantAdvance(state, pawn))
231  {
232  if (pawn.owner() == BLACK)
233  result += table[index(BLACK, pawn.square())];
234  else
235  result -= table[index(WHITE, pawn.square())];
236  }
237  }
238  return result;
239 }
240 
241 template <osl::Player P> inline
243 PawnAdvanceAll::adjust(int index, MultiInt& values)
244 {
245  if(P==BLACK)
246  values += PawnAdvance::table[index];
247  else
248  values -= PawnAdvance::table[index];
249 }
250 
251 template <osl::Player P>
254  osl::Move moved, MultiInt& values)
255 {
256  assert(moved.player() == P);
257  if (moved.ptype() == PAWN)
258  {
259  if (cantAdvance(state, moved.ptypeO(), moved.to()))
260  {
261  adjust<P>(index(P, moved.to()), values);
262  return;
263  }
264  }
265  const Player Opponent = alt(P);
266  Ptype captured = moved.capturePtype();
267  if (captured == PAWN)
268  {
269  if (cantAdvance(state, moved.capturePtypeO(), moved.to()))
270  adjust<P>(index(Opponent, moved.to()), values);
271  }
272  else if (captured != PTYPE_EMPTY)
273  {
274  const Piece piece = state.pieceAt(
276  if (piece.isPlayerPtype(Opponent,PAWN))
277  adjust<P>(index(Opponent, piece.square()), values);
278  }
279  if (!moved.isDrop())
280  {
281  const Piece piece = state.pieceAt(
283  if (piece.isPlayerPtype(P,PAWN))
284  adjust<Opponent>(index(P, piece.square()), values);
285  }
286  {
287  const Piece piece = state.pieceAt(
289  if (piece.isPlayerPtype(P,PAWN))
290  adjust<P>(index(P, piece.square()), values);
291  }
292 }
293 
294 
295 ␌
300 
303 {
304  for (size_t i = 0; i < ONE_DIM; ++i)
305  {
306  for (int s=0; s<NStages; ++s)
307  head_table[i][s] = weights.value(i + ONE_DIM*s);
308  }
309 }
310 
313 {
314  MultiInt result;
315  CArray<Square, 2> kings = {{state.kingSquare<BLACK>(),
316  state.kingSquare<WHITE>()}};
317  for (int i = PtypeTraits<SILVER>::indexMin;
318  i < PtypeTraits<SILVER>::indexLimit; ++i)
319  {
320  const Piece silver = state.pieceOf(i);
321  if (!silver.isOnBoard() || silver.isPromoted()) continue;
322  if (silver.owner()==BLACK){
323  result += evalOne<BLACK>(state, silver, kings);
324  }
325  else{
326  result -= evalOne<WHITE>(state, silver, kings);
327  }
328  }
329  return result;
330 }
331 
332 template<osl::Player P>
333 inline
336  const osl::Piece silver)
337 {
338  assert(silver.isOnBoard() && !silver.isPromoted());
339  assert(silver.owner()==P);
340  if ((P == BLACK && silver.square().y() != 9) ||
341  (P == WHITE && silver.square().y() != 1))
342  {
344  Piece pdl = state.pieceAt(dl);
345  if (!pdl.canMoveOn<P>() ||
346  state.hasEffectAt(alt(P), dl))
347  {
349  Piece pdr = state.pieceAt(dr);
350  if (!pdr.canMoveOn<P>() ||
351  state.hasEffectAt(alt(P), dr))
352  {
353  return false;
354  }
355  }
356  }
357  return true;
358 }
359 
361 SilverRetreat::setUp(const Weights &weights, int stage)
362 {
363  for (size_t i = 0; i < weights.dimension(); ++i) {
364  retreat_table[i][stage] = weights.value(i);
365  }
366 }
367 
368 ␌
375 
378 {
379  for (size_t i = 0; i < ONE_DIM; ++i)
380  {
381  for (int s=0; s<NStages; ++s)
382  knight_table[i][s] = weights.value(i + ONE_DIM*s);
383  }
384 }
385 
387 GoldSideMove::setUp(const Weights &weights)
388 {
389  for (size_t i = 0; i < ONE_DIM; ++i)
390  {
391  for (int s=0; s<NStages; ++s)
392  side_table[i][s] = weights.value(i + ONE_DIM*s);
393  }
394 }
395 
398 {
399  MultiInt result;
400  CArray<Square, 2> kings = {{state.kingSquare<BLACK>(),
401  state.kingSquare<WHITE>()}};
402  for (int i = PtypeTraits<GOLD>::indexMin;
403  i < PtypeTraits<GOLD>::indexLimit; ++i)
404  {
405  const Piece gold = state.pieceOf(i);
406  if (!gold.isOnBoard())
407  continue;
408  if (gold.owner() == BLACK)
409  {
410  result += evalOne<BLACK>(state, gold, kings);
411  }
412  else
413  {
414  result -= evalOne<WHITE>(state, gold, kings);
415  }
416  }
417  return result;
418 }
419 
420 template<osl::Player P>
421 inline
424  const osl::Piece gold)
425 {
426  assert(gold.isOnBoard());
427  assert(P==gold.owner());
428 
429  if ((P == BLACK && gold.square().y() != 9) ||
430  (P == WHITE && gold.square().y() != 1))
431  {
433  if ((state.pieceAt(d).isOnBoardByOwner(P) ||
434  state.hasEffectAt(alt(P), d)))
435  {
436  return false;
437  }
438  }
439  return true;
440 }
441 
443 GoldRetreat::setUp(const Weights &weights,int stage)
444 {
445  for (size_t i = 0; i < weights.dimension(); ++i) {
446  retreat_table[i][stage] = weights.value(i);
447  }
448 }
449 
450 ␌
451 
453 
454 template<osl::Player P>
455 inline
458  const osl::Piece knight)
459 {
460  // knight が敵陣一段目にいないと仮定
461  // もしいる場合はSquare(1,1)のUURが駒台に衝突
462  assert(P==knight.owner());
464  const Piece puul = state.pieceAt(uul);
465  if (!puul.canMoveOn<P>())
466  {
468  const Piece puur = state.pieceAt(uur);
469  if (!puur.canMoveOn<P>())
470  return true;
471  }
472  return false;
473 }
474 
476 KnightAdvance::setUp(const Weights &weights,int stage)
477 {
478  for (size_t i = 0; i < weights.dimension(); ++i) {
479  table[i][stage] = weights.value(i);
480  }
481 }
482 
484  const NumEffectState &state)
485 {
486  MultiInt result;
487  for (int i = PtypeTraits<KNIGHT>::indexMin;
488  i < PtypeTraits<KNIGHT>::indexLimit; ++i)
489  {
490  const Piece knight = state.pieceOf(i);
491  if (!knight.isOnBoard() || knight.isPromoted()) continue;
492  if (knight.owner() == BLACK){
493  if(cantAdvance<BLACK>(state,knight))
494  result += table[index(BLACK, knight.square())];
495  }
496  else if(cantAdvance<WHITE>(state,knight)){
497  result -= table[index(WHITE, knight.square())];
498  }
499  }
500  return result;
501 }
502 ␌
503 
505 
507 AllGold::setUp(const Weights &weights,int stage)
508 {
509  weight[stage] = weights.value(0);
510 }
511 
512 ␌
513 
515 
517 PtypeY::setUp(const Weights &weights,int stage)
518 {
519  for (size_t i = 0; i < weights.dimension(); ++i)
520  {
521  table[i][stage] = weights.value(i);
522  }
523 }
524 
526 {
527  MultiInt result;
528  for (int i = 0; i < Piece::SIZE; ++i)
529  {
530  const Piece p = state.pieceOf(i);
531  if (!p.isOnBoard())
532  continue;
533  if (p.owner() == BLACK)
534  result += table[index(BLACK,p.ptype(),p.square())];
535  else
536  result -= table[index(WHITE,p.ptype(),p.square())];
537  }
538  return result;
539 }
540 
541 template<osl::Player P>
544  MultiInt const& last_value)
545 {
546  MultiInt result(last_value);
547 
548  if (!moved.isDrop())
549  {
550  if (P == BLACK)
551  result -= table[index(BLACK, moved.oldPtype(), moved.from())];
552  else
553  result += table[index(WHITE, moved.oldPtype(), moved.from())];
554  }
555  Ptype captured = moved.capturePtype();
556  if (captured != PTYPE_EMPTY)
557  {
558  const MultiInt weight =
559  table[index(alt(P), captured, moved.to())];
560  if (P == BLACK)
561  result += weight;
562  else
563  result -= weight;
564  }
565  {
566  if (P == BLACK)
567  result += table[index(BLACK, moved.ptype(), moved.to())];
568  else
569  result -= table[index(WHITE, moved.ptype(), moved.to())];
570  }
571 
572  return result;
573 }
574 
575 ␌
577 
579 PtypeX::setUp(const Weights &weights,int stage)
580 {
581  for (size_t i = 0; i < weights.dimension(); ++i)
582  {
583  table[i][stage] = weights.value(i);
584  }
585 }
586 
588 {
589  MultiInt result;
590  for (int i = 0; i < Piece::SIZE; ++i)
591  {
592  const Piece p = state.pieceOf(i);
593  if (!p.isOnBoard())
594  continue;
595  if (p.owner() == BLACK)
596  result += table[index(BLACK,p.ptype(),p.square())];
597  else
598  result -= table[index(WHITE,p.ptype(),p.square())];
599  }
600  return result;
601 }
602 
603 template<osl::Player P>
606  MultiInt const& last_value)
607 {
608  MultiInt result(last_value);
609 
610  if (!moved.isDrop())
611  {
612  if (P == BLACK)
613  result -= table[index(BLACK, moved.oldPtype(), moved.from())];
614  else
615  result += table[index(WHITE, moved.oldPtype(), moved.from())];
616  Ptype captured = moved.capturePtype();
617  if (captured != PTYPE_EMPTY)
618  {
619  if (P == BLACK)
620  result += table[index(WHITE, captured, moved.to())];
621  else
622  result -= table[index(BLACK, captured, moved.to())];
623  }
624  }
625  if (P == BLACK)
626  result += table[index(BLACK, moved.ptype(), moved.to())];
627  else
628  result -= table[index(WHITE, moved.ptype(), moved.to())];
629  return result;
630 }
631 
632 ␌
635 
636 void osl::eval::ml::KnightCheck::setUp(const Weights &weights,int stage)
637 {
638  KnightCheck::weight[stage] = weights.value(0);
639 }
640 
642 KnightCheckY::setUp(const Weights &weights)
643 {
644  for (size_t i = 0; i < ONE_DIM; ++i)
645  {
646  for (int s=0; s<NStages; ++s)
647  KnightCheck::y_table[i][s] = weights.value(i + ONE_DIM*s);
648  }
649 }
650 
652 KnightCheck::eval(const NumEffectState &state)
653 {
654  MultiInt result;
655  if (canCheck<BLACK>(state))
656  {
657  const int index_y = indexY<BLACK>(state.kingSquare<BLACK>().y());
658  result += value(index_y);
659  }
660  if (canCheck<WHITE>(state))
661  {
662  const int index_y = indexY<WHITE>(state.kingSquare<WHITE>().y());
663  result -= value(index_y);
664  }
665  return result;
666 }
667 
670 
672 PawnPtypeOPtypeO::setUp(const Weights &weights)
673 {
674  for (size_t i = 0; i < ONE_DIM; ++i)
675  {
676  for (int s=0; s<NStages; ++s)
677  table[i][s] = weights.value(i + ONE_DIM*s);
678  }
679 }
680 
682 PawnPtypeOPtypeOY::setUp(const Weights &weights)
683 {
684  for (size_t i = 0; i < ONE_DIM; ++i)
685  {
686  for (int s=0; s<NStages; ++s)
687  PawnPtypeOPtypeO::y_table[i][s] = weights.value(i + ONE_DIM*s);
688  }
689 }
690 
693 {
694  MultiInt result;
695  for (int i = PtypeTraits<PAWN>::indexMin;
696  i < PtypeTraits<PAWN>::indexLimit; ++i)
697  {
698  Piece pawn = state.pieceOf(i);
699  if (pawn.isOnBoard() && !pawn.isPromoted())
700  {
701  const Square up = Board_Table.nextSquare(pawn.owner(),
702  pawn.square(), U);
703  const Square up_up = Board_Table.nextSquare(pawn.owner(),
704  up, U);
705  PtypeO up_p =
706  (up.isOnBoard() ? state.pieceAt(up).ptypeO() : PTYPEO_EDGE);
707  PtypeO up_up_p =
708  (up_up.isOnBoard() ? state.pieceAt(up_up).ptypeO() : PTYPEO_EDGE);
709  const int idx = index(pawn.owner(), up_p, up_up_p);
710  const int idx_y = indexY(pawn.owner(), up_p, up_up_p,
711  pawn.square().y());
712  if (pawn.owner() == BLACK)
713  result += table[idx] + y_table[idx_y];
714  else
715  result -= table[idx] + y_table[idx_y];
716  }
717  }
718  return result;
719 }
720 
721 template<osl::Player P>
722 MultiInt
723 #if (defined __GNUC__ && ! defined __clang__)
724  __attribute__((__flatten__))
725 #endif
728  const CArray2d<int, 2, 9> &pawns,
729  const MultiInt &last_value)
730 {
731  assert(moved.player()==P);
732  MultiInt result(last_value);
733  if (!moved.isDrop())
734  {
735  if (moved.oldPtype() == PAWN)
736  {
737  const Square up_up = moved.to() + DirectionPlayerTraits<U,P>::offset();
738  const PtypeO up_up_p =
739  (up_up.isOnBoard() ? state.pieceAt(up_up).ptypeO() : PTYPEO_EDGE);
740  const int i = index(P, moved.capturePtypeOSafe(), up_up_p);
741  const int i_y = indexY(P, moved.capturePtypeOSafe(),
742  up_up_p, moved.from().y());
743  if (P == BLACK)
744  result -= table[i]+y_table[i_y];
745  else
746  result += table[i]+y_table[i_y];
747  }
748  if (pawns[BLACK][moved.from().x() - 1] != 0)
749  {
750  if (pawns[BLACK][moved.from().x() - 1] ==
751  moved.from().y() + 1)
752  {
753  const Square up_up = moved.from() + DirectionPlayerTraits<U,BLACK>::offset();
754  const PtypeO up_up_p =
755  (up_up.isOnBoard() ? (up_up == moved.to() ? moved.capturePtypeOSafe() :
756  state.pieceAt(up_up).ptypeO()) :
757  PTYPEO_EDGE);
758  const int i = index(BLACK, moved.oldPtypeO(), up_up_p);
759  const int i_y = indexY(BLACK, moved.oldPtypeO(), up_up_p,
760  moved.from().y() + 1);
761  result -= table[i]+y_table[i_y];
762  if (up_up != moved.to())
763  {
764  const int new_i = index(BLACK, PTYPEO_EMPTY, up_up_p);
765  const int new_i_y = indexY(BLACK, PTYPEO_EMPTY, up_up_p,
766  moved.from().y() + 1);
767  result += table[new_i]+y_table[new_i_y];
768  }
769  }
770  if (pawns[BLACK][moved.from().x() - 1] ==
771  moved.from().y() + 2)
772  {
773  const Square up = moved.from() + DirectionPlayerTraits<D,BLACK>::offset();
774  const PtypeO up_p =
775  (up.isOnBoard() ? (up == moved.to() ? moved.capturePtypeOSafe() :
776  state.pieceAt(up).ptypeO()) : PTYPEO_EDGE);
777  const int i = index(BLACK, up_p, moved.oldPtypeO());
778  const int i_y = indexY(BLACK, up_p, moved.oldPtypeO(),
779  moved.from().y() + 2);
780  result -= table[i]+y_table[i_y];
781  if (moved.to() != up)
782  {
783  const int new_i = index(BLACK, up_p, PTYPEO_EMPTY);
784  const int new_i_y = indexY(BLACK, up_p, PTYPEO_EMPTY,
785  moved.from().y() + 2);
786  result += table[new_i]+y_table[new_i_y];
787  }
788  }
789  }
790  if (pawns[WHITE][moved.from().x() - 1] != 0)
791  {
792  if (pawns[WHITE][moved.from().x() - 1] ==
793  moved.from().y() - 1)
794  {
795  const Square up_up = moved.from() + DirectionPlayerTraits<U,WHITE>::offset();
796  const PtypeO up_up_p =
797  (up_up.isOnBoard() ? (up_up == moved.to() ? moved.capturePtypeOSafe() :
798  state.pieceAt(up_up).ptypeO()) :
799  PTYPEO_EDGE);
800  const int i = index(WHITE, moved.oldPtypeO(), up_up_p);
801  const int i_y = indexY(WHITE, moved.oldPtypeO(), up_up_p,
802  moved.from().y() - 1);
803  result += table[i]+y_table[i_y];
804  if (moved.to() != up_up)
805  {
806  const int new_i = index(WHITE, PTYPEO_EMPTY, up_up_p);
807  const int new_i_y = indexY(WHITE, PTYPEO_EMPTY, up_up_p,
808  moved.from().y() - 1);
809  result -= table[new_i]+y_table[new_i_y];
810  }
811  }
812  if (pawns[WHITE][moved.from().x() - 1] ==
813  moved.from().y() - 2)
814  {
815  const Square up = moved.from() + DirectionPlayerTraits<D,WHITE>::offset();
816  const PtypeO up_p =
817  (up.isOnBoard() ? (up == moved.to() ? moved.capturePtypeOSafe() :
818  state.pieceAt(up).ptypeO()) : PTYPEO_EDGE);
819  const int i = index(WHITE, up_p, moved.oldPtypeO());
820  const int i_y = indexY(WHITE, up_p, moved.oldPtypeO(),
821  moved.from().y() - 2);
822  result += table[i]+y_table[i_y];
823  if (moved.to() != up)
824  {
825  const int new_i = index(WHITE, up_p, PTYPEO_EMPTY);
826  const int new_i_y = indexY(WHITE, up_p, PTYPEO_EMPTY,
827  moved.from().y() - 2);
828  result -= table[new_i]+y_table[new_i_y];
829  }
830  }
831  }
832  }
833  Ptype captured = moved.capturePtype();
834  if (captured == PAWN)
835  {
836  const Square up = moved.to() + DirectionPlayerTraits<D,P>::offset();
837  const Square up_up = up + DirectionPlayerTraits<D,P>::offset();
838  const PtypeO up_p =
839  (up.isOnBoard() ? (up == moved.from() ? moved.oldPtypeO() :
840  state.pieceAt(up).ptypeO()) : PTYPEO_EDGE);
841  const PtypeO up_up_p =
842  (up_up.isOnBoard() ? (up_up == moved.from() ? moved.oldPtypeO() :
843  state.pieceAt(up_up).ptypeO()) : PTYPEO_EDGE);
844  const int i = index(alt(P), up_p, up_up_p);
845  const int i_y = indexY(alt(P), up_p, up_up_p,
846  moved.to().y());
847  if (P == BLACK)
848  {
849  result += table[i]+y_table[i_y];
850  }
851  else
852  {
853  result -= table[i]+y_table[i_y];
854  }
855  }
856  if (moved.ptype() == PAWN)
857  {
858  const Square up = moved.to() + DirectionPlayerTraits<U,P>::offset();
859  const Square up_up = up + DirectionPlayerTraits<U,P>::offset();
860  const PtypeO up_p =
861  (up.isOnBoard() ? (up == moved.from() ? moved.oldPtypeO() :
862  state.pieceAt(up).ptypeO()) : PTYPEO_EDGE);
863  const PtypeO up_up_p =
864  (up_up.isOnBoard() ? (up_up == moved.from() ? moved.oldPtypeO() :
865  state.pieceAt(up_up).ptypeO()) : PTYPEO_EDGE);
866  const int i = index(P, up_p, up_up_p);
867  const int i_y = indexY(P, up_p, up_up_p, moved.to().y());
868  if (P == BLACK)
869  {
870  result += table[i]+y_table[i_y];
871  }
872  else
873  {
874  result -= table[i]+y_table[i_y];
875  }
876  }
877  if (pawns[BLACK][moved.to().x() - 1] != 0)
878  {
879  if (pawns[BLACK][moved.to().x() - 1] ==
880  moved.to().y() + 1)
881  {
882  const Square up_up = moved.to() + DirectionPlayerTraits<U,BLACK>::offset();
883  const PtypeO up_up_p =
884  (up_up.isOnBoard() ? state.pieceAt(up_up).ptypeO() :
885  PTYPEO_EDGE);
886  const int i = index(BLACK, moved.ptypeO(), up_up_p);
887  const int i_y = indexY(BLACK, moved.ptypeO(), up_up_p,
888  moved.to().y() + 1);
889  result += table[i]+y_table[i_y];
890  if (moved.isDrop() || moved.from() != up_up)
891  {
892  const int old_i = index(BLACK, moved.capturePtypeOSafe(), up_up_p);
893  const int old_i_y = indexY(BLACK, moved.capturePtypeOSafe(),
894  up_up_p, moved.to().y() + 1);
895  result -= table[old_i]+y_table[old_i_y];
896  }
897  }
898  if (pawns[BLACK][moved.to().x() - 1] ==
899  moved.to().y() + 2)
900  {
901  const Square up = moved.to() + DirectionPlayerTraits<D,BLACK>::offset();
902  const PtypeO up_p =
903  (up.isOnBoard() ? state.pieceAt(up).ptypeO() : PTYPEO_EDGE);
904  const int i = index(BLACK, up_p, moved.ptypeO());
905  const int i_y = indexY(BLACK, up_p, moved.ptypeO(), moved.to().y() + 2);
906  result += table[i]+y_table[i_y];
907  if (moved.isDrop() || up != moved.from())
908  {
909  const int old_i = index(BLACK, up_p, moved.capturePtypeOSafe());
910  const int old_i_y = indexY(BLACK, up_p, moved.capturePtypeOSafe(),
911  moved.to().y() + 2);
912  result -= table[old_i]+y_table[old_i_y];
913  }
914  }
915  }
916  if (pawns[WHITE][moved.to().x() - 1] != 0)
917  {
918  if (pawns[WHITE][moved.to().x() - 1] ==
919  moved.to().y() - 1)
920  {
921  const Square up_up = moved.to() + DirectionPlayerTraits<U,WHITE>::offset();
922  const PtypeO up_up_p =
923  (up_up.isOnBoard() ? state.pieceAt(up_up).ptypeO() :
924  PTYPEO_EDGE);
925  const int i = index(WHITE, moved.ptypeO(), up_up_p);
926  const int i_y = indexY(WHITE, moved.ptypeO(), up_up_p,
927  moved.to().y() - 1);
928  result -= table[i]+y_table[i_y];
929  if (up_up != moved.from())
930  {
931  const int old_i = index(WHITE, moved.capturePtypeOSafe(), up_up_p);
932  const int old_i_y = indexY(WHITE, moved.capturePtypeOSafe(), up_up_p,
933  moved.to().y() - 1);
934  result += table[old_i]+y_table[old_i_y];
935  }
936  }
937  if (pawns[WHITE][moved.to().x() - 1] ==
938  moved.to().y() - 2)
939  {
940  const Square up = moved.to() + DirectionPlayerTraits<D,WHITE>::offset();
941  const PtypeO up_p =
942  (up.isOnBoard() ? state.pieceAt(up).ptypeO() : PTYPEO_EDGE);
943  const int i = index(WHITE, up_p, moved.ptypeO());
944  const int i_y = indexY(WHITE, up_p, moved.ptypeO(), moved.to().y() - 2);
945  result -= table[i]+y_table[i_y];
946  if (moved.isDrop() || up != moved.from())
947  {
948  const int old_i = index(WHITE, up_p, moved.capturePtypeOSafe());
949  const int old_i_y = indexY(WHITE, up_p, moved.capturePtypeOSafe(),
950  moved.to().y() - 2);
951  result += table[old_i]+y_table[old_i_y];
952  }
953  }
954  }
955  return result;
956 }
957 
958 
959 ␌
962 
964 PromotedMinorPieces::setUp(const Weights &weights)
965 {
966  for (size_t i = 0; i < ONE_DIM; ++i)
967  {
968  for (int s=0; s<NStages; ++s)
969  table[i][s] = weights.value(i + ONE_DIM*s);
970  }
971 }
972 
974 PromotedMinorPiecesY::setUp(const Weights &weights)
975 {
976  for (size_t i = 0; i < ONE_DIM; ++i)
977  {
978  for (int s=0; s<NStages; ++s)
979  PromotedMinorPieces::y_table[i][s] = weights.value(i + ONE_DIM*s);
980  }
981 }
982 
983 template <int Sign>
984 inline void osl::eval::ml::
985 PromotedMinorPieces::adjust(int index, int index_attack, int index_defense,
986  MultiInt &result)
987 {
988  if(Sign>0)
989  result+= table[index] + y_table[index_attack] + y_table[index_defense];
990  else
991  result-= table[index] + y_table[index_attack] + y_table[index_defense];
992 }
993 template <osl::Player P>
996  const PieceMask promoted,
997  MultiInt &result)
998 {
999  PieceMask attack = promoted & state.piecesOnBoard(P);
1000  const Square king = state.kingSquare<alt(P)>();
1001  const Square self_king = state.kingSquare<P>();
1002  int min_left = -10;
1003  int min_right = 10;
1004  while (attack.any())
1005  {
1006  const Piece p = state.pieceOf(attack.takeOneBit());
1007  const int x_diff = (P == BLACK ? p.square().x() - king.x() :
1008  king.x() - p.square().x());
1009  if (x_diff <= 0)
1010  {
1011  if (x_diff > min_left)
1012  {
1013  if (min_left != -10)
1014  {
1015  if (P == BLACK)
1016  adjust<1>(-min_left, indexY<true, P>(king, -min_left),
1017  indexY<false, P>(self_king, -min_left), result);
1018  else
1019  adjust<-1>(-min_left, indexY<true, P>(king, -min_left),
1020  indexY<false, P>(self_king, -min_left), result);
1021  }
1022  min_left = x_diff;
1023  }
1024  else
1025  {
1026  if (P == BLACK)
1027  adjust<1>(-x_diff, indexY<true, P>(king, -x_diff),
1028  indexY<false, P>(self_king, -x_diff),
1029  result);
1030  else
1031  adjust<-1>(-x_diff, indexY<true, P>(king, -x_diff),
1032  indexY<false, P>(self_king, -x_diff),
1033  result);
1034  }
1035  }
1036  if (x_diff >= 0)
1037  {
1038  if (x_diff < min_right)
1039  {
1040  if (min_right != 10)
1041  {
1042  if (P == BLACK)
1043  adjust<1>(min_right, indexY<true, P>(king, min_right),
1044  indexY<false, P>(self_king, min_right),
1045  result);
1046  else
1047  adjust<-1>(min_right, indexY<true, P>(king, min_right),
1048  indexY<false, P>(self_king, min_right),
1049  result);
1050  }
1051  min_right = x_diff;
1052  }
1053  else if (x_diff != 0)
1054  {
1055  if (P == BLACK)
1056  adjust<1>(x_diff, indexY<true, P>(king, x_diff),
1057  indexY<false, P>(self_king, x_diff),
1058  result);
1059  else
1060  adjust<-1>(x_diff, indexY<true, P>(king, x_diff),
1061  indexY<false, P>(self_king, x_diff),
1062  result);
1063  }
1064  }
1065  }
1066 }
1067 
1070 {
1071  MultiInt result;
1072  PieceMask promoted_pieces = state.promotedPieces();
1073  promoted_pieces.clearBit<ROOK>();
1074  promoted_pieces.clearBit<BISHOP>();
1075  if (promoted_pieces.none())
1076  return result;
1077 
1078  evalOne<BLACK>(state, promoted_pieces, result);
1079  evalOne<WHITE>(state, promoted_pieces, result);
1080  return result;
1081 }
1082 
1085  Move moved,
1086  const MultiInt &last_values)
1087 {
1088  Ptype captured = moved.capturePtype();
1089  if (moved.ptype() == KING ||
1090  (isPromoted(moved.ptype()) && !isMajor(moved.ptype())) ||
1092  !isMajor(captured)))
1093  return eval(state);
1094 
1095  return last_values;
1096 }
1097 
1098 ␌
1101 
1103 {
1104  for (size_t i = 0; i < ONE_DIM; ++i)
1105  {
1106  for (int s=0; s<NStages; ++s)
1107  table[i][s] = weights.value(i + ONE_DIM*s);
1108  }
1109 }
1110 
1112  const Weights &weights)
1113 {
1114  for (size_t i = 0; i < ONE_DIM; ++i)
1115  {
1116  for (int s=0; s<NStages; ++s)
1117  NonPawnAttacked::king_table[i][s] = weights.value(i + ONE_DIM*s);
1118  }
1119  for(int x_diff=0;x_diff<9;x_diff++)
1120  for(int y_diff= -8;y_diff<=8;y_diff++)
1121  for(int has_support=0;has_support<2;has_support++)
1122  for(int same_turn=0;same_turn<2;same_turn++)
1123  for(int ptype=0;ptype<PTYPE_SIZE;ptype++){
1124  int index=((ptype + (same_turn ? 0 : PTYPE_SIZE) +
1125  (has_support ? 0 : PTYPE_SIZE*2))* 9 + x_diff) * 17 +
1126  y_diff + 8;
1127  int index0=ptype + (same_turn ? 0 : PTYPE_SIZE) +
1128  (has_support ? 0 : PTYPE_SIZE * 2);
1130  }
1131 }
1132 
1133 template <int Sign>
1135 NonPawnAttacked::adjust(int black_turn_king_attack,
1136  int black_turn_king_defense,
1137  int white_turn_king_attack,
1138  int white_turn_king_defense,
1139  MultiIntPair &result)
1140 {
1141  if(Sign>0){
1142  result[BLACK] += king_table[black_turn_king_attack] +
1143  king_table[black_turn_king_defense];
1144  result[WHITE] += king_table[white_turn_king_attack] +
1145  king_table[white_turn_king_defense];
1146  }
1147  else{
1148  result[BLACK] -= king_table[black_turn_king_attack] +
1149  king_table[black_turn_king_defense];
1150  result[WHITE] -= king_table[white_turn_king_attack] +
1151  king_table[white_turn_king_defense];
1152  }
1153 }
1154 
1156 NonPawnAttacked::eval(const NumEffectState &state, MultiIntPair& result)
1157 {
1158  result = MultiIntPair();
1159  CArray<Square, 2> kings = {{state.kingSquare<BLACK>(),
1160  state.kingSquare<WHITE>()}};
1161  PieceMask black_attacked = state.effectedMask(WHITE) & state.piecesOnBoard(BLACK);
1162  black_attacked.reset(KingTraits<BLACK>::index);
1163  mask_t black_ppawn = state.promotedPieces().getMask<PAWN>() & black_attacked.selectBit<PAWN>();
1164  black_attacked.clearBit<PAWN>();
1165  black_attacked.orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
1166  PieceMask black_with_support = state.effectedMask(BLACK) & black_attacked;
1167  PieceMask black_without_support = (~state.effectedMask(BLACK)) & black_attacked;
1168  while (black_with_support.any())
1169  {
1170  const Piece piece = state.pieceOf(black_with_support.takeOneBit());
1171  const int index_king_black_turn_attack =
1172  indexK<true>(kings[WHITE], true, true, piece);
1173  const int index_king_white_turn_attack =
1174  indexK<true>(kings[WHITE], false, true, piece);
1175  const int index_king_black_turn_defense =
1176  indexK<false>(kings[BLACK], true, true, piece);
1177  const int index_king_white_turn_defense =
1178  indexK<false>(kings[BLACK], false, true, piece);
1179  adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1180  index_king_white_turn_attack, index_king_white_turn_defense,
1181  result);
1182  }
1183  while (black_without_support.any())
1184  {
1185  const Piece piece = state.pieceOf(black_without_support.takeOneBit());
1186  const int index_king_black_turn_attack =
1187  indexK<true>(kings[WHITE], true, false, piece);
1188  const int index_king_white_turn_attack =
1189  indexK<true>(kings[WHITE], false, false, piece);
1190  const int index_king_black_turn_defense =
1191  indexK<false>(kings[BLACK], true, false, piece);
1192  const int index_king_white_turn_defense =
1193  indexK<false>(kings[BLACK], false, false, piece);
1194  adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1195  index_king_white_turn_attack, index_king_white_turn_defense,
1196  result);
1197  }
1198 
1199  PieceMask white_attacked = state.effectedMask(BLACK) & state.piecesOnBoard(WHITE);
1200  white_attacked.reset(KingTraits<WHITE>::index);
1201  mask_t white_ppawn = state.promotedPieces().getMask<PAWN>() & white_attacked.selectBit<PAWN>();
1202  white_attacked.clearBit<PAWN>();
1203  white_attacked.orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
1204  PieceMask white_with_support = state.effectedMask(WHITE) & white_attacked;
1205  PieceMask white_without_support = (~state.effectedMask(WHITE)) & white_attacked;
1206  while (white_with_support.any())
1207  {
1208  const Piece piece = state.pieceOf(white_with_support.takeOneBit());
1209  const int index_king_black_turn_attack =
1210  indexK<true>(kings[BLACK], false, true, piece);
1211  const int index_king_white_turn_attack =
1212  indexK<true>(kings[BLACK], true, true, piece);
1213  const int index_king_black_turn_defense =
1214  indexK<false>(kings[WHITE], false, true, piece);
1215  const int index_king_white_turn_defense =
1216  indexK<false>(kings[WHITE], true, true, piece);
1217  adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1218  index_king_white_turn_attack, index_king_white_turn_defense,
1219  result);
1220  }
1221  while (white_without_support.any())
1222  {
1223  const Piece piece = state.pieceOf(white_without_support.takeOneBit());
1224  const int index_king_black_turn_attack =
1225  indexK<true>(kings[BLACK], false, false, piece);
1226  const int index_king_white_turn_attack =
1227  indexK<true>(kings[BLACK], true, false, piece);
1228  const int index_king_black_turn_defense =
1229  indexK<false>(kings[WHITE], false, false, piece);
1230  const int index_king_white_turn_defense =
1231  indexK<false>(kings[WHITE], true, false, piece);
1232  adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1233  index_king_white_turn_attack, index_king_white_turn_defense,
1234  result);
1235  }
1236 }
1237 
1238 template<osl::Player P>
1241  const NumEffectState &state,
1242  Move moved,
1243  const CArray<PieceMask, 2> &effected,
1244  MultiIntPair &result)
1245 {
1246  if (moved.ptype() == KING)
1247  {
1248  eval(state, result);
1249  return;
1250  }
1251 
1252  CArray<PieceMask, 2> effected_mask = effected;
1253  effected_mask[0].clearBit<KING>();
1254  effected_mask[1].clearBit<KING>();
1255  CArray<PieceMask, 2> new_mask = {{
1256  state.effectedMask(BLACK),
1257  state.effectedMask(WHITE)
1258  }};
1259 
1260  mask_t black_ppawn =
1261  new_mask[0].selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
1262  mask_t white_ppawn =
1263  new_mask[1].template selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
1264  new_mask[0].clearBit<PAWN>();
1265  new_mask[1].clearBit<PAWN>();
1266  new_mask[0].orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
1267  new_mask[1].orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
1268  new_mask[0].clearBit<KING>();
1269  new_mask[1].clearBit<KING>();
1270  CArray<Square, 2> kings = {{ state.kingSquare<BLACK>(),
1271  state.kingSquare<WHITE>() }};
1272  const Piece p = state.pieceAt(moved.to());
1273  assert(p.owner()==P);
1274  if (!moved.isDrop())
1275  {
1276  if (effected_mask[alt(P)].test(p.number()))
1277  {
1278  const bool has_support = effected_mask[P].test(p.number());
1279  const int index_king_black_turn_attack =
1280  indexK<true>(kings[alt(P)], BLACK == P,
1281  has_support, moved.from(), P, moved.oldPtype());
1282  const int index_king_white_turn_attack =
1283  indexK<true>(kings[alt(P)], WHITE == P,
1284  has_support, moved.from(), P, moved.oldPtype());
1285  const int index_king_black_turn_defense =
1286  indexK<false>(kings[P], BLACK == P,
1287  has_support, moved.from(), P, moved.oldPtype());
1288  const int index_king_white_turn_defense =
1289  indexK<false>(kings[P], WHITE == P,
1290  has_support, moved.from(), P, moved.oldPtype());
1291  if (P == BLACK)
1292  adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1293  index_king_white_turn_attack, index_king_white_turn_defense,
1294  result);
1295  else
1296  adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1297  index_king_white_turn_attack, index_king_white_turn_defense,
1298  result);
1299  }
1300  }
1301  if (new_mask[alt(P)].test(p.number()))
1302  {
1303  const bool has_support = new_mask[P].test(p.number());
1304  const int index_king_black_turn_attack =
1305  indexK<true>(kings[alt(P)], BLACK == P,
1306  has_support, p);
1307  const int index_king_white_turn_attack =
1308  indexK<true>(kings[alt(P)], WHITE == P,
1309  has_support, p);
1310  const int index_king_black_turn_defense =
1311  indexK<false>(kings[P], BLACK == P,
1312  has_support, p);
1313  const int index_king_white_turn_defense =
1314  indexK<false>(kings[P], WHITE == P,
1315  has_support, p);
1316  if (P == BLACK)
1317  adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1318  index_king_white_turn_attack, index_king_white_turn_defense,
1319  result);
1320  else
1321  adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1322  index_king_white_turn_attack, index_king_white_turn_defense,
1323  result);
1324  }
1325  const Ptype captured = moved.capturePtype();
1326  if (captured != PTYPE_EMPTY && captured != PAWN)
1327  {
1328  PieceMask captured_mask =
1329  effected_mask[P] & (~state.piecesOnBoard(BLACK)) &
1330  (~state.piecesOnBoard(WHITE));
1331 
1332  const bool has_support = effected_mask[alt(P)].test(captured_mask.takeOneBit());
1333  const int index_king_black_turn_attack =
1334  indexK<true>(kings[P], WHITE == P,
1335  has_support, moved.to(), alt(P), captured);
1336  const int index_king_white_turn_attack =
1337  indexK<true>(kings[P], BLACK == P,
1338  has_support, moved.to(), alt(P), captured);
1339  const int index_king_black_turn_defense =
1340  indexK<false>(kings[alt(P)], WHITE == P,
1341  has_support, moved.to(), alt(P), captured);
1342  const int index_king_white_turn_defense =
1343  indexK<false>(kings[alt(P)], BLACK == P,
1344  has_support, moved.to(), alt(P), captured);
1345  if (P == BLACK)
1346  adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1347  index_king_white_turn_attack, index_king_white_turn_defense,
1348  result);
1349  else
1350  adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1351  index_king_white_turn_attack, index_king_white_turn_defense,
1352  result);
1353  }
1354 
1355  updateEffectChanged<BLACK>(state, effected_mask, new_mask, p.number(),
1356  result);
1357  updateEffectChanged<WHITE>(state, effected_mask, new_mask, p.number(),
1358  result);
1359 }
1360 
1361 ␌
1364 
1366 KnightHead::setUp(const Weights &weights)
1367 {
1368  for (size_t i = 0; i < ONE_DIM; ++i)
1369  {
1370  for (int s=0; s<NStages; ++s)
1371  table[i][s] = weights.value(i + ONE_DIM*s);
1372  }
1373 }
1374 
1377 {
1378  for (size_t i = 0; i < ONE_DIM; ++i)
1379  {
1380  for (int s=0; s<NStages; ++s)
1381  KnightHead::opp_table[i][s] = weights.value(i + ONE_DIM*s);
1382  }
1383 }
1384 
1386 KnightHead::eval(const NumEffectState &state)
1387 {
1388  MultiInt result;
1389  for (int i = PtypeTraits<KNIGHT>::indexMin;
1390  i < PtypeTraits<KNIGHT>::indexLimit;
1391  ++i)
1392  {
1393  const Piece knight = state.pieceOf(i);
1394  if (knight.isOnBoard() && !knight.isPromoted())
1395  {
1396  const Square up = Board_Table.nextSquare(knight.owner(),
1397  knight.square(), U);
1398  const Piece up_piece = state.pieceAt(up);
1399  if ((up_piece.isEmpty() && state.hasPieceOnStand<PAWN>(alt(knight.owner())) &&
1400  !state.isPawnMaskSet(alt(knight.owner()), knight.square().x()) &&
1401  state.countEffect(knight.owner(), up) <=
1402  state.countEffect(alt(knight.owner()), up)) ||
1403  (state.hasEffectByPtypeStrict<PAWN>(alt(knight.owner()), up) &&
1404  (up_piece.isEmpty() || up_piece.owner() == knight.owner()) &&
1405  state.countEffect(knight.owner(), up) <
1406  state.countEffect(alt(knight.owner()), up)))
1407  {
1408  const int y = knight.square().y();
1409  if (knight.owner() == BLACK)
1410  {
1411  result += table[y - 1];
1412  }
1413  else
1414  {
1415  result -= table[9 - y];
1416  }
1417  }
1418  else if (up_piece.isPiece() && up_piece.owner() != knight.owner() &&
1419  state.hasPieceOnStand<PAWN>(up_piece.owner()))
1420  {
1421  const int y = (knight.owner() == BLACK ? knight.square().y() :
1422  10 - knight.square().y());
1423  const int index = up_piece.ptype() * 9 + y - 1;
1424  if (knight.owner() == BLACK)
1425  {
1426  result += opp_table[index];
1427  }
1428  else
1429  {
1430  result -= opp_table[index];
1431  }
1432  }
1433  }
1434  }
1435  return result;
1436 }
1437 
1438 ␌
1440 
1442 NonPawnAttackedPtype::setUp(const Weights &weights)
1443 {
1444  for (size_t i = 0; i < ONE_DIM; ++i)
1445  {
1446  for (int s=0; s<NStages; ++s)
1447  table[i][s] = weights.value(i + ONE_DIM*s);
1448  }
1449 }
1450 
1453  CArray<PieceMask, 40> &attacked_mask,
1454  MultiIntPair &result)
1455 {
1456  result = MultiIntPair();
1457  PieceMask black_attacked = state.effectedMask(WHITE) & state.piecesOnBoard(BLACK);
1458  black_attacked.reset(KingTraits<BLACK>::index);
1459  mask_t black_ppawn = state.promotedPieces().getMask<PAWN>() & black_attacked.selectBit<PAWN>();
1460  black_attacked.clearBit<PAWN>();
1461  black_attacked.orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
1462  while (black_attacked.any())
1463  {
1464  const Piece piece = state.pieceOf(black_attacked.takeOneBit());
1465  const bool with_support = state.effectedMask(BLACK).test(piece.number());
1466  PieceMask attacking =
1467  state.effectSetAt(piece.square()) & state.piecesOnBoard(WHITE);
1468  attacked_mask[piece.number()] = attacking;
1469 
1470  while (attacking.any())
1471  {
1472  const Piece attack = state.pieceOf(attacking.takeOneBit());
1473  const int index_black_turn = index(true, with_support,
1474  piece.ptype(), attack.ptype());
1475  const int index_white_turn = index(false, with_support,
1476  piece.ptype(), attack.ptype());
1477  adjust<1>(index_black_turn, index_white_turn, result);
1478  }
1479  }
1480  PieceMask white_attacked = state.effectedMask(BLACK) & state.piecesOnBoard(WHITE);
1481  white_attacked.reset(KingTraits<WHITE>::index);
1482  mask_t white_ppawn = state.promotedPieces().getMask<PAWN>() & white_attacked.selectBit<PAWN>();
1483  white_attacked.clearBit<PAWN>();
1484  white_attacked.orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
1485  while (white_attacked.any())
1486  {
1487  const Piece piece = state.pieceOf(white_attacked.takeOneBit());
1488  const bool with_support = state.effectedMask(WHITE).test(piece.number());
1489  PieceMask attacking =
1490  state.effectSetAt(piece.square()) & state.piecesOnBoard(BLACK);
1491  attacked_mask[piece.number()] = attacking;
1492  while (attacking.any())
1493  {
1494  const Piece attack = state.pieceOf(attacking.takeOneBit());
1495  const int index_black_turn = index(false, with_support,
1496  piece.ptype(), attack.ptype());
1497  const int index_white_turn = index(true, with_support,
1498  piece.ptype(), attack.ptype());
1499  adjust<-1>(index_black_turn, index_white_turn, result);
1500  }
1501  }
1502 }
1503 
1504 template<osl::Player P>
1507  const NumEffectState &state,
1508  Move moved,
1509  const CArray<PieceMask, 2> &effected,
1510  CArray<PieceMask, 40> &attacked_mask,
1511  MultiIntPair &result)
1512 {
1513  CArray<PieceMask, 2> effected_mask = effected;
1514  effected_mask[0].clearBit<KING>();
1515  effected_mask[1].clearBit<KING>();
1516  CArray<PieceMask, 2> new_mask = {{
1517  state.effectedMask(BLACK),
1518  state.effectedMask(WHITE)
1519  }};
1520  mask_t black_ppawn =
1521  new_mask[0].selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
1522  mask_t white_ppawn =
1523  new_mask[1].selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
1524  new_mask[0].clearBit<PAWN>();
1525  new_mask[1].clearBit<PAWN>();
1526  new_mask[0].orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
1527  new_mask[1].orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
1528  new_mask[0].clearBit<KING>();
1529  new_mask[1].clearBit<KING>();
1530  const Piece p = state.pieceAt(moved.to());
1531  assert(p.owner()==P);
1532  assert(moved.player()==P);
1533  const Ptype captured = moved.capturePtype();
1534  int captured_number = -1;
1535  if (captured != PTYPE_EMPTY && captured != PAWN)
1536  {
1537  PieceMask captured_mask =
1538  effected_mask[P] & (~state.piecesOnBoard(BLACK)) &
1539  (~state.piecesOnBoard(WHITE));
1540  captured_number = captured_mask.takeOneBit();
1541  }
1542  if (!moved.isDrop() && moved.oldPtype() != PAWN)
1543  {
1544  if (effected_mask[alt(P)].test(p.number()))
1545  {
1546  const bool has_support = effected_mask[P].test(p.number());
1547  PieceMask attacking = attacked_mask[p.number()];
1548  if (captured_number != -1)
1549  {
1550  if (attacking.test(captured_number))
1551  {
1552  if (P == BLACK)
1553  {
1554  evalOnePiece<false>(P, moved.oldPtype(), captured,
1555  has_support, result);
1556  }
1557  else
1558  {
1559  evalOnePiece<true>(P, moved.oldPtype(), captured,
1560  has_support, result);
1561  }
1562  attacking.reset(captured_number);
1563  }
1564  }
1565  while (attacking.any())
1566  {
1567  const Piece attack = state.pieceOf(attacking.takeOneBit());
1568  if (P == BLACK)
1569  {
1570  evalOnePiece<false>(P, moved.oldPtype(), attack.ptype(),
1571  has_support, result);
1572  }
1573  else
1574  {
1575  evalOnePiece<true>(P, moved.oldPtype(), attack.ptype(),
1576  has_support, result);
1577  }
1578  }
1579  }
1580  }
1581  if (new_mask[alt(P)].test(p.number()))
1582  {
1583  const bool has_support = new_mask[P].test(p.number());
1584  PieceMask attacking =
1585  state.effectSetAt(moved.to()) & state.piecesOnBoard(alt(P));
1586  attacked_mask[p.number()] = attacking;
1587  while (attacking.any())
1588  {
1589  const Piece attack = state.pieceOf(attacking.takeOneBit());
1590  if (P == BLACK)
1591  {
1592  evalOnePiece<true>(P, p.ptype(), attack.ptype(),
1593  has_support, result);
1594  }
1595  else
1596  {
1597  evalOnePiece<false>(P, p.ptype(), attack.ptype(),
1598  has_support, result);
1599  }
1600  }
1601  }
1602  if (captured_number != -1)
1603  {
1604  const bool has_support = effected_mask[alt(P)].test(captured_number);
1605  PieceMask attacking = attacked_mask[captured_number];
1606  if (attacking.test(p.number()))
1607  {
1608  if (P == BLACK)
1609  {
1610  evalOnePiece<true>(alt(P), captured, moved.oldPtype(),
1611  has_support, result);
1612  }
1613  else
1614  {
1615  evalOnePiece<false>(alt(P), captured, moved.oldPtype(),
1616  has_support, result);
1617  }
1618  attacking.reset(p.number());
1619  }
1620  while (attacking.any())
1621  {
1622  const Piece attack = state.pieceOf(attacking.takeOneBit());
1623  if (P == BLACK)
1624  {
1625  evalOnePiece<true>(alt(P), captured, attack.ptype(),
1626  has_support, result);
1627  }
1628  else
1629  {
1630  evalOnePiece<false>(alt(P), captured, attack.ptype(),
1631  has_support, result);
1632  }
1633  }
1634  }
1635  updateChanged<BLACK>(state, p, moved, captured_number,
1636  effected_mask, new_mask, attacked_mask, result);
1637  updateChanged<WHITE>(state, p, moved, captured_number,
1638  effected_mask, new_mask, attacked_mask, result);
1639 }
1640 ␌
1644 {
1645  for (int i = 0; i < ONE_DIM; ++i)
1646  {
1647  for (int s=0; s<NStages; ++s)
1648  table[i][s] = weights.value(i + ONE_DIM*s);
1649  }
1650  for (int i=0; i<PTYPE_SIZE*2*PTYPE_SIZE; ++i)
1651  for (int j=i+1; j<PTYPE_SIZE*2*PTYPE_SIZE; ++j) {
1652  table[index2(j,i)] = table[index2(i,j)];
1653  }
1654 }
1655 template <osl::Player Owner>
1657 evalOne(const NumEffectState &state)
1658 {
1659  MultiInt result;
1660  PieceMask attacked = state.effectedMask(alt(Owner)) & state.piecesOnBoard(Owner);
1661  attacked.reset(state.kingPiece<Owner>().number());
1662  mask_t ppawn = state.promotedPieces().getMask<PAWN>() & attacked.selectBit<PAWN>();
1663  attacked.clearBit<PAWN>();
1664  attacked.orMask(PtypeFuns<PAWN>::indexNum, ppawn);
1665  PieceVector pieces;
1666  while (attacked.any())
1667  {
1668  const Piece piece = state.pieceOf(attacked.takeOneBit());
1669  pieces.push_back(piece);
1670  }
1671  for (size_t i=0; i+1<pieces.size(); ++i) {
1672  const int i0 = index1(state, pieces[i]);
1673  for (size_t j=i+1; j<pieces.size(); ++j) {
1674  const int i1 = index1(state, pieces[j]);
1675  if (Owner == BLACK)
1676  result += table[index2(i0, i1)];
1677  else
1678  result -= table[index2(i0, i1)];
1679  }
1680  }
1681  return result;
1682 }
1683 
1685 eval(const NumEffectState &state)
1686 {
1687  return evalOne<BLACK>(state) + evalOne<WHITE>(state);
1688 }
1689 
1690 ␌
1702 {
1703  for (size_t i = 0; i < ONE_DIM; ++i)
1704  {
1705  for (int s=0; s<NStages; ++s)
1706  table[i][s] = weights.value(i + ONE_DIM*s);
1707  }
1708 }
1709 
1711 {
1712  for (size_t i = 0; i < ONE_DIM; ++i)
1713  {
1714  for (int s=0; s<NStages; ++s)
1715  PtypeCount::xy_table[i][s] = weights.value(i + ONE_DIM*s);
1716  }
1717  for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
1718  Ptype ptype=static_cast<Ptype>(i);
1719  int indexMin=Ptype_Table.getIndexMin(ptype);
1720  int size=Ptype_Table.getIndexLimit(ptype)-indexMin;
1721  for(int x=0;x<5;x++){
1722  for(int j=0;j<size;j++){
1723  for(int k=0;k<160;k+=40){
1724  PtypeCount::xy_table[(indexMin+j+k)*5+x]+=PtypeCount::table[indexMin+j+k];
1725  }
1726  }
1727  }
1728  }
1729  for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
1730  Ptype ptype=static_cast<Ptype>(i);
1731  int indexMin=Ptype_Table.getIndexMin(ptype);
1732  int size=Ptype_Table.getIndexLimit(ptype)-indexMin;
1733  for(int x=0;x<5;x++){
1734  for(int k=0;k<160;k+=40)
1735  PtypeCount::xy_table_diff[(indexMin+k)*5+x]=PtypeCount::xy_table[(indexMin+k)*5+x];
1736  for(int j=1;j<size;j++){
1737  for(int k=0;k<160;k+=40)
1738  PtypeCount::xy_table_diff[(indexMin+k+j)*5+x]=PtypeCount::xy_table[(indexMin+k+j)*5+x]-PtypeCount::xy_table[(indexMin+k+j-1)*5+x];
1739  }
1740  }
1741  for(int y=0;y<9;y++){
1742  for(int k=0;k<160;k+=40)
1743  PtypeCount::xy_table_diff[800+(indexMin+k)*9+y]=PtypeCount::xy_table[800+(indexMin+k)*9+y];
1744  for(int j=1;j<size;j++){
1745  for(int k=0;k<160;k+=40)
1746  PtypeCount::xy_table_diff[800+(indexMin+k+j)*9+y]=PtypeCount::xy_table[800+(indexMin+k+j)*9+y]-PtypeCount::xy_table[800+(indexMin+k+j-1)*9+y];
1747  }
1748  }
1749  }
1750 }
1751 
1753 {
1754  for (size_t i = 0; i < ONE_DIM; ++i)
1755  {
1756  for (int s=0; s<NStages; ++s)
1757  PtypeCount::xy_attack_table[i][s] = weights.value(i + ONE_DIM*s);
1758  }
1759  for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
1760  Ptype ptype=static_cast<Ptype>(i);
1761  int indexMin=Ptype_Table.getIndexMin(ptype);
1762  int size=Ptype_Table.getIndexLimit(ptype)-indexMin;
1763  for(int x=0;x<5;x++){
1764  for(int k=0;k<160;k+=40)
1765  PtypeCount::xy_attack_table_diff[(indexMin+k)*5+x]=PtypeCount::xy_attack_table[(indexMin+k)*5+x];
1766  for(int j=1;j<size;j++){
1767  for(int k=0;k<160;k+=40)
1768  PtypeCount::xy_attack_table_diff[(indexMin+k+j)*5+x]=PtypeCount::xy_attack_table[(indexMin+k+j)*5+x]-PtypeCount::xy_attack_table[(indexMin+k+j-1)*5+x];
1769  }
1770  }
1771  for(int y=0;y<9;y++){
1772  for(int k=0;k<160;k+=40)
1773  PtypeCount::xy_attack_table_diff[800+(indexMin+k)*9+y]=PtypeCount::xy_attack_table[800+(indexMin+k)*9+y];
1774  for(int j=1;j<size;j++){
1775  for(int k=0;k<160;k+=40)
1776  PtypeCount::xy_attack_table_diff[800+(indexMin+k+j)*9+y]=PtypeCount::xy_attack_table[800+(indexMin+k+j)*9+y]-PtypeCount::xy_attack_table[800+(indexMin+k+j-1)*9+y];
1777  }
1778  }
1779  }
1780 }
1781 
1782 template<osl::Player P,osl::Ptype T>
1785  const osl::CArray2d<int, 2, osl::PTYPE_SIZE> &ptype_board_count,
1786  const osl::CArray<int,2> &kings_x,
1787  const osl::CArray<int,2> &kings_y)
1788 {
1789  MultiInt out;
1790  int i=playerToIndex(P);
1791  int j=static_cast<int>(T);
1792  if (ptype_count[i][j] != 0)
1793  {
1794  const int index_x = indexCountX<T>(ptype_count[i][j], kings_x[i]);
1795  const int index_y = indexCountY<T>(ptype_count[i][j], kings_y[i]);
1796  const int index_x_attack =
1797  indexCountX<T>(ptype_count[i][j], kings_x[1-i]);
1798  const int index_y_attack =
1799  indexCountY<T>(ptype_count[i][j], kings_y[1-i]);
1800  if (P == BLACK)
1801  {
1802  out += xy_table[index_x] + xy_table[index_y];
1803  out += xy_attack_table[index_x_attack] +
1804  xy_attack_table[index_y_attack];
1805  }
1806  else
1807  {
1808  out -= (xy_table[index_x] + xy_table[index_y]);
1809  out -= (xy_attack_table[index_x_attack] +
1810  xy_attack_table[index_y_attack]);
1811  }
1812  if (ptype_board_count[i][j] != 0)
1813  {
1814  const int index_x =
1815  indexBoardCountX<T>(ptype_board_count[i][j], kings_x[i]);
1816  const int index_y =
1817  indexBoardCountY<T>(ptype_board_count[i][j], kings_y[i]);
1818  const int index_x_attack =
1819  indexBoardCountX<T>(ptype_board_count[i][j], kings_x[(i + 1) & 1]);
1820  const int index_y_attack =
1821  indexBoardCountY<T>(ptype_board_count[i][j], kings_y[(i + 1) & 1]);
1822  if (P == BLACK)
1823  {
1824  out += xy_table[index_x] + xy_table[index_y];
1825  out += xy_attack_table[index_x_attack] +
1826  xy_attack_table[index_y_attack];
1827  }
1828  else
1829  {
1830  out -= (xy_table[index_x] + xy_table[index_y]);
1831  out -= (xy_attack_table[index_x_attack] +
1832  xy_attack_table[index_y_attack]);
1833  }
1834  }
1835  }
1836  return out;
1837 }
1838 
1839 void
1840 #if (defined __GNUC__ && ! defined __clang__)
1841  __attribute__((__flatten__))
1842 #endif
1844  const NumEffectState &state,
1845  const CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
1846  const CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
1847  MultiInt &out)
1848 {
1849  out.clear();
1850  CArray<int, 2> kings_x = {{ state.kingSquare<BLACK>().x(),
1851  state.kingSquare<WHITE>().x() }};
1852  CArray<int, 2> kings_y = {{ state.kingSquare<BLACK>().y(),
1853  10 - state.kingSquare<WHITE>().y() }};
1854  if (kings_x[0] > 5)
1855  kings_x[0] = 10 - kings_x[0];
1856  if (kings_x[1] > 5)
1857  kings_x[1] = 10 - kings_x[1];
1858  out =
1859  evalPlayerPtype<BLACK,PPAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
1860  evalPlayerPtype<BLACK,PLANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
1861  evalPlayerPtype<BLACK,PKNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
1862  evalPlayerPtype<BLACK,PSILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
1863  evalPlayerPtype<BLACK,PBISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
1864  evalPlayerPtype<BLACK,PROOK>(ptype_count,ptype_board_count,kings_x,kings_y)+
1865  evalPlayerPtype<BLACK,GOLD>(ptype_count,ptype_board_count,kings_x,kings_y)+
1866  evalPlayerPtype<BLACK,PAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
1867  evalPlayerPtype<BLACK,LANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
1868  evalPlayerPtype<BLACK,KNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
1869  evalPlayerPtype<BLACK,SILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
1870  evalPlayerPtype<BLACK,BISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
1871  evalPlayerPtype<BLACK,ROOK>(ptype_count,ptype_board_count,kings_x,kings_y)+
1872  evalPlayerPtype<WHITE,PPAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
1873  evalPlayerPtype<WHITE,PLANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
1874  evalPlayerPtype<WHITE,PKNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
1875  evalPlayerPtype<WHITE,PSILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
1876  evalPlayerPtype<WHITE,PBISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
1877  evalPlayerPtype<WHITE,PROOK>(ptype_count,ptype_board_count,kings_x,kings_y)+
1878  evalPlayerPtype<WHITE,GOLD>(ptype_count,ptype_board_count,kings_x,kings_y)+
1879  evalPlayerPtype<WHITE,PAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
1880  evalPlayerPtype<WHITE,LANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
1881  evalPlayerPtype<WHITE,KNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
1882  evalPlayerPtype<WHITE,SILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
1883  evalPlayerPtype<WHITE,BISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
1884  evalPlayerPtype<WHITE,ROOK>(ptype_count,ptype_board_count,kings_x,kings_y);
1885 }
1886 
1887 template<osl::Player P>
1889  const NumEffectState &state,
1890  Move last_move,
1891  CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
1892  CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
1893  MultiInt &last_value_and_out,
1894  unsigned int &ptypeo_mask)
1895 {
1896  assert(last_move.player()==P);
1897  const Player altP=alt(P);
1898  CArray<int, 2> kings_x = {{ state.kingSquare<BLACK>().x(),
1899  state.kingSquare<WHITE>().x() }};
1900  CArray<int, 2> kings_y = {{ state.kingSquare<BLACK>().y(),
1901  10 - state.kingSquare<WHITE>().y() }};
1902  if (kings_x[0] > 5)
1903  kings_x[0] = 10 - kings_x[0];
1904  if (kings_x[1] > 5)
1905  kings_x[1] = 10 - kings_x[1];
1906 
1907  if (last_move.ptype() == KING)
1908  {
1909  const Ptype capturedPtype = last_move.capturePtype();
1910  if (capturedPtype != PTYPE_EMPTY)
1911  {
1912  const PtypeO capturedPtypeO = last_move.capturePtypeO();
1913  if(--ptype_count[altP][capturedPtype]==0)
1914  ptypeo_mask &= ~(1<<(last_move.capturePtypeO()-PTYPEO_MIN));
1915  --ptype_board_count[altP][capturedPtype];
1916  const Ptype base_captured = unpromote(capturedPtype);
1917  ++ptype_count[P][base_captured];
1918  ptypeo_mask |= (1<<(captured(capturedPtypeO)-PTYPEO_MIN));
1919  }
1920  eval(state, ptype_count, ptype_board_count, last_value_and_out);
1921  return;
1922  }
1923 
1924  MultiInt sum;
1925  if (last_move.isDrop())
1926  {
1927  const int count = ++ptype_board_count[P][last_move.ptype()];
1928  sum = valueBoardAll(last_move.ptype(),count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP]);
1929  }
1930  else{
1931  Ptype capturedPtype = last_move.capturePtype();
1932  if (capturedPtype != PTYPE_EMPTY)
1933  {
1934  const int count = --ptype_count[altP][capturedPtype];
1935  if(count==0)
1936  ptypeo_mask &= ~(1<<(last_move.capturePtypeO()-PTYPEO_MIN));
1937  const int board_count = --ptype_board_count[altP][capturedPtype];
1938  const Ptype base_captured = unpromote(capturedPtype);
1939  const int c_count = ++ptype_count[P][base_captured];
1940  ptypeo_mask |= 1<<(captured(last_move.capturePtypeO())-PTYPEO_MIN);
1941  sum=valueAll(capturedPtype,count+1,kings_x[altP],kings_y[altP],kings_x[P],kings_y[P])+
1942  valueBoardAll(capturedPtype,board_count+1,kings_x[altP],kings_y[altP],kings_x[P],kings_y[P])+
1943  valueAll(base_captured,c_count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP]);
1944  }
1945  if (last_move.isPromotion())
1946  {
1947  const Ptype old_ptype = last_move.oldPtype();
1948  const Ptype new_ptype = last_move.ptype();
1949  const int base_count = --ptype_count[P][old_ptype];
1950  const int base_board_count = --ptype_board_count[P][old_ptype];
1951  const int count = ++ptype_count[P][new_ptype];
1952  const int board_count = ++ptype_board_count[P][new_ptype];
1953  if(base_count==0)
1954  ptypeo_mask &= ~(1<<(last_move.oldPtypeO()-PTYPEO_MIN));
1955  ptypeo_mask |= (1<<(last_move.ptypeO()-PTYPEO_MIN));
1956  sum+=valueAll(new_ptype,count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP])+
1957  valueBoardAll(new_ptype,board_count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP])-
1958  valueAll(old_ptype,base_count+1,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP])-
1959  valueBoardAll(old_ptype,base_board_count+1,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP]);
1960  }
1961  }
1962  if(P==BLACK) last_value_and_out+= sum;
1963  else last_value_and_out-= sum;
1964 }
1965 
1968 {
1969  for (size_t i = 0; i < ONE_DIM; ++i)
1970  {
1971  for (int s=0; s<NStages; ++s)
1972  table[i][s] = weights.value(i + ONE_DIM*s);
1973  }
1974 }
1975 
1978 
1981 {
1982  MultiInt result;
1983  for (int i = PtypeTraits<LANCE>::indexMin;
1984  i < PtypeTraits<LANCE>::indexLimit;
1985  ++i)
1986  {
1987  const Piece lance = state.pieceOf(i);
1988  if (lance.isOnBoard() && !lance.isPromoted())
1989  {
1990  const Square self_king = state.kingSquare(lance.owner());
1991  const Square opp_king = state.kingSquare(alt(lance.owner()));
1992  Square p = state.mobilityOf(lance.owner() == BLACK ? U : D,
1993  lance.number());
1994  if (!p.isOnBoard())
1995  {
1996  const int index1 = 0 + 0 + (PTYPEO_EDGE - PTYPEO_MIN) * 17 * 9;
1997  const int index2 = 0 + 0 + (PTYPEO_EDGE - PTYPEO_MIN) * 17 * 9 + 4896;
1998  if (lance.owner() == BLACK)
1999  {
2000  result += table[index1];
2001  result += table[index2];
2002  }
2003  else
2004  {
2005  result -= table[index1];
2006  result -= table[index2];
2007  }
2008  }
2009  else
2010  {
2011  const int index1 = index(lance.owner(), p, opp_king,
2012  state.pieceAt(p).ptypeO(), true);
2013  const int index2 = index(lance.owner(), p, self_king,
2014  state.pieceAt(p).ptypeO(), false);
2015  if (lance.owner() == BLACK)
2016  {
2017  result += table[index1];
2018  result += table[index2];
2019  }
2020  else
2021  {
2022  result -= table[index1];
2023  result -= table[index2];
2024  }
2025  }
2026  }
2027  }
2028  return result;
2029 }
2030 
2033 
2035 {
2036  for (size_t i = 0; i < ONE_DIM; ++i)
2037  {
2038  for (int s = 0; s < NStages; ++s)
2039  {
2040  table[i][s] = weights.value(i + ONE_DIM*s);
2041  }
2042  }
2043 }
2044 
2046 PtypeYPawnY::eval(const NumEffectState &state,
2047  const CArray2d<int, 2, 9> &pawns)
2048 {
2049  MultiInt result;
2050  for (int i = 0; i < Piece::SIZE; ++i)
2051  {
2052  const Piece piece = state.pieceOf(i);
2053  // only skip pawn, not ppawns
2054  if (piece.ptype() == PAWN)
2055  continue;
2056  if (!piece.isOnBoard())
2057  continue;
2058 
2059  const int idx = index(piece.owner(), piece.ptype(), piece.square().y(),
2060  pawns[piece.owner()][piece.square().x() - 1]);
2061  if (piece.owner() == BLACK)
2062  {
2063  result += table[idx];
2064  }
2065  else
2066  {
2067  result -= table[idx];
2068  }
2069  }
2070 
2071  return result;
2072 }
2073 
2074 template<osl::Player P>
2077  Move moved,
2078  const CArray2d<int, 2, 9> &pawns,
2079  MultiInt& last_value)
2080 {
2081  Ptype captured = moved.capturePtype();
2082  assert(P==moved.player());
2083 
2084  if (moved.oldPtype() == PAWN)
2085  {
2086  const int x = moved.to().x();
2087  const int old_pawn_y = (moved.isDrop() ? 0 : moved.from().y());
2088  const int new_pawn_y = pawns[P][moved.to().x() - 1];
2089  for (int y = 1; y <= 9; ++y)
2090  {
2091  const Piece p = state.pieceAt(Square(x, y));
2092  if (y == moved.to().y())
2093  {
2094  if (p.ptype() == PPAWN)
2095  {
2096  const int idx_new = index(P, p.ptype(), y, new_pawn_y);
2097  if (P == BLACK)
2098  {
2099  last_value += table[idx_new];
2100  }
2101  else
2102  {
2103  last_value -= table[idx_new];
2104  }
2105  }
2106  }
2107  else if (!p.isEmpty() && p.owner() == P)
2108  {
2109  const int idx_old = index(P, p.ptype(), y, old_pawn_y);
2110  const int idx_new = index(P, p.ptype(), y, new_pawn_y);
2111  if (P == BLACK)
2112  {
2113  last_value -= table[idx_old];
2114  last_value += table[idx_new];
2115  }
2116  else
2117  {
2118  last_value += table[idx_old];
2119  last_value -= table[idx_new];
2120  }
2121  }
2122  }
2123  }
2124  else
2125  {
2126  if (!moved.isDrop())
2127  {
2128  const int pawn_y = pawns[P][moved.from().x() - 1];
2129  const int idx = index(P, moved.oldPtype(), moved.from().y(),
2130  pawn_y);
2131  if (P == BLACK)
2132  {
2133  last_value -= table[idx];
2134  }
2135  else
2136  {
2137  last_value += table[idx];
2138  }
2139  }
2140  {
2141  const int pawn_y = pawns[P][moved.to().x() - 1];
2142  const int idx = index(P, moved.ptype(), moved.to().y(),
2143  pawn_y);
2144  if (P == BLACK)
2145  {
2146  last_value += table[idx];
2147  }
2148  else
2149  {
2150  last_value -= table[idx];
2151  }
2152  }
2153  }
2154 
2155  if (captured != PTYPE_EMPTY)
2156  {
2157  if (captured == PAWN)
2158  {
2159  const int old_pawn_y = moved.to().y();
2160  const int new_pawn_y = 0;
2161  const int x = moved.to().x();
2162  for (int y = 1; y <= 9; ++y)
2163  {
2164  const Piece p = state.pieceAt(Square(x, y));
2165  if (!p.isEmpty() && p.owner() == alt(P))
2166  {
2167  const int idx_old = index(alt(P), p.ptype(), y,
2168  old_pawn_y);
2169  const int idx_new = index(alt(P), p.ptype(), y,
2170  new_pawn_y);
2171  if (P == BLACK)
2172  {
2173  last_value += table[idx_old];
2174  last_value -= table[idx_new];
2175  }
2176  else
2177  {
2178  last_value -= table[idx_old];
2179  last_value += table[idx_new];
2180  }
2181  }
2182  }
2183  }
2184  else
2185  {
2186  const int pawn_y = pawns[alt(P)][moved.to().x() - 1];
2187  const int idx = index(alt(P), captured, moved.to().y(),
2188  pawn_y);
2189  if (P == BLACK)
2190  {
2191  last_value += table[idx];
2192  }
2193  else
2194  {
2195  last_value -= table[idx];
2196  }
2197  }
2198  }
2199 }
2200 
2205 
2207 GoldAndSilverNearKing::setUp(const Weights &weights)
2208 {
2209  for (size_t i = 0; i < ONE_DIM; ++i)
2210  {
2211  for (int s=0; s<NStages; ++s)
2212  table[i][s] = weights.value(i + ONE_DIM*s);
2213  }
2214 }
2215 
2218 {
2219  for (size_t i = 0; i < ONE_DIM; ++i)
2220  {
2221  for (int s=0; s<NStages; ++s)
2223  weights.value(i + ONE_DIM*s);
2224  }
2225 }
2226 
2227 template <osl::Player P>
2230  const CArray2d<int, 2, 3> &gs_count)
2231 {
2232  MultiInt result;
2233  int total = 0;
2234  const Square king = state.kingSquare<P>();
2235  for (size_t i = 0; i < gs_count[0].size(); ++i)
2236  {
2237  total += gs_count[P][i];
2238  if (total != 0)
2239  {
2240  result += table[index<P>(king, i, total)];
2241  }
2242  }
2243  result += combination_table[
2244  indexCombination<P>(king, gs_count[P][0],
2245  gs_count[P][1], gs_count[P][2])];
2246  return P == BLACK ? result : -result;
2247 }
2248 
2251  const CArray2d<int, 2, 3> &gs_count)
2252 {
2253  return evalOne<BLACK>(state, gs_count) + evalOne<WHITE>(state, gs_count);
2254 }
2255 
2256 ␌
2259 
2261 PtypeCombination::setUp(const Weights &weights)
2262 {
2263  static CArray<MultiInt, 8192> orig_table;
2264  for (size_t i = 0; i < ONE_DIM; ++i)
2265  {
2266  for (int s = 0; s < NStages; ++s)
2267  {
2268  orig_table[i][s] = weights.value(i + ONE_DIM*s);
2269  }
2270  }
2271  for(int i=0;i<8192;i++){
2272  int pawn=(i>>12)&1;
2273  int ppawn=(i>>6)&1;
2274  int lance=(i>>11)&1;
2275  int plance=(i>>5)&1;
2276  int knight=(i>>10)&1;
2277  int pknight=(i>>4)&1;
2278  int silver=(i>>9)&1;
2279  int psilver=(i>>3)&1;
2280  int bishop=(i>>8)&1;
2281  int pbishop=(i>>2)&1;
2282  int rook=(i>>7)&1;
2283  int prook=(i>>1)&1;
2284  int gold=(i>>0)&1;
2285  int newIndex=ppawn|(plance<<1)|(pknight<<2)|(psilver<<3)|(pbishop<<4)|
2286  (prook<<5)|(gold<<6)|(pawn<<7)|(lance<<8)|(knight<<9)|(silver<<10)|
2287  (bishop<<11)|(rook<<12);
2288  table[newIndex]=orig_table[i];
2289  }
2290 }
2291 
2293 PtypeCombination::eval(unsigned int ptypeo_mask)
2294 {
2295  return evalOne<BLACK>(ptypeo_mask) + evalOne<WHITE>(ptypeo_mask);
2296 }
2297 
2298 ␌
2301 inline
2302 std::pair<int,int> osl::eval::ml::
2303 SilverFork::matchRook(const NumEffectState& state, Piece rook,
2304  const CArray<bool,2>& has_silver,
2305  Square& silver_drop)
2306 {
2307  const Square sq = rook.square();
2308  if (rook.isPromoted() || sq.isPieceStand())
2309  return std::make_pair(0,0);
2310  const Player owner = rook.owner();
2311  if (! has_silver[alt(owner)] || ! sq.canPromote(alt(owner)))
2312  return std::make_pair(0,0);
2313  const CArray<Offset,2> offset = {{
2314  Board_Table.getOffset(owner, UL), Board_Table.getOffset(owner, UR)
2315  }};
2316  for (size_t i=0; i<offset.size(); ++i) {
2317  const Square next = sq+offset[i], next2 = next+offset[i];
2318  if (! state.pieceAt(next).isEmpty() || state.hasEffectAt(owner, next))
2319  continue;
2320  const Piece p = state.pieceAt(next2);
2321  if (! p.isOnBoardByOwner(owner))
2322  continue;
2323  silver_drop = next;
2324  if (p.ptype() == ROOK)
2325  return std::make_pair(sign(owner), 0);
2326  if (p.ptype() == GOLD)
2327  return std::make_pair(sign(owner), state.hasEffectAt(owner, next2) ? 1 : 2);
2328  }
2329  return std::make_pair(0,0);
2330 }
2331 inline
2332 std::pair<int,int> osl::eval::ml::
2333 SilverFork::matchGold(const NumEffectState& state, Piece gold,
2334  const CArray<bool,2>& has_silver, Square& silver_drop)
2335 {
2336  const Square sq = gold.square();
2337  if (sq.isPieceStand())
2338  return std::make_pair(0,0);
2339  const Player owner = gold.owner();
2340  if (! has_silver[alt(owner)] || ! sq.canPromote(alt(owner)))
2341  return std::make_pair(0,0);
2342  const CArray<Offset,2> offset = {{
2344  }};
2345  const bool guarded = state.hasEffectAt(owner, sq);
2346  for (size_t i=0; i<offset.size(); ++i) {
2347  const Square next = sq+offset[i], next2 = next+offset[i];
2348  const Piece np = state.pieceAt(next);
2349  if (np.isEdge())
2350  continue;
2351  const Square next_down = next + Board_Table.getOffset(owner, D);
2352  if (! state.pieceAt(next_down).isEmpty() || state.hasEffectAt(owner, next_down))
2353  continue;
2354  const Piece p = state.pieceAt(next2);
2355  if (! p.isOnBoardByOwner(owner))
2356  continue;
2357  if (p.ptype() == ROOK || p.ptype() == GOLD) {
2358  silver_drop = next_down;
2359  const bool recaputure = guarded
2360  || (p.ptype() == GOLD && state.hasEffectAt(owner, next2))
2361  || (np.canMoveOn(owner) && ! state.hasEffectAt(alt(owner), next));
2362  return std::make_pair(sign(owner), 3 + recaputure);
2363  }
2364  }
2365  return std::make_pair(0,0);
2366 }
2367 
2369 SilverFork::eval(const NumEffectState& state, CArray<std::pair<Square,int>,2>& silver_drop)
2370 {
2371  silver_drop.fill(std::make_pair(Square(),0));
2372  MultiIntPair result; // by turn
2373  const CArray<bool,2> has_silver = {{
2374  state.hasPieceOnStand<SILVER>(BLACK),
2375  state.hasPieceOnStand<SILVER>(WHITE),
2376  }};
2377  if (! has_silver[BLACK] && ! has_silver[WHITE])
2378  return result;
2379  Square drop;
2380  for (int i = PtypeTraits<ROOK>::indexMin;
2381  i < PtypeTraits<ROOK>::indexLimit; ++i)
2382  {
2383  const Piece rook = state.pieceOf(i);
2384  std::pair<int,int> match = matchRook(state, rook, has_silver, drop);
2385  if (match.first) {
2386  const MultiInt value_attack = table[match.second*2];
2387  const Player attack = (match.first > 0) ? WHITE : BLACK;
2388  if (-value_attack[0] > silver_drop[attack].second) {
2389  silver_drop[attack].second = -value_attack[0];
2390  silver_drop[attack].first = drop;
2391  }
2392  if (match.first > 0) // owner is black
2393  {
2394  result[BLACK] += table[match.second*2+1];
2395  result[WHITE] += value_attack;
2396  }
2397  else if (match.first < 0) // owner is white
2398  {
2399  result[BLACK] -= value_attack;
2400  result[WHITE] -= table[match.second*2+1];
2401  }
2402  }
2403  }
2404 
2405  for (int i = PtypeTraits<GOLD>::indexMin;
2406  i < PtypeTraits<GOLD>::indexLimit; ++i)
2407  {
2408  const Piece gold = state.pieceOf(i);
2409  std::pair<int,int> match = matchGold(state, gold, has_silver, drop);
2410  if (match.first) {
2411  const MultiInt value_attack = table[match.second*2];
2412  const Player attack = (match.first > 0) ? WHITE : BLACK;
2413  if (-value_attack[0] > silver_drop[attack].second) {
2414  silver_drop[attack].second = -value_attack[0];
2415  silver_drop[attack].first = drop;
2416  }
2417  if (match.first > 0)
2418  {
2419  result[BLACK] += table[match.second*2+1];
2420  result[WHITE] += value_attack;
2421  }
2422  else if (match.first < 0)
2423  {
2424  result[BLACK] -= value_attack;
2425  result[WHITE] -= table[match.second*2+1];
2426  }
2427  }
2428  }
2429  return result;
2430 }
2431 
2433 {
2434  for (int i = 0; i < ONE_DIM; ++i)
2435  {
2436  for (int s=0; s<NStages; ++s)
2437  table[i][s] = weights.value(i + ONE_DIM*s);
2438  }
2439 }
2440 ␌
2444 {
2445  for (int i = 0; i < ONE_DIM; ++i)
2446  {
2447  for (int s=0; s<NStages; ++s)
2448  table[i][s] = weights.value(i + ONE_DIM*s);
2449  }
2450  for (int i=0; i<PTYPE_SIZE; ++i)
2451  for (int j=i+1; j<PTYPE_SIZE; ++j)
2452  {
2453  table[bishopIndex((Ptype)j,(Ptype)i)*2] = table[bishopIndex((Ptype)i,(Ptype)j)*2];
2454  table[bishopIndex((Ptype)j,(Ptype)i)*2+1] = table[bishopIndex((Ptype)i,(Ptype)j)*2+1];
2455  table[rookIndex((Ptype)j,(Ptype)i)*2] = table[rookIndex((Ptype)i,(Ptype)j)*2];
2456  table[rookIndex((Ptype)j,(Ptype)i)*2+1] = table[rookIndex((Ptype)i,(Ptype)j)*2+1];
2457  }
2458 }
2459 inline
2461 findDropInLine(const NumEffectState& state, Player defense,
2462  const Square a, const Square b, Piece king)
2463 {
2464  Offset offset = Board_Table.getShortOffset(Offset32(b,a));
2465  Square drop_position;
2466  Square sq=a+offset;
2467  for (Piece p=state.pieceAt(sq); p.isEmpty(); sq+=offset, p=state.pieceAt(sq))
2468  {
2469  if (! drop_position.isPieceStand())
2470  continue;
2471  if (! state.hasEffectAt(defense, sq)
2472  || (state.hasEffectAt(alt(defense), sq)
2473  && ! state.hasEffectNotBy(defense, king, sq)))
2474  drop_position = sq;
2475  }
2476  return (sq == b) ? drop_position : Square();
2477 }
2478 inline
2480 testCenter(const NumEffectState& state, Player defense,
2481  const Square a, const Square b, Piece king,
2482  Square center, bool maybe_empty)
2483 {
2484  const Piece p = state.pieceAt(center);
2485  if (! p.isEmpty()
2486  || (state.hasEffectAt(defense, center)
2487  && (! state.hasEffectAt(alt(defense), center)
2488  || state.hasEffectNotBy(defense, king, center))))
2489  return false;
2490  return state.isEmptyBetween(center, a, !maybe_empty)
2491  && state.isEmptyBetween(center, b, !maybe_empty);
2492 }
2493 
2496  const Square a, const Square b,
2497  bool maybe_empty)
2498 {
2499  const Piece king = state.kingPiece(defense);
2500  const int cx = b.x() - a.x(), cy = b.y() - a.y();
2501  if ((cx + cy) % 2)
2502  return Square();
2503  const int p = (cx+cy)/2, q = (cx-cy)/2;
2504  if (p == 0 || q == 0)
2505  return findDropInLine(state, defense, a, b, king);
2506 
2507  const CArray<Square,2> centers = {{
2508  b + Offset(-p,-p), b + Offset(-q,q)
2509  }};
2510 
2511  for (size_t i=0; i<centers.size(); ++i) {
2512  if (! centers[i].isOnBoardRegion())
2513  continue;
2514  if (testCenter(state, defense, a, b, king, centers[i], maybe_empty))
2515  return centers[i];
2516  }
2517  return Square();
2518 }
2519 
2520 inline
2523  const Square a, const Square b)
2524 {
2525  const Piece king = state.kingPiece(defense);
2526  const CArray<Square,2> centers = {{
2527  Square(a.x(), b.y()), Square(b.x(), a.y())
2528  }};
2529  if (centers[0] == a || centers[0] == b)
2530  return findDropInLine(state, defense, a, b, king);
2531  for (size_t i=0; i<centers.size(); ++i)
2532  {
2533  assert(centers[i].isOnBoardRegion());
2534  if (testCenter(state, defense, a, b, king, centers[i]))
2535  return centers[i];
2536  }
2537  return Square();
2538 }
2539 
2540 template <osl::Player Defense>
2542 BishopRookFork::evalOne(const NumEffectState &state, const PieceVector& target,
2543  std::pair<Square,int>& bishop_drop,
2544  std::pair<Square,int>& rook_drop)
2545 {
2546  MultiIntPair result;
2547  for (size_t i=0; i<target.size(); ++i)
2548  {
2549  const Piece pi = target[i];
2550  assert(pi.isOnBoardByOwner(Defense));
2551  for (size_t j=i+1; j<target.size(); ++j)
2552  {
2553  const Piece pj = target[j];
2554  assert(pj.isOnBoardByOwner(Defense));
2555  if (state.hasPieceOnStand<BISHOP>(alt(Defense)))
2556  {
2557  const Square center
2558  = isBishopForkSquare(state, Defense, pi.square(), pj.square());
2559  if (! center.isPieceStand()) {
2560  const int index = bishopIndex(pi.ptype(), pj.ptype())*2;
2561  const MultiInt value_attack = table[index];
2562  if (-value_attack[0] > bishop_drop.second) { // negative value is better for attacker
2563  bishop_drop.second = -value_attack[0];
2564  bishop_drop.first = center;
2565  }
2566  if (Defense == BLACK)
2567  {
2568  result[BLACK] += table[index+1];
2569  result[WHITE] += value_attack;
2570  }
2571  else
2572  {
2573  result[BLACK] -= value_attack;
2574  result[WHITE] -= table[index+1];
2575  }
2576  }
2577  }
2578  if (state.hasPieceOnStand<ROOK>(alt(Defense)))
2579  {
2580  const Square center
2581  = isRookForkSquare(state, Defense, pi.square(), pj.square());
2582  if (! center.isPieceStand()) {
2583  const int index = rookIndex(pi.ptype(), pj.ptype())*2;
2584  const MultiInt value_attack = table[index];
2585  if (-value_attack[0] > rook_drop.second) { // negative value is better for attacker
2586  rook_drop.second = -value_attack[0];
2587  rook_drop.first = center;
2588  }
2589  if (Defense == BLACK)
2590  {
2591  result[BLACK] += table[index+1];
2592  result[WHITE] += value_attack;
2593  }
2594  else
2595  {
2596  result[BLACK] -= value_attack;
2597  result[WHITE] -= table[index+1];
2598  }
2599  }
2600  }
2601  }
2602  }
2603  assert(bishop_drop.second == 0 || ! bishop_drop.first.isPieceStand());
2604  return result;
2605 }
2606 
2608 BishopRookFork::eval(const NumEffectState &state,
2609  CArray<std::pair<Square,int>,2>& bishop_drop,
2610  CArray<std::pair<Square,int>,2>& rook_drop)
2611 {
2612  bishop_drop.fill(std::make_pair(Square(),0));
2613  rook_drop.fill(std::make_pair(Square(),0));
2614  MultiIntPair result;
2615  const CArray<bool,2> has_bishop = {{
2616  state.hasPieceOnStand<BISHOP>(BLACK),
2617  state.hasPieceOnStand<BISHOP>(WHITE),
2618  }};
2619  const CArray<bool,2> has_rook = {{
2620  state.hasPieceOnStand<ROOK>(BLACK),
2621  state.hasPieceOnStand<ROOK>(WHITE),
2622  }};
2623  if (has_bishop[BLACK] + has_bishop[WHITE]
2624  + has_rook[BLACK] + has_rook[WHITE] == 0)
2625  return result;
2626  PieceMask notcovered = ~state.effectedMask(BLACK);
2627  notcovered &= ~state.effectedMask(WHITE);
2628  notcovered.clearBit<PAWN>();
2629  notcovered.setBit<KING>();
2630  if (has_bishop[WHITE] + has_rook[WHITE]) {
2631  PieceVector pieces;
2632  PieceMask target = notcovered & state.piecesOnBoard(BLACK);
2633  while (target.any())
2634  pieces.push_back(state.pieceOf(target.takeOneBit()));
2635  result += evalOne<BLACK>(state, pieces, bishop_drop[WHITE], rook_drop[WHITE]);
2636  }
2637  if (has_bishop[BLACK] + has_rook[BLACK]) {
2638  PieceVector pieces;
2639  PieceMask target = notcovered & state.piecesOnBoard(WHITE);
2640  while (target.any())
2641  pieces.push_back(state.pieceOf(target.takeOneBit()));
2642  result += evalOne<WHITE>(state, pieces, bishop_drop[BLACK], rook_drop[BLACK]);
2643  }
2644  return result;
2645 }
2646 
2647 ␌
2648 
2652 {
2653  for (int i = 0; i < ONE_DIM; ++i)
2654  {
2655  for (int s=0; s<NStages; ++s)
2656  table[i][s] = weights.value(i + ONE_DIM*s);
2657  }
2658  for (int i=0; i<PTYPE_SIZE; ++i)
2659  for (int j=i+1; j<PTYPE_SIZE; ++j) {
2660  table[index((Ptype)j,(Ptype)i)*2] = table[index((Ptype)i,(Ptype)j)*2];
2661  table[index((Ptype)j,(Ptype)i)*2+1] = table[index((Ptype)i,(Ptype)j)*2+1];
2662  table[(index((Ptype)j,(Ptype)i)+DROP_DIM)*2] = table[(index((Ptype)i,(Ptype)j)+DROP_DIM)*2];
2663  table[(index((Ptype)j,(Ptype)i)+DROP_DIM)*2+1] = table[(index((Ptype)i,(Ptype)j)+DROP_DIM)*2+1];
2664  }
2665 }
2666 
2667 template <osl::Player Defense>
2669 KnightFork::evalOne(const NumEffectState &state, bool has_knight,
2670  BoardMask& knight_fork_squares,
2671  std::pair<Square,int>& knight_drop)
2672 {
2673  knight_fork_squares.clear();
2674  const int z = playerToIndex(Defense);
2675  const int y_min = 3-z*2, y_max = 9-z*2;
2676  CArray<PieceVector,10> pieces;
2677  {
2678  PieceMask target = state.piecesOnBoard(Defense);
2679  target.clearBit<PAWN>();
2680  target.clearBit<LANCE>();
2681  target.clearBit<KNIGHT>();
2682  while (target.any()) {
2683  const Piece p = state.pieceOf(target.takeOneBit());
2684  const int y = p.square().y();
2685  pieces[y].push_back(p);
2686  }
2687  }
2688  MultiIntPair result;
2689  for (int y=y_min; y<=y_max; ++y){
2690  if (pieces[y].size() < 2)
2691  continue;
2692  const int y_drop = y - sign(Defense)*2;
2693  for (size_t i=0; i<pieces[y].size(); ++i)
2694  {
2695  const Piece pi = pieces[y][i];
2696  assert(pi.isOnBoardByOwner(Defense));
2697  assert(pi.square().y() == y);
2698  const int xi = pi.square().x();
2699  for (size_t j=i+1; j<pieces[y].size(); ++j)
2700  {
2701  const Piece pj = pieces[y][j];
2702  assert(pj.isOnBoardByOwner(Defense));
2703  assert(pj.square().y() == y);
2704  const int xj = pj.square().x();
2705  if (abs(xi -xj) != 2)
2706  continue;
2707  const Square drop = Square((xi+xj)/2, y_drop);
2708  knight_fork_squares.set(drop);
2709  if (! state[drop].isEmpty() || state.hasEffectAt(Defense, drop))
2710  continue;
2711  int found = index(pi.ptype(), pj.ptype());
2712  if (! has_knight)
2713  found += DROP_DIM;
2714  found *= 2;
2715  const MultiInt value_attack = table[found];
2716  if (Defense == BLACK)
2717  {
2718  result[BLACK] += table[found+1];
2719  result[WHITE] += value_attack;
2720  }
2721  else
2722  {
2723  result[BLACK] -= value_attack;
2724  result[WHITE] -= table[found+1];
2725  }
2726  if (has_knight && -value_attack[0] > knight_drop.second) {
2727  knight_drop.second = -value_attack[0];
2728  knight_drop.first = Square((pi.square().x()+pj.square().x())/2, y_drop);
2729  }
2730  }
2731  }
2732  }
2733  return result;
2734 }
2735 
2737 KnightFork::eval(const NumEffectState &state,
2738  CArray<BoardMask,2>& knight_fork_squares,
2739  CArray<std::pair<Square,int>,2>& knight_drop)
2740 {
2741  knight_drop.fill(std::make_pair(Square(),0));
2742  MultiIntPair result;
2743  const CArray<bool,2> has_knight = {{
2744  state.hasPieceOnStand<KNIGHT>(BLACK),
2745  state.hasPieceOnStand<KNIGHT>(WHITE),
2746  }};
2747 
2748  const CArray<bool,2> may_have_knight = {{
2749  has_knight[BLACK]
2750  || (state.effectedMask(BLACK).selectBit<KNIGHT>()
2751  & ~state.effectedMask(WHITE).selectBit<KNIGHT>()
2753  has_knight[WHITE]
2754  || (state.effectedMask(WHITE).selectBit<KNIGHT>()
2755  & ~state.effectedMask(BLACK).selectBit<KNIGHT>()
2757  }};
2758  if (has_knight[BLACK] + has_knight[WHITE]
2759  + may_have_knight[BLACK] + may_have_knight[WHITE] == 0) {
2760  knight_fork_squares[BLACK].invalidate();
2761  knight_fork_squares[WHITE].invalidate();
2762  return result;
2763  }
2764  {
2765  const Player Defense = BLACK;
2766  if (has_knight[alt(Defense)] + may_have_knight[alt(Defense)] > 0)
2767  result += evalOne<Defense>(state, has_knight[alt(Defense)],
2768  knight_fork_squares[alt(Defense)],
2769  knight_drop[alt(Defense)]);
2770  else
2771  knight_fork_squares[alt(Defense)].invalidate();
2772  }
2773  {
2774  const Player Defense = WHITE;
2775  if (has_knight[alt(Defense)] + may_have_knight[alt(Defense)] > 0)
2776  result += evalOne<Defense>(state, has_knight[alt(Defense)],
2777  knight_fork_squares[alt(Defense)],
2778  knight_drop[alt(Defense)]);
2779  else
2780  knight_fork_squares[alt(Defense)].invalidate();
2781  }
2782  return result;
2783 }
2784 
2785 template <osl::Player P, osl::Player Defense>
2787 KnightFork::updateSquares(const NumEffectState& state, Move moved,
2788  BoardMask& knight_fork_squares)
2789 {
2790  assert(! knight_fork_squares.isInvalid());
2791  const Square to = moved.to();
2792  if (P != Defense) {
2793  if (! moved.isCapture())
2794  return;
2795  if ((Defense == BLACK && to.y() >= 3)
2796  || (Defense == WHITE && to.y() <= 7)) {
2797  knight_fork_squares.reset(to.neighbor<Defense,UUL>());
2798  knight_fork_squares.reset(to.neighbor<Defense,UUR>());
2799  }
2800  return;
2801  }
2802  if (! moved.isDrop()) {
2803  if ((P == BLACK && moved.from().y() >= 3)
2804  || (P == WHITE && moved.from().y() <= 7)) {
2805  knight_fork_squares.reset(moved.from().neighbor<P,UUL>());
2806  knight_fork_squares.reset(moved.from().neighbor<P,UUR>());
2807  }
2808  }
2809  if (! isTarget(moved.ptype())
2810  || (P == BLACK && to.y() < 3) || (P == WHITE && to.y() > 7))
2811  return;
2812  if (to.x() <= 7)
2813  {
2814  const Square l = to.neighbor<BLACK,L>(), l2 = l.neighbor<BLACK,L>();
2815  if (state[l2].isOnBoardByOwner<P>()) {
2816  knight_fork_squares.set(l.neighbor<P,U>().template neighbor<P,U>());
2817  }
2818  }
2819  if (to.x() >= 3)
2820  {
2821  const Square r = to.neighbor<BLACK,R>(), r2 = r.neighbor<BLACK,R>();
2822  if (state[r2].isOnBoardByOwner<P>()){
2823  knight_fork_squares.set(r.neighbor<P,U>().template neighbor<P,U>());
2824  }
2825  }
2826 }
2827 
2828 template <osl::Player Defense>
2831  bool has_knight,
2832  const BoardMask& knight_fork_squares,
2833  std::pair<Square,int>& knight_drop)
2834 {
2835  MultiIntPair result;
2836  BoardMask mask = knight_fork_squares;
2837  while (mask.any()) {
2838  Square sq = mask.takeOneBit();
2839  if (! state[sq].isEmpty() || state.hasEffectAt(Defense, sq))
2840  continue;
2841  const Piece pi = state[sq.back<Defense,UUL>()];
2842  const Piece pj = state[sq.back<Defense,UUR>()];
2843  if (! pi.isOnBoardByOwner<Defense>() || ! pj.isOnBoardByOwner<Defense>())
2844  std::cerr << state << Defense << ' ' << pi << ' ' << pj << "\n";
2845  assert(pi.isOnBoardByOwner<Defense>());
2846  assert(pj.isOnBoardByOwner<Defense>());
2847  int found = index(pi.ptype(), pj.ptype());
2848  if (! has_knight)
2849  found += DROP_DIM;
2850  found *= 2;
2851  const MultiInt value_attack = table[found];
2852  if (Defense == BLACK)
2853  {
2854  result[BLACK] += table[found+1];
2855  result[WHITE] += value_attack;
2856  }
2857  else
2858  {
2859  result[BLACK] -= value_attack;
2860  result[WHITE] -= table[found+1];
2861  }
2862  if (has_knight && -value_attack[0] > knight_drop.second) {
2863  knight_drop.second = -value_attack[0];
2864  knight_drop.first = sq;
2865  }
2866  }
2867  return result;
2868 }
2869 
2870 template <osl::Player P>
2872 KnightFork::evalWithUpdate(const NumEffectState &state, Move moved,
2873  CArray<BoardMask,2>& knight_fork_squares,
2874  CArray<std::pair<Square,int>,2>& knight_drop)
2875 {
2876  knight_drop.fill(std::make_pair(Square(),0));
2877  MultiIntPair result;
2878  const CArray<bool,2> has_knight = {{
2879  state.hasPieceOnStand<KNIGHT>(BLACK),
2880  state.hasPieceOnStand<KNIGHT>(WHITE),
2881  }};
2882  const CArray<bool,2> may_have_knight = {{
2883  has_knight[BLACK]
2884  || (state.effectedMask(BLACK).selectBit<KNIGHT>()
2885  & ~state.effectedMask(WHITE).selectBit<KNIGHT>()
2887  has_knight[WHITE]
2888  || (state.effectedMask(WHITE).selectBit<KNIGHT>()
2889  & ~state.effectedMask(BLACK).selectBit<KNIGHT>()
2891  }};
2892  if (has_knight[BLACK] + has_knight[WHITE]
2893  + may_have_knight[BLACK] + may_have_knight[WHITE] == 0) {
2894  knight_fork_squares[BLACK].invalidate();
2895  knight_fork_squares[WHITE].invalidate();
2896  return result;
2897  }
2898  {
2899  const Player Defense = BLACK;
2900  if (has_knight[alt(Defense)] + may_have_knight[alt(Defense)] > 0) {
2901  if (knight_fork_squares[alt(Defense)].isInvalid())
2902  result += evalOne<Defense>(state, has_knight[alt(Defense)],
2903  knight_fork_squares[alt(Defense)],
2904  knight_drop[alt(Defense)]);
2905  else {
2906  updateSquares<P,Defense>(state, moved, knight_fork_squares[alt(Defense)]);
2907  result += accumulate<Defense>(state, has_knight[alt(Defense)],
2908  knight_fork_squares[alt(Defense)],
2909  knight_drop[alt(Defense)]);
2910  }
2911  }
2912  else
2913  knight_fork_squares[alt(Defense)].invalidate();
2914  }
2915  {
2916  const Player Defense = WHITE;
2917  if (has_knight[alt(Defense)] + may_have_knight[alt(Defense)] > 0) {
2918  if (knight_fork_squares[alt(Defense)].isInvalid())
2919  result += evalOne<Defense>(state, has_knight[alt(Defense)],
2920  knight_fork_squares[alt(Defense)],
2921  knight_drop[alt(Defense)]);
2922  else {
2923  updateSquares<P,Defense>(state, moved, knight_fork_squares[alt(Defense)]);
2924  result += accumulate<Defense>(state, has_knight[alt(Defense)],
2925  knight_fork_squares[alt(Defense)],
2926  knight_drop[alt(Defense)]);
2927  }
2928  }
2929  else
2930  knight_fork_squares[alt(Defense)].invalidate();
2931  }
2932  return result;
2933 }
2934 
2935 ␌
2937 {
2938  for (size_t i = 0; i < ONE_DIM; ++i)
2939  {
2940  for (int s=0; s<NStages; ++s)
2941  table[i][s] = weights.value(i + ONE_DIM*s);
2942  }
2943 }
2946 {
2947  const CArray<std::pair<Square,Ptype>,5> pattern = {{
2948  std::make_pair( Square(2,6), SILVER ),
2949  std::make_pair( Square(1,5), PAWN ),
2950  std::make_pair( Square(3,7), KNIGHT ),
2951  std::make_pair( Square(2,5), PAWN ),
2952  std::make_pair( Square(3,6), PAWN ),
2953  }};
2954  MultiInt sum;
2955  bool match = state.kingSquare(BLACK).x() >= 5;
2956  if (match) {
2957  for (size_t i=0; i<pattern.size(); ++i) {
2958  const Piece p = state.pieceAt(pattern[i].first);
2959  if (p.ptype() != pattern[i].second || p.owner() != BLACK) {
2960  match = false;
2961  break;
2962  }
2963  }
2964  if (match)
2965  sum += table[0];
2966  }
2967  match = state.kingSquare(WHITE).x() <= 5;
2968  if (match) {
2969  for (size_t i=0; i<pattern.size(); ++i) {
2970  const Piece p = state.pieceAt(pattern[i].first.rotate180());
2971  if (p.ptype() != pattern[i].second || p.owner() != WHITE) {
2972  match = false;
2973  break;
2974  }
2975  }
2976  if (match)
2977  sum += -table[0];
2978  }
2979  return sum;
2980 }
2981 
2982 ␌
2983 
2987 {
2988  for (size_t i = 0; i < ONE_DIM; ++i)
2989  {
2990  for (int s=0; s<NStages; ++s)
2991  table[i][s] = weights.value(i + ONE_DIM*s);
2992  }
2993 }
2994 
2995 template <osl::Player P>
2997 Promotion37::evalOne(const NumEffectState &state, int rank)
2998 {
2999  CArray<int,PTYPE_SIZE> count = {{ 0 }};
3000  for (int x=1; x<=9; ++x) {
3001  const Square target(x, rank);
3002  if (! state[target].isEmpty())
3003  continue;
3004  int a = state.countEffect(P, target);
3005  const int d = state.countEffect(alt(P), target);
3006  if (a > 0 && a == d)
3007  a += AdditionalEffect::hasEffect(state, target, P);
3008  if (a <= d)
3009  continue;
3010  const Ptype ptype = state.findCheapAttack(P, target).ptype();
3011  if (isPiece(ptype) && ! isPromoted(ptype))
3012  count[ptype]++;
3013  }
3014  MultiInt ret;
3015  for (int p=PTYPE_BASIC_MIN; p<=PTYPE_MAX; ++p) {
3016  if (count[p] > 0)
3017  ret += table[p]*sign(P);
3018  if (count[p] > 1)
3019  ret += table[p-8]*(sign(P)*(count[p]-1));
3020  }
3021  return ret;
3022 }
3023 
3025 Promotion37::eval(const NumEffectState &state)
3026 {
3027  return evalOne<BLACK>(state, 3) + evalOne<WHITE>(state, 7);
3028 }
3029 
3030 template <osl::Player P>
3032 Promotion37::evalWithUpdate(const NumEffectState& state, Move moved,
3033  MultiInt const& last_value)
3034 {
3035  if (moved.isPass())
3036  return last_value;
3037  // todo changedEffects
3038  return eval(state);
3039 }
3040 
3041 ␌
3042 namespace osl
3043 {
3044  namespace eval
3045  {
3046  namespace ml
3047  {
3048  template void PawnAdvanceAll::
3049  evalWithUpdateBang<BLACK>(const NumEffectState &, Move,MultiInt&);
3050  template void PawnAdvanceAll::
3051  evalWithUpdateBang<WHITE>(const NumEffectState &, Move,MultiInt&);
3052  template MultiInt PtypeY::
3053  evalWithUpdate<BLACK>(const NumEffectState &, Move, MultiInt const&);
3054  template MultiInt PtypeY::
3055  evalWithUpdate<WHITE>(const NumEffectState &, Move, MultiInt const&);
3056  template MultiInt PtypeX::
3057  evalWithUpdate<BLACK>(const NumEffectState &, Move, MultiInt const&);
3058  template MultiInt PtypeX::
3059  evalWithUpdate<WHITE>(const NumEffectState &, Move, MultiInt const&);
3060  template MultiInt PawnPtypeOPtypeO::
3061  evalWithUpdate<BLACK>(const NumEffectState &, Move, const CArray2d<int, 2, 9> &, MultiInt const&);
3062  template MultiInt PawnPtypeOPtypeO::
3063  evalWithUpdate<WHITE>(const NumEffectState &, Move, const CArray2d<int, 2, 9> &, MultiInt const&);
3064 
3065  template void osl::eval::ml::NonPawnAttacked::
3066  evalWithUpdateBang<BLACK>(const NumEffectState &state,
3067  Move moved,
3068  const CArray<PieceMask, 2> &effected,
3069  MultiIntPair &result);
3070  template void osl::eval::ml::NonPawnAttacked::
3071  evalWithUpdateBang<WHITE>(const NumEffectState &state,
3072  Move moved,
3073  const CArray<PieceMask, 2> &effected,
3074  MultiIntPair &result);
3075  template void osl::eval::ml::NonPawnAttackedPtype::
3076  evalWithUpdateBang<BLACK>(
3077  const NumEffectState &state,
3078  Move moved,
3079  const CArray<PieceMask, 2> &effected,
3080  CArray<PieceMask, 40> &attacked_mask,
3081  MultiIntPair &result);
3082  template void osl::eval::ml::NonPawnAttackedPtype::
3083  evalWithUpdateBang<WHITE>(
3084  const NumEffectState &state,
3085  Move moved,
3086  const CArray<PieceMask, 2> &effected,
3087  CArray<PieceMask, 40> &attacked_mask,
3088  MultiIntPair &result);
3089  template void osl::eval::ml::PtypeYPawnY::
3090  evalWithUpdateBang<BLACK>(const NumEffectState &state,
3091  Move moved,
3092  const CArray2d<int, 2, 9> &pawns,
3093  MultiInt& last_value);
3094  template void osl::eval::ml::PtypeYPawnY::
3095  evalWithUpdateBang<WHITE>(const NumEffectState &state,
3096  Move moved,
3097  const CArray2d<int, 2, 9> &pawns,
3098  MultiInt& last_value);
3099  template void PtypeCount::
3100  evalWithUpdateBang<BLACK>(const NumEffectState &state,Move last_move,
3101  CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
3102  CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
3103  MultiInt &last_value_and_out,
3104  unsigned int &ptypeo_mask);
3105  template void PtypeCount::
3106  evalWithUpdateBang<WHITE>(const NumEffectState &state,Move last_move,
3107  CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
3108  CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
3109  MultiInt &last_value_and_out,
3110  unsigned int &ptypeo_mask);
3111 
3112  template MultiIntPair KnightFork::
3113  evalWithUpdate<BLACK>(const NumEffectState&, Move, CArray<BoardMask,2>&,
3114  CArray<std::pair<Square,int>,2>&);
3115  template MultiIntPair KnightFork::
3116  evalWithUpdate<WHITE>(const NumEffectState&, Move, CArray<BoardMask,2>&,
3117  CArray<std::pair<Square,int>,2>&);
3118  }
3119  }
3120 }
3121 // ;;; Local Variables:
3122 // ;;; mode:c++
3123 // ;;; c-basic-offset:2
3124 // ;;; End:
const Offset getOffset(Direction dir) const
Definition: boardTable.h:47
const Offset getShortOffset(Offset32 offset32) const
Longの利きの可能性のあるoffsetの場合は, 反復に使う offsetを Shortの利きのoffsetの場合はそれ自身を返す.
Definition: boardTable.h:110
const Square nextSquare(Player P, Square pos, Direction dr) const
next position from pos for player P.
Definition: boardTable.h:61
static size_t size()
Definition: container.h:76
size_t size() const
Definition: container.h:243
void push_back(const T &e)
Definition: container.h:204
圧縮していない moveの表現 .
Definition: basic_type.h:1052
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
Definition: basic_type.h:1162
bool isPromotion() const
Definition: basic_type.h:1147
Ptype ptype() const
Definition: basic_type.h:1155
Player player() const
Definition: basic_type.h:1195
PtypeO oldPtypeO() const
移動前のPtypeO, i.e., 成る手だった場合成る前
Definition: basic_type.h:1168
bool isDrop() const
Definition: basic_type.h:1150
bool isPass() const
Definition: basic_type.h:1092
Ptype capturePtype() const
Definition: basic_type.h:1180
PtypeO capturePtypeO() const
Definition: basic_type.h:1185
PtypeO capturePtypeOSafe() const
Definition: basic_type.h:1189
Ptype oldPtype() const
移動前のPtype, i.e., 成る手だった場合成る前
Definition: basic_type.h:1174
bool isCapture() const
Definition: basic_type.h:1148
const Square to() const
Definition: basic_type.h:1132
const Square from() const
Definition: basic_type.h:1125
利きを持つ局面
const NumBitmapEffect effectSetAt(Square sq) const
const PieceMask effectedMask(Player pl) const
pl からの利きが(1つ以上)ある駒一覧
bool hasEffectNotBy(Player player, Piece piece, Square target) const
対象とするマスにあるプレイヤーの(ただしある駒以外)利きがあるかどうか.
int countEffect(Player player, Square target) const
利きの数を数える.
const PieceMask & piecesOnBoard(Player p) const
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
const Piece findCheapAttack(Player P, Square square) const
Square mobilityOf(Direction d, int num) const
const PieceMask promotedPieces() const
bool hasEffectByPtypeStrict(Player attack, Square target) const
target に ptype の利きがあるか? 成不成を区別
座標の差分
Definition: basic_type.h:430
駒番号のビットセット.
Definition: pieceMask.h:21
const mask_t getMask(int num) const
Definition: pieceMask.h:59
void clearBit()
unpromote(PTYPE) の駒のbit を消す
Definition: pieceMask.h:74
bool test(int num) const
Definition: pieceMask.h:45
void orMask(int index, mask_t val)
Definition: pieceMask.h:42
void setBit()
unpromote(PTYPE) の駒のbit を立てる
Definition: pieceMask.h:81
bool any() const
Definition: pieceMask.h:57
const mask_t selectBit() const
unpromote(PTYPE) の駒のbit だけ取り出す
Definition: pieceMask.h:66
void reset(int num)
Definition: pieceMask.h:54
PtypeO ptypeO() const
Definition: basic_type.h:824
Ptype ptype() const
Definition: basic_type.h:821
bool isPromoted() const
promoteした駒かどうかをチェックする
Definition: basic_type.h:898
const Square square() const
Definition: basic_type.h:832
bool isEmpty() const
Definition: basic_type.h:913
bool isEdge() const
Definition: basic_type.h:919
Player owner() const
Definition: basic_type.h:963
bool isPiece() const
Definition: basic_type.h:953
bool isPlayerPtype(Player pl, Ptype ptype) const
あるpieceがPlayer pの持ち物でPtype ptypeであるかどうかをチェックする. TはEMPTY, EDGEではない.
Definition: basic_type.h:937
bool canMoveOn() const
Player Pの駒が,thisの上に移動できるか? PIECE_EMPTY 0x00008000 BLACK_PIECE 0x000XxxYY X>=2, YY>0 PIECE_EDGE 0xfff1...
Definition: basic_type.h:980
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition: basic_type.h:852
int number() const
Definition: basic_type.h:828
bool isOnBoard() const
Definition: basic_type.h:985
static const int SIZE
Definition: basic_type.h:794
int getIndexLimit(Ptype ptype) const
Definition: ptypeTable.h:93
int getIndexMin(Ptype ptype) const
Definition: ptypeTable.h:88
bool hasPieceOnStand(Player player, Ptype ptype) const
Definition: simpleState.h:191
const Piece kingPiece() const
Definition: simpleState.h:83
const Piece pieceOf(int num) const
Definition: simpleState.h:76
bool isEmptyBetween(Square from, Square to, Offset offset, bool pieceExistsAtTo=false) const
Definition: simpleState.h:267
Square kingSquare() const
Definition: simpleState.h:94
bool isPawnMaskSet(Player player, int x) const
Definition: simpleState.h:146
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
bool isPieceStand() const
Definition: basic_type.h:576
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
const Square neighbor() const
Definition: basic_type.h:746
bool canPromote() const
Definition: basic_type.h:659
const Square back() const
Definition: basic_type.h:750
bool isOnBoard() const
盤面上を表すかどうかの判定. 1<=x() && x()<=9 && 1<=y() && y()<=9 Squareの内部表現に依存する.
Definition: basic_type.h:583
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
void reset(unsigned int i)
Definition: boardMask.h:47
void set(unsigned int i)
Definition: boardMask.h:40
bool isInvalid() const
Definition: boardMask.h:39
static MultiInt weight
Definition: minorPiece.h:729
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:507
static const Square isRookForkSquare(const NumEffectState &state, Player defense, const Square a, const Square b)
Definition: minorPiece.cc:2522
static MultiIntPair eval(const NumEffectState &state, CArray< std::pair< Square, int >, 2 > &bishop_drop, CArray< std::pair< Square, int >, 2 > &rook_drop)
Definition: minorPiece.cc:2608
static MultiIntPair evalOne(const NumEffectState &state, const PieceVector &target, std::pair< Square, int > &bishop_drop, std::pair< Square, int > &rook_drop)
static bool testCenter(const NumEffectState &state, Player defense, const Square a, const Square b, Piece king, Square center, bool maybe_empty=false)
Definition: minorPiece.cc:2480
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2443
static const Square isBishopForkSquare(const NumEffectState &state, Player defense, const Square a, const Square b, bool maybe_empty=false)
Definition: minorPiece.cc:2495
static const Square findDropInLine(const NumEffectState &state, Player defense, const Square a, const Square b, Piece king)
Definition: minorPiece.cc:2461
static CArray< MultiInt, ONE_DIM > table
Definition: minorPiece.h:1657
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2217
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2207
static MultiInt eval(const NumEffectState &state, const CArray2d< int, 2, 3 > &gs_count)
Definition: minorPiece.cc:2250
static CArray< MultiInt, 9720 > combination_table
Definition: minorPiece.h:1592
static CArray< MultiInt, 1215 > table
Definition: minorPiece.h:1591
static MultiInt evalOne(const NumEffectState &state, const CArray2d< int, 2, 3 > &gs_count)
static CArray< MultiInt, 14 > side_table
Definition: minorPiece.h:672
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:397
static CArray< MultiInt, 153 > knight_table
Definition: minorPiece.h:670
static bool canRetreat(const NumEffectState &state, const Piece gold)
Definition: minorPiece.cc:423
static CArray< MultiInt, 9 > retreat_table
Definition: minorPiece.h:671
static void setUp(const Weights &weights)
Definition: minorPiece.cc:377
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:443
static void setUp(const Weights &weights)
Definition: minorPiece.cc:387
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:476
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:483
static bool cantAdvance(const NumEffectState &state, const Piece knight)
Definition: minorPiece.cc:457
static CArray< MultiInt, 9 > table
Definition: minorPiece.h:701
static void setUp(const Weights &weights)
Definition: minorPiece.cc:642
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:636
static MultiInt weight
Definition: minorPiece.h:814
static CArray< MultiInt, 9 > y_table
Definition: minorPiece.h:820
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:652
static CArray< MultiInt, ONE_DIM > table
Definition: minorPiece.h:1688
static MultiIntPair eval(const NumEffectState &state, CArray< BoardMask, 2 > &knight_fork_squares, CArray< std::pair< Square, int >, 2 > &knight_drop)
Definition: minorPiece.cc:2737
static MultiIntPair evalWithUpdate(const NumEffectState &state, Move moved, CArray< BoardMask, 2 > &knight_fork_squares, CArray< std::pair< Square, int >, 2 > &knight_drop)
static void updateSquares(const NumEffectState &state, Move moved, BoardMask &knight_fork_squares)
Definition: minorPiece.cc:2787
static MultiIntPair evalOne(const NumEffectState &state, bool has_knight, BoardMask &knight_fork_squares, std::pair< Square, int > &knight_drop)
static MultiIntPair accumulate(const NumEffectState &state, bool has_knight, const BoardMask &knight_fork_squares, std::pair< Square, int > &knight_drop)
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2651
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1376
static CArray< MultiInt, 144 > opp_table
Definition: minorPiece.h:839
static CArray< MultiInt, 9 > table
Definition: minorPiece.h:838
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:1386
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1366
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1967
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:1980
static CArray< MultiInt, 9792 > table
Definition: minorPiece.h:1535
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:204
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1111
static CArray< MultiInt, ONE_DIM > table
Definition: minorPiece.h:1371
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1643
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:1685
static MultiInt evalOne(const NumEffectState &state)
static void evalWithUpdateBang(const NumEffectState &state, Move moved, const CArray< PieceMask, 2 > &effected_mask, CArray< PieceMask, 40 > &attacked_mask, MultiIntPair &last_value_and_out)
Definition: minorPiece.cc:1506
static CArray< MultiInt, 1024 > table
Definition: minorPiece.h:1344
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1442
static void eval(const NumEffectState &state, CArray< PieceMask, 40 > &attacked_mask, MultiIntPair &out)
Definition: minorPiece.cc:1452
static CArray< MultiInt, 19584 > king_table
Definition: minorPiece.h:1075
static void eval(const NumEffectState &state, MultiIntPair &out)
Definition: minorPiece.cc:1156
static void adjust(int black_turn_king_attack, int black_turn_king_defense, int white_turn_king_attack, int white_turn_king_defense, MultiIntPair &result)
Definition: minorPiece.cc:1135
static CArray< MultiInt, 64 > table
Definition: minorPiece.h:1074
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1102
static void evalWithUpdateBang(const NumEffectState &state, Move moved, const CArray< PieceMask, 2 > &effected_mask, MultiIntPair &last_value_and_out)
Definition: minorPiece.cc:1240
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:221
static CArray< MultiInt, 9 > table
Definition: minorPiece.h:532
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:214
static CArray< MultiInt, 81 > defense_y_table
Definition: minorPiece.h:45
static CArray< MultiInt, 90 > x_stand_table
Definition: minorPiece.h:48
static CArray< MultiInt, 90 > x_table
Definition: minorPiece.h:46
static CArray< MultiInt, 162 > y_stand_table
Definition: minorPiece.h:49
static CArray< MultiInt, 81 > attack_y_table
Definition: minorPiece.h:45
static CArray< MultiInt, 9 > attack_table
Definition: minorPiece.h:44
static CArray< MultiInt, 36 > state_king_relative_table
Definition: minorPiece.h:51
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:100
static CArray< MultiInt, 10 > drop_non_drop_table
Definition: minorPiece.h:50
static CArray< MultiInt, 9 > defense_table
Definition: minorPiece.h:44
static CArray< MultiInt, 18 > stand_table
Definition: minorPiece.h:47
static void setUp(const Weights &weights)
Definition: minorPiece.cc:82
static void setUp(const Weights &weights)
Definition: minorPiece.cc:65
static void setUp(const Weights &weights)
Definition: minorPiece.cc:73
static void setUp(const Weights &weights)
Definition: minorPiece.cc:56
static void setUp(const Weights &weights)
Definition: minorPiece.cc:6
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:47
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:38
static void setUp(const Weights &weights)
Definition: minorPiece.cc:682
static void setUp(const Weights &weights)
Definition: minorPiece.cc:672
static CArray< MultiInt, 9216 > y_table
Definition: minorPiece.h:878
static MultiInt evalWithUpdate(const NumEffectState &state, Move moved, const CArray2d< int, 2, 9 > &pawns, const MultiInt &last_value)
Definition: minorPiece.cc:727
static CArray< MultiInt, 1024 > table
Definition: minorPiece.h:877
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:692
static void setUp(const Weights &weights)
Definition: minorPiece.cc:91
static void setUp(const Weights &weights)
Definition: minorPiece.cc:974
static void setUp(const Weights &weights)
Definition: minorPiece.cc:964
static CArray< MultiInt, 9 > table
Definition: minorPiece.h:906
static void adjust(int index, int index_attack, int index_defense, MultiInt &result)
Definition: minorPiece.cc:985
static MultiInt evalWithUpdate(const NumEffectState &state, Move moved, const MultiInt &last_values)
Definition: minorPiece.cc:1084
static void evalOne(const NumEffectState &state, const PieceMask promoted, MultiInt &result)
Definition: minorPiece.cc:995
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:1069
static CArray< MultiInt, 162 > y_table
Definition: minorPiece.h:907
static MultiInt evalWithUpdate(const NumEffectState &, Move moved, MultiInt const &last_value)
static MultiInt evalOne(const NumEffectState &state, int rank)
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:3025
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2986
static CArray< MultiInt, ONE_DIM > table
Definition: minorPiece.h:1735
static MultiInt eval(unsigned int ptypeo_mask)
Definition: minorPiece.cc:2293
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2261
static CArray< MultiInt, 8192 > table
Definition: minorPiece.h:1621
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1752
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1710
static CArray< MultiInt, 2240 > xy_attack_table
Definition: minorPiece.h:1498
static MultiInt evalPlayerPtype(const CArray2d< int, 2, PTYPE_SIZE > &ptype_count, const CArray2d< int, 2, PTYPE_SIZE > &ptype_board_count, const osl::CArray< int, 2 > &kings_x, const osl::CArray< int, 2 > &kings_y)
static void setUp(const Weights &weights)
Definition: minorPiece.cc:1701
static CArray< MultiInt, 2240 > xy_table_diff
Definition: minorPiece.h:1499
static void eval(const NumEffectState &state, const CArray2d< int, 2, PTYPE_SIZE > &ptype_count, const CArray2d< int, 2, PTYPE_SIZE > &ptype_board_count, MultiInt &out)
Definition: minorPiece.cc:1843
static CArray< MultiInt, 160 > table
Definition: minorPiece.h:1496
static CArray< MultiInt, 2240 > xy_table
Definition: minorPiece.h:1497
static void evalWithUpdateBang(const NumEffectState &state, Move last_move, CArray2d< int, 2, PTYPE_SIZE > &ptype_count, CArray2d< int, 2, PTYPE_SIZE > &ptype_board_count, MultiInt &last_value_and_out, unsigned int &ptypeo_mask)
Definition: minorPiece.cc:1888
static CArray< MultiInt, 2240 > xy_attack_table_diff
Definition: minorPiece.h:1500
static MultiInt evalWithUpdate(const NumEffectState &, Move moved, MultiInt const &last_value)
Definition: minorPiece.cc:605
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:579
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:587
static CArray< MultiInt, 80 > table
Definition: minorPiece.h:764
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2034
static void evalWithUpdateBang(const NumEffectState &state, Move moved, const CArray2d< int, 2, 9 > &pawns, MultiInt &last_value)
Definition: minorPiece.cc:2076
static CArray< MultiInt, 1440 > table
Definition: minorPiece.h:1560
static MultiInt eval(const NumEffectState &state, const CArray2d< int, 2, 9 > &pawns)
Definition: minorPiece.cc:2046
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:517
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:525
static MultiInt evalWithUpdate(const NumEffectState &, Move moved, MultiInt const &last_value)
Definition: minorPiece.cc:543
static CArray< MultiInt, 144 > table
Definition: minorPiece.h:742
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:2945
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2936
static CArray< MultiInt, ONE_DIM > table
Definition: minorPiece.h:1720
static MultiInt eval(const NumEffectState &state)
Definition: minorPiece.cc:312
static CArray< MultiInt, 9 > retreat_table
Definition: minorPiece.h:582
static CArray< MultiInt, 153 > head_table
Definition: minorPiece.h:581
static bool canRetreat(const NumEffectState &state, const Piece silver)
Definition: minorPiece.cc:335
static std::pair< int, int > matchGold(const NumEffectState &state, Piece gold, const CArray< bool, 2 > &has_silver, Square &silver_drop)
Definition: minorPiece.cc:2333
static std::pair< int, int > matchRook(const NumEffectState &state, Piece rook, const CArray< bool, 2 > &has_silver, Square &silver_drop)
Definition: minorPiece.cc:2303
static CArray< MultiInt, ONE_DIM > table
Definition: minorPiece.h:1636
static void setUp(const Weights &weights)
Definition: minorPiece.cc:2432
static MultiIntPair eval(const NumEffectState &state, CArray< std::pair< Square, int >, 2 > &silver_drop)
Definition: minorPiece.cc:2369
static void setUp(const Weights &weights)
Definition: minorPiece.cc:302
static void setUp(const Weights &weights, int stage)
Definition: minorPiece.cc:361
CArray< PiecePair::IndexTable, 10 > & y_table
Definition: piecePair.cc:36
GeneralMask< mask_int_t > mask_t
Definition: mask.h:351
const PtypeO PTYPEO_EMPTY
Definition: basic_type.h:303
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:84
@ PTYPE_MAX
Definition: basic_type.h:105
@ ROOK
Definition: basic_type.h:100
@ PPAWN
Definition: basic_type.h:87
@ BISHOP
Definition: basic_type.h:99
@ PAWN
Definition: basic_type.h:95
@ KING
Definition: basic_type.h:93
@ KNIGHT
Definition: basic_type.h:97
@ PTYPE_EMPTY
Definition: basic_type.h:85
@ SILVER
Definition: basic_type.h:98
@ PTYPE_BASIC_MIN
Definition: basic_type.h:103
@ GOLD
Definition: basic_type.h:94
@ LANCE
Definition: basic_type.h:96
const PtypeTable Ptype_Table
Definition: tables.cc:97
const int PTYPE_SIZE
Definition: basic_type.h:107
QuadIntPair MultiIntPair
Definition: midgame.h:14
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition: basic_type.h:157
constexpr int playerToIndex(Player player)
Definition: basic_type.h:16
const int NStages
Definition: midgame.h:11
const BoardTable Board_Table
Definition: tables.cc:95
@ R
Definition: basic_type.h:317
@ D
Definition: basic_type.h:319
@ UUR
Definition: basic_type.h:323
@ UUL
Definition: basic_type.h:322
@ UL
Definition: basic_type.h:313
@ U
Definition: basic_type.h:314
@ L
Definition: basic_type.h:316
@ UR
Definition: basic_type.h:315
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
Definition: basic_type.h:137
QuadInt MultiInt
Definition: midgame.h:13
Offset32Base< 8, 9 > Offset32
Definition: offset32.h:63
constexpr int sign(Player player)
Definition: basic_type.h:23
Player
Definition: basic_type.h:8
@ WHITE
Definition: basic_type.h:10
@ BLACK
Definition: basic_type.h:9
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
Definition: basic_type.h:120
const PtypeO PTYPEO_EDGE __attribute__((unused))
bool isMajor(Ptype ptype)
Definition: basic_type.h:185
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
@ PTYPEO_MIN
Definition: basic_type.h:200
constexpr Player alt(Player player)
Definition: basic_type.h:13
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
Definition: basic_type.h:264
static bool hasEffect(const NumEffectState &, Square target, Player attack)
target に attack の追加利きが一つでもあるか. 相手の影利きが先にある場合は対象としない.
static void evalWithUpdateBang(const NumEffectState &state, Move moved, MultiInt &last_value)
Definition: minorPiece.cc:253
static void adjust(int index, MultiInt &values)
Definition: minorPiece.cc:243
size_t dimension() const
Definition: weights.h:29
int value(size_t index) const
Definition: weights.h:27