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