6 template <
bool Opening>
8 template <
bool Opening>
19 for (
size_t i = 0; i < empty_table.size(); ++i)
21 empty_table[i] = weights.
value(i);
23 for (
size_t i = 0; i < defense_table.size(); ++i)
25 defense_table[i] = weights.
value(i + empty_table.size());
27 for (
size_t i = 0; i < empty_y_table.size(); ++i)
29 empty_y_table[i] = weights.
value(i + empty_table.size() +
30 defense_table.size());
32 for (
size_t i = 0; i < defense_y_table.size(); ++i)
34 defense_y_table[i] = weights.
value(i + empty_table.size() +
35 defense_table.size() +
36 empty_y_table.size());
85 return (dir * 4 + state);
95 return (dir * 4 + state) * 9 + y - 1;
109 state.kingSquare(defenseP),
111 if (!state.pieceAt(target).isEmpty())
113 empty = defense = NOT_EMPTY;
116 const int attack_count = state.countEffect(
alt(defenseP), target);
117 const int defense_count = state.countEffect(defenseP, target);
118 if (attack_count == 0)
123 else if (defense_count == 1)
125 empty = MORE_EFFECT_KING_ONLY;
127 else if (attack_count >= defense_count)
135 if (defense_count == 1 && attack_count > defense_count)
137 defense = MORE_EFFECT_KING_ONLY;
139 else if (attack_count > defense_count)
141 defense = MORE_EFFECT;
145 defense = LESS_EFFECT;
160 state.kingSquare(defense),
162 if (!state.pieceAt(target).isEmpty())
165 const int attack_count = state.countEffect(
alt(defense), target);
166 if (attack_count == 0)
168 const int defense_count = state.countEffect(defense, target);
169 if (defense_count == 1)
170 return MORE_EFFECT_KING_ONLY;
171 else if (attack_count >= defense_count)
187 state.kingSquare(defense),
189 if (!state.pieceAt(target).isOnBoardByOwner(defense))
192 const int attack_count = state.countEffect(
alt(defense), target);
193 if (attack_count == 0)
196 const int defense_count = state.countEffect(defense, target);
197 if (defense_count == 1 && attack_count > defense_count)
198 return MORE_EFFECT_KING_ONLY;
199 else if (attack_count > defense_count)
206 template <
class MakeEffectState>
207 const osl::CArray<int,2>
208 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
215 CArray<int,2>
result = {{0, 0}};
220 if (black_effect_state != NOT_EMPTY)
222 result[0] -= table[index(dir, black_effect_state)];
225 if (white_effect_state != NOT_EMPTY)
227 result[1] += table[index(dir, white_effect_state)];
234 template <
class MakeEffectState>
235 const osl::CArray<int,2>
236 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
241 const CArray<int,2>& last_value,
const table_t& table)
243 CArray<int,2>
result = last_value;
246 mask.set(last_move.
to()); mask.set(last_move.
from());
247 for (
int z=0; z<2; ++z)
258 const EffectState effect_state = f(new_state, pl, dir);
259 if (effect_state != NOT_EMPTY)
261 result[z] -= table[index(dir, effect_state)];
265 result[1] = -result[1];
270 template <
class MakeEffectState>
274 const CArray<int,2>& last_value_o,
const CArray<int,2>& last_value_e,
277 CArray<int,2> result_o = last_value_o, result_e = last_value_e;
280 mask.set(last_move.
to()); mask.set(last_move.
from());
281 for (
int z=0; z<2; ++z)
288 result_o[z] = result_e[z] = 0;
292 const EffectState effect_state = f(new_state, pl, dir);
293 if (effect_state != NOT_EMPTY)
295 result_o[z] -= table_o[index(dir, effect_state)];
296 result_e[z] -= table_e[index(dir, effect_state)];
301 result_o[1] = -result_o[1];
302 result_e[1] = -result_e[1];
305 return std::make_pair(result_o, result_e);
308 template <
bool Opening>
313 for (
size_t i = 0; i < weights.
dimension(); ++i)
315 table[i] = weights.
value(i);
319 template <
bool Opening>
323 return evalCommon<MakeEffectStateSimple>(state, table);
325 template <
bool Opening>
328 const CArray<int,2>& last_value)
330 return evalWithUpdateCommon<MakeEffectStateSimple>
331 (new_state, last_move, last_value, table);
334 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
337 const CArray<int,2>& last_value_opening,
338 const CArray<int,2>& last_value_ending)
340 return evalWithUpdateCommon<MakeEffectStateSimple>
341 (new_state, last_move, last_value_opening, last_value_ending,
346 template <
bool Opening>
351 for (
size_t i = 0; i < weights.
dimension(); ++i)
353 table[i] = weights.
value(i);
356 template <
bool Opening>
360 return evalCommon<MakeEffectStateDefense>(state, table);
362 template <
bool Opening>
365 const CArray<int,2>& last_value)
367 return evalWithUpdateCommon<MakeEffectStateDefense>
368 (new_state, last_move, last_value, table);
372 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
375 const CArray<int,2>& last_value_opening,
376 const CArray<int,2>& last_value_ending)
378 return evalWithUpdateCommon<MakeEffectStateDefense>
379 (new_state, last_move, last_value_opening, last_value_ending,
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)
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);
437 const NumEffectState &state,
443 defense_effect = NOT_EMPTY;
446 state.kingSquare(defense),
448 const Piece piece = state.pieceAt(target);
453 const int attack_count = state.countEffect(
alt(defense), target);
454 const int defense_count = state.countEffect(defense, target);
458 if (attack_count == 0)
460 else if (defense_count == 1)
461 empty = MORE_EFFECT_KING_ONLY;
462 else if (attack_count >= defense_count)
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;
476 defense_effect = LESS_EFFECT;
483 return dir * 4 + state;
488 PieceMask , PieceMask )
492 const int black_liberty = black_king.
liberty();
493 const bool black_u_blocked =
497 const bool black_d_blocked =
501 const bool black_l_blocked =
505 const bool black_r_blocked =
510 const int white_liberty = white_king.
liberty();
511 const bool white_u_blocked =
515 const bool white_d_blocked =
519 const bool white_l_blocked =
523 const bool white_r_blocked =
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)
537 const int idx = index(dir, black_empty_effect_state);
538 result -= base_table[idx];
540 result -= u_table[idx];
542 result -= d_table[idx];
544 result -= l_table[idx];
546 result -= r_table[idx];
548 if (black_defense_effect_state != NOT_EMPTY)
550 const int idx = index(dir, black_defense_effect_state);
551 result -= base_defense_piece_table[idx];
553 result -= u_defense_piece_table[idx];
555 result -= d_defense_piece_table[idx];
557 result -= l_defense_piece_table[idx];
559 result -= r_defense_piece_table[idx];
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)
567 const int idx = index(dir, white_empty_effect_state);
568 result += base_table[idx];
570 result += u_table[idx];
572 result += d_table[idx];
574 result += l_table[idx];
576 result += r_table[idx];
578 if (white_defense_effect_state != NOT_EMPTY)
580 const int idx = index(dir, white_defense_effect_state);
581 result += base_defense_piece_table[idx];
583 result += u_defense_piece_table[idx];
585 result += d_defense_piece_table[idx];
587 result += l_defense_piece_table[idx];
589 result += r_defense_piece_table[idx];
605 for (
int i = 0; i < ONE_DIM; ++i)
608 table[i][s] = weights.
value(i + ONE_DIM*s);
615 for (
int i = 0; i < ONE_DIM; ++i)
618 table[i][s] = weights.
value(i + ONE_DIM*s);
645 const Square black_king = state.kingSquare<
BLACK>();
646 adjust<1>(index(black_king),
647 indexY<BLACK>(black_king),
659 const Square white_king = state.kingSquare<
WHITE>();
660 adjust<-1>(index(white_king),
661 indexY<WHITE>(white_king),
668 template <osl::Player P>
672 const int king_x = king.
x();
675 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
679 return target_x - 1 + ((x_diff == 1) ? 0 : 5);
683 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
687 return target_x - 1 + ((x_diff == 1) ? 0 : 5);
691 template <osl::Player P>
693 const NumEffectState &state,
697 const King8Info info(state.Iking8Info(P));
698 if ((diff == 1) ^ (P ==
BLACK))
702 assert((diff == 1 && P ==
BLACK) || (diff == -1 && P ==
WHITE));
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)
712 Piece p(state.pieceAt(target));
713 if ((!p.isEdge()) && ! p.isOnBoardByOwner<P>() &&
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)];
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)];
750 const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(state, 1);
751 const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(state, -1);
753 val[b] += table[index<BLACK>(black_king, 1)];
755 val[b] += table[index<BLACK>(black_king, -1)];
757 const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(state, 1);
758 const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(state, -1);
760 val[w] -= table[index<WHITE>(white_king, 1)];
762 val[w] -= table[index<WHITE>(white_king, -1)];
768 std::pair<osl::CArray<int,2>,osl::CArray<int,2> >
770 KingXBlockedBase::evalWithUpdate(
const NumEffectState &new_state,
Move last_move,
771 const CArray<int,2>& last_value_o,
const CArray<int,2>& last_value_e,
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());
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)];
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)];
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)];
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)];
806 return std::make_pair(val_o, val_e);
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());
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),
842 if (black_l_blocked) {
843 adjust<1>(KingXBlockedBase::index<BLACK>(black_king, -1),
844 index<BLACK>(black_king, -1),
847 if (black_r_blocked && black_l_blocked)
850 KingXBothBlocked::indexY<BLACK>(black_king),
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),
864 if (white_l_blocked) {
865 adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, -1),
866 index<WHITE>(white_king, -1),
869 if (white_r_blocked && white_l_blocked)
872 KingXBothBlocked::indexY<WHITE>(white_king),
878 template <osl::Player P>
inline
882 const int king_x = king.
x();
885 const int king_y = king.
y();
886 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
890 return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
894 const int king_y = 10 - king.
y();
895 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
899 return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
909 for (
size_t i = 0; i < table.size(); ++i)
911 table[i][stage] = weights.
value(i);
920 (new_state, last_move, last_values);
926 for (
size_t i = 0; i < table.size(); ++i)
928 table[i][stage] = weights.
value(i);
938 for (
int i = 0; i < ONE_DIM; ++i)
941 table[i][s] = weights.
value(i + ONE_DIM*s);
947 for (
int i = 0; i < ONE_DIM; ++i)
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))));
974 indexY<BLACK>(state.kingSquare<
BLACK>(),
986 indexY<BLACK>(state.kingSquare<
BLACK>(),
999 indexY<WHITE>(state.kingSquare<
WHITE>(),
1011 indexY<WHITE>(state.kingSquare<
WHITE>(),
1029 for (
size_t i = 0; i < table.size(); ++i)
1031 table[i][stage] = weights.
value(i);
1039 return std::abs(king.
x() - target.
x()) + std::abs(king.
y() - target.
y()) * 2;
1042 template <osl::Player Defense>
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);
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()))];
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()))];
1075 return evalOne<BLACK>(state) + evalOne<WHITE>(state);