My Project
minorPiece.cc
Go to the documentation of this file.
3#include <iostream>
4using 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
38void 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
47void 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
204NoPawnOnStand::setUp(const Weights &weights,int stage)
205{
206 weight[stage] = weights.value(0);
207}
208
209
210
212
214PawnAdvance::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
241template <osl::Player P> inline
243PawnAdvanceAll::adjust(int index, MultiInt& values)
244{
245 if(P==BLACK)
246 values += PawnAdvance::table[index];
247 else
248 values -= PawnAdvance::table[index];
249}
250
251template <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>()}};
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
332template<osl::Player P>
333inline
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
361SilverRetreat::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
387GoldSideMove::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
420template<osl::Player P>
421inline
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
443GoldRetreat::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
454template<osl::Player P>
455inline
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
476KnightAdvance::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;
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
507AllGold::setUp(const Weights &weights,int stage)
508{
509 weight[stage] = weights.value(0);
510}
511
512
513
515
517PtypeY::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
541template<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
579PtypeX::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
603template<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
636void osl::eval::ml::KnightCheck::setUp(const Weights &weights,int stage)
637{
638 KnightCheck::weight[stage] = weights.value(0);
639}
640
642KnightCheckY::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
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
672PawnPtypeOPtypeO::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
682PawnPtypeOPtypeOY::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
721template<osl::Player P>
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 {
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
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
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
983template <int Sign>
985PromotedMinorPieces::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}
993template <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
1133template <int Sign>
1135NonPawnAttacked::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
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
1238template<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
1366KnightHead::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
1386KnightHead::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
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
1504template<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}
1655template <osl::Player Owner>
1657evalOne(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
1685eval(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
1782template<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
1839void
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
1887template<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
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
2074template<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
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
2227template <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
2261PtypeCombination::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
2293PtypeCombination::eval(unsigned int ptypeo_mask)
2294{
2295 return evalOne<BLACK>(ptypeo_mask) + evalOne<WHITE>(ptypeo_mask);
2296}
2297
2298
2301inline
2302std::pair<int,int> osl::eval::ml::
2303SilverFork::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 = {{
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}
2331inline
2332std::pair<int,int> osl::eval::ml::
2333SilverFork::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
2369SilverFork::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),
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}
2459inline
2461findDropInLine(const NumEffectState& state, Player defense,
2462 const Square a, const Square b, Piece king)
2463{
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}
2478inline
2480testCenter(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
2520inline
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
2540template <osl::Player Defense>
2542BishopRookFork::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
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),
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
2667template <osl::Player Defense>
2669KnightFork::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;
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
2737KnightFork::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),
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
2785template <osl::Player P, osl::Player Defense>
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
2828template <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
2870template <osl::Player P>
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),
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
2995template <osl::Player P>
2997Promotion37::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
3025Promotion37::eval(const NumEffectState &state)
3026{
3027 return evalOne<BLACK>(state, 3) + evalOne<WHITE>(state, 7);
3028}
3029
3030template <osl::Player P>
3033 MultiInt const& last_value)
3034{
3035 if (moved.isPass())
3036 return last_value;
3037 // todo changedEffects
3038 return eval(state);
3039}
3040
3041
3042namespace 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の表現 .
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
bool isPromotion() const
Ptype ptype() const
Player player() const
PtypeO oldPtypeO() const
移動前のPtypeO, i.e., 成る手だった場合成る前
bool isDrop() const
bool isPass() const
Ptype capturePtype() const
PtypeO capturePtypeO() const
PtypeO capturePtypeOSafe() const
Ptype oldPtype() const
移動前のPtype, i.e., 成る手だった場合成る前
bool isCapture() const
const Square to() const
const Square from() const
利きを持つ局面
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
利きの数を数える.
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
const Piece findCheapAttack(Player P, Square square) const
Square mobilityOf(Direction d, int num) const
const PieceMask promotedPieces() const
const PieceMask & piecesOnBoard(Player p) 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
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
Square kingSquare() const
Definition simpleState.h:94
bool isPawnMaskSet(Player player, int x) const
const Piece pieceAt(Square sq) const
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
static MultiInt weight
Definition minorPiece.h:729
static void setUp(const Weights &weights, int stage)
static const Square isRookForkSquare(const NumEffectState &state, Player defense, const Square a, const Square b)
static MultiIntPair eval(const NumEffectState &state, CArray< std::pair< Square, int >, 2 > &bishop_drop, CArray< std::pair< Square, int >, 2 > &rook_drop)
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)
static void setUp(const Weights &weights)
static const Square isBishopForkSquare(const NumEffectState &state, Player defense, const Square a, const Square b, bool maybe_empty=false)
static const Square findDropInLine(const NumEffectState &state, Player defense, const Square a, const Square b, Piece king)
static CArray< MultiInt, ONE_DIM > table
static void setUp(const Weights &weights)
static void setUp(const Weights &weights)
static MultiInt eval(const NumEffectState &state, const CArray2d< int, 2, 3 > &gs_count)
static CArray< MultiInt, 9720 > combination_table
static CArray< MultiInt, 1215 > table
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)
static CArray< MultiInt, 153 > knight_table
Definition minorPiece.h:670
static bool canRetreat(const NumEffectState &state, const Piece gold)
static CArray< MultiInt, 9 > retreat_table
Definition minorPiece.h:671
static void setUp(const Weights &weights)
static void setUp(const Weights &weights, int stage)
static void setUp(const Weights &weights)
static void setUp(const Weights &weights, int stage)
static MultiInt eval(const NumEffectState &state)
static bool cantAdvance(const NumEffectState &state, const Piece knight)
static CArray< MultiInt, 9 > table
Definition minorPiece.h:701
static void setUp(const Weights &weights)
static void setUp(const Weights &weights, int stage)
static CArray< MultiInt, 9 > y_table
Definition minorPiece.h:820
static MultiInt eval(const NumEffectState &state)
static CArray< MultiInt, ONE_DIM > table
static MultiIntPair eval(const NumEffectState &state, CArray< BoardMask, 2 > &knight_fork_squares, CArray< std::pair< Square, int >, 2 > &knight_drop)
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)
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)
static void setUp(const Weights &weights)
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)
static void setUp(const Weights &weights)
static void setUp(const Weights &weights)
static MultiInt eval(const NumEffectState &state)
static CArray< MultiInt, 9792 > table
static void setUp(const Weights &weights, int stage)
static void setUp(const Weights &weights)
static CArray< MultiInt, ONE_DIM > table
static void setUp(const Weights &weights)
static MultiInt eval(const NumEffectState &state)
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)
static CArray< MultiInt, 1024 > table
static void setUp(const Weights &weights)
static void eval(const NumEffectState &state, CArray< PieceMask, 40 > &attacked_mask, MultiIntPair &out)
static CArray< MultiInt, 19584 > king_table
static void eval(const NumEffectState &state, MultiIntPair &out)
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)
static CArray< MultiInt, 64 > table
static void setUp(const Weights &weights)
static void evalWithUpdateBang(const NumEffectState &state, Move moved, const CArray< PieceMask, 2 > &effected_mask, MultiIntPair &last_value_and_out)
static MultiInt eval(const NumEffectState &state)
static CArray< MultiInt, 9 > table
Definition minorPiece.h:532
static void setUp(const Weights &weights, int stage)
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)
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)
static void setUp(const Weights &weights)
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)
static CArray< MultiInt, 1024 > table
Definition minorPiece.h:877
static MultiInt eval(const NumEffectState &state)
static void setUp(const Weights &weights)
Definition minorPiece.cc:91
static void setUp(const Weights &weights)
static void setUp(const Weights &weights)
static CArray< MultiInt, 9 > table
Definition minorPiece.h:906
static void adjust(int index, int index_attack, int index_defense, MultiInt &result)
static MultiInt evalWithUpdate(const NumEffectState &state, Move moved, const MultiInt &last_values)
static void evalOne(const NumEffectState &state, const PieceMask promoted, MultiInt &result)
static MultiInt eval(const NumEffectState &state)
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)
static void setUp(const Weights &weights)
static CArray< MultiInt, ONE_DIM > table
static MultiInt eval(unsigned int ptypeo_mask)
static void setUp(const Weights &weights)
static CArray< MultiInt, 8192 > table
static void setUp(const Weights &weights)
static void setUp(const Weights &weights)
static CArray< MultiInt, 2240 > xy_attack_table
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)
static CArray< MultiInt, 2240 > xy_table_diff
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)
static CArray< MultiInt, 160 > table
static CArray< MultiInt, 2240 > xy_table
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)
static CArray< MultiInt, 2240 > xy_attack_table_diff
static MultiInt evalWithUpdate(const NumEffectState &, Move moved, MultiInt const &last_value)
static void setUp(const Weights &weights, int stage)
static MultiInt eval(const NumEffectState &state)
static CArray< MultiInt, 80 > table
Definition minorPiece.h:764
static void setUp(const Weights &weights)
static void evalWithUpdateBang(const NumEffectState &state, Move moved, const CArray2d< int, 2, 9 > &pawns, MultiInt &last_value)
static CArray< MultiInt, 1440 > table
static MultiInt eval(const NumEffectState &state, const CArray2d< int, 2, 9 > &pawns)
static void setUp(const Weights &weights, int stage)
static MultiInt eval(const NumEffectState &state)
static MultiInt evalWithUpdate(const NumEffectState &, Move moved, MultiInt const &last_value)
static CArray< MultiInt, 144 > table
Definition minorPiece.h:742
static MultiInt eval(const NumEffectState &state)
static void setUp(const Weights &weights)
static CArray< MultiInt, ONE_DIM > table
static MultiInt eval(const NumEffectState &state)
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)
static std::pair< int, int > matchGold(const NumEffectState &state, Piece gold, const CArray< bool, 2 > &has_silver, Square &silver_drop)
static std::pair< int, int > matchRook(const NumEffectState &state, Piece rook, const CArray< bool, 2 > &has_silver, Square &silver_drop)
static CArray< MultiInt, ONE_DIM > table
static void setUp(const Weights &weights)
static MultiIntPair eval(const NumEffectState &state, CArray< std::pair< Square, int >, 2 > &silver_drop)
static void setUp(const Weights &weights)
static void setUp(const Weights &weights, int stage)
CArray< PiecePair::IndexTable, 10 > & y_table
Definition piecePair.cc:36
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
@ UUR
Definition basic_type.h:323
@ UUL
Definition basic_type.h:322
bool isPromoted(Ptype ptype)
ptypeがpromote後の型かどうかのチェック
Definition basic_type.h:137
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)
static void adjust(int index, MultiInt &values)
size_t dimension() const
Definition weights.h:29
int value(size_t index) const
Definition weights.h:27