8 for (
size_t i = 0; i <
ONE_DIM; ++i)
35 osl::CArray<osl::MultiInt, 1>
40 for (
int i = 0; i < ONE_DIM; ++i)
49 for (
int i = 0; i < ONE_DIM; ++i)
58 for (
int i = 0; i < ONE_DIM; ++i)
67 for (
int i = 0; i < ONE_DIM; ++i)
75 for (
int i = 0; i < ONE_DIM; ++i)
84 for (
int i = 0; i < ONE_DIM; ++i)
93 for (
int i = 0; i < ONE_DIM; ++i)
101 const NumEffectState &state)
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),
110 for (
int x = 1; x <= 9; ++x)
112 const bool black_on_board = state.isPawnMaskSet<
BLACK>(x);
113 const bool white_on_board = state.isPawnMaskSet<
WHITE>(x);
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);
129 result += standValue(attack_index, defense_index,
130 attack_index_y, defense_index_y,
131 attack_index_x, defense_index_x);
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);
149 result -= standValue(attack_index, defense_index,
150 attack_index_y, defense_index_y,
151 attack_index_x, defense_index_x);
154 const int index_x = (x > 5 ? 10 - x : x);
155 if (black_on_board && white_on_board)
158 state_king_relative_table[std::abs(kings[
BLACK].x() - x) +
161 state_king_relative_table[std::abs(kings[
WHITE].x() - x) +
164 else if (black_on_board && !white_on_board)
166 result += drop_non_drop_table[index_x - 1];
167 result -= drop_non_drop_table[index_x - 1 + 5];
169 state_king_relative_table[std::abs(kings[
BLACK].x() - x) +
172 state_king_relative_table[std::abs(kings[
WHITE].x() - x) +
175 else if (!black_on_board && white_on_board)
177 result += drop_non_drop_table[index_x - 1 + 5];
178 result -= drop_non_drop_table[index_x - 1];
180 state_king_relative_table[std::abs(kings[
BLACK].x() - x) +
183 state_king_relative_table[std::abs(kings[
WHITE].x() - x) +
189 state_king_relative_table[std::abs(kings[
BLACK].x() - x) +
192 state_king_relative_table[std::abs(kings[
WHITE].x() - x) +
216 for (
size_t i = 0; i < weights.
dimension(); ++i) {
217 table[i][stage] = weights.
value(i);
222 const NumEffectState &state)
226 i < PtypeTraits<PAWN>::indexLimit; ++i)
228 const Piece pawn = state.pieceOf(i);
230 cantAdvance(state, pawn))
241 template <osl::Player P>
inline
251 template <osl::Player P>
256 assert(moved.
player() == P);
259 if (cantAdvance(state, moved.
ptypeO(), moved.
to()))
261 adjust<P>(index(P, moved.
to()), values);
267 if (captured ==
PAWN)
270 adjust<P>(index(Opponent, moved.
to()), values);
277 adjust<P>(index(Opponent, piece.
square()), values);
284 adjust<Opponent>(index(P, piece.
square()), values);
290 adjust<P>(index(P, piece.
square()), values);
304 for (
size_t i = 0; i < ONE_DIM; ++i)
307 head_table[i][s] = weights.
value(i + ONE_DIM*s);
315 CArray<Square, 2> kings = {{state.kingSquare<
BLACK>(),
316 state.kingSquare<
WHITE>()}};
318 i < PtypeTraits<SILVER>::indexLimit; ++i)
320 const Piece silver = state.pieceOf(i);
323 result += evalOne<BLACK>(state, silver, kings);
326 result -= evalOne<WHITE>(state, silver, kings);
332 template<osl::Player P>
339 assert(silver.
owner()==P);
363 for (
size_t i = 0; i < weights.
dimension(); ++i) {
364 retreat_table[i][stage] = weights.
value(i);
379 for (
size_t i = 0; i < ONE_DIM; ++i)
382 knight_table[i][s] = weights.
value(i + ONE_DIM*s);
389 for (
size_t i = 0; i < ONE_DIM; ++i)
392 side_table[i][s] = weights.
value(i + ONE_DIM*s);
400 CArray<Square, 2> kings = {{state.kingSquare<
BLACK>(),
401 state.kingSquare<
WHITE>()}};
403 i < PtypeTraits<GOLD>::indexLimit; ++i)
405 const Piece gold = state.pieceOf(i);
410 result += evalOne<BLACK>(state, gold, kings);
414 result -= evalOne<WHITE>(state, gold, kings);
420 template<osl::Player P>
427 assert(P==gold.
owner());
445 for (
size_t i = 0; i < weights.
dimension(); ++i) {
446 retreat_table[i][stage] = weights.
value(i);
454 template<osl::Player P>
462 assert(P==knight.
owner());
478 for (
size_t i = 0; i < weights.
dimension(); ++i) {
479 table[i][stage] = weights.
value(i);
484 const NumEffectState &state)
488 i < PtypeTraits<KNIGHT>::indexLimit; ++i)
490 const Piece knight = state.pieceOf(i);
493 if(cantAdvance<BLACK>(state,knight))
496 else if(cantAdvance<WHITE>(state,knight)){
519 for (
size_t i = 0; i < weights.
dimension(); ++i)
521 table[i][stage] = weights.
value(i);
530 const Piece p = state.pieceOf(i);
541 template<osl::Player P>
559 table[index(
alt(P), captured, moved.
to())];
567 result += table[index(
BLACK, moved.
ptype(), moved.
to())];
569 result -= table[index(
WHITE, moved.
ptype(), moved.
to())];
581 for (
size_t i = 0; i < weights.
dimension(); ++i)
583 table[i][stage] = weights.
value(i);
592 const Piece p = state.pieceOf(i);
603 template<osl::Player P>
620 result += table[index(
WHITE, captured, moved.
to())];
622 result -= table[index(
BLACK, captured, moved.
to())];
626 result += table[index(
BLACK, moved.
ptype(), moved.
to())];
628 result -= table[index(
WHITE, moved.
ptype(), moved.
to())];
644 for (
size_t i = 0; i < ONE_DIM; ++i)
655 if (canCheck<BLACK>(state))
657 const int index_y = indexY<BLACK>(state.kingSquare<
BLACK>().y());
658 result += value(index_y);
660 if (canCheck<WHITE>(state))
662 const int index_y = indexY<WHITE>(state.kingSquare<
WHITE>().y());
663 result -= value(index_y);
674 for (
size_t i = 0; i < ONE_DIM; ++i)
677 table[i][s] = weights.
value(i + ONE_DIM*s);
684 for (
size_t i = 0; i < ONE_DIM; ++i)
696 i < PtypeTraits<PAWN>::indexLimit; ++i)
698 Piece pawn = state.pieceOf(i);
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,
713 result += table[idx] +
y_table[idx_y];
715 result -= table[idx] +
y_table[idx_y];
721 template<osl::Player P>
723 #if (defined __GNUC__ && ! defined __clang__)
728 const CArray2d<int, 2, 9> &pawns,
731 assert(moved.
player()==P);
742 up_up_p, moved.
from().
y());
744 result -= table[i]+
y_table[i_y];
746 result += table[i]+y_table[i_y];
751 moved.
from().
y() + 1)
756 state.pieceAt(up_up).ptypeO()) :
760 moved.
from().
y() + 1);
761 result -= table[i]+
y_table[i_y];
762 if (up_up != moved.
to())
766 moved.
from().
y() + 1);
767 result += table[new_i]+y_table[new_i_y];
771 moved.
from().
y() + 2)
779 moved.
from().
y() + 2);
780 result -= table[i]+y_table[i_y];
781 if (moved.
to() != up)
785 moved.
from().
y() + 2);
786 result += table[new_i]+y_table[new_i_y];
793 moved.
from().
y() - 1)
798 state.pieceAt(up_up).ptypeO()) :
802 moved.
from().
y() - 1);
803 result += table[i]+
y_table[i_y];
804 if (moved.
to() != up_up)
808 moved.
from().
y() - 1);
809 result -= table[new_i]+y_table[new_i_y];
813 moved.
from().
y() - 2)
821 moved.
from().
y() - 2);
822 result += table[i]+y_table[i_y];
823 if (moved.
to() != up)
827 moved.
from().
y() - 2);
828 result -= table[new_i]+y_table[new_i_y];
834 if (captured ==
PAWN)
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,
849 result += table[i]+
y_table[i_y];
853 result -= table[i]+
y_table[i_y];
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());
870 result += table[i]+
y_table[i_y];
874 result -= table[i]+
y_table[i_y];
877 if (pawns[
BLACK][moved.
to().
x() - 1] != 0)
879 if (pawns[
BLACK][moved.
to().
x() - 1] ==
884 (up_up.
isOnBoard() ? state.pieceAt(up_up).ptypeO() :
886 const int i = index(
BLACK, moved.
ptypeO(), up_up_p);
887 const int i_y = indexY(
BLACK, moved.
ptypeO(), up_up_p,
889 result += table[i]+
y_table[i_y];
894 up_up_p, moved.
to().
y() + 1);
895 result -= table[old_i]+y_table[old_i_y];
898 if (pawns[
BLACK][moved.
to().
x() - 1] ==
905 const int i_y = indexY(
BLACK, up_p, moved.
ptypeO(), moved.
to().
y() + 2);
906 result += table[i]+y_table[i_y];
912 result -= table[old_i]+y_table[old_i_y];
916 if (pawns[
WHITE][moved.
to().
x() - 1] != 0)
918 if (pawns[
WHITE][moved.
to().
x() - 1] ==
923 (up_up.
isOnBoard() ? state.pieceAt(up_up).ptypeO() :
925 const int i = index(
WHITE, moved.
ptypeO(), up_up_p);
926 const int i_y = indexY(
WHITE, moved.
ptypeO(), up_up_p,
928 result -= table[i]+
y_table[i_y];
929 if (up_up != moved.
from())
934 result += table[old_i]+y_table[old_i_y];
937 if (pawns[
WHITE][moved.
to().
x() - 1] ==
944 const int i_y = indexY(
WHITE, up_p, moved.
ptypeO(), moved.
to().
y() - 2);
945 result -= table[i]+y_table[i_y];
951 result += table[old_i]+y_table[old_i_y];
966 for (
size_t i = 0; i < ONE_DIM; ++i)
969 table[i][s] = weights.
value(i + ONE_DIM*s);
976 for (
size_t i = 0; i < ONE_DIM; ++i)
989 result+= table[index] +
y_table[index_attack] +
y_table[index_defense];
991 result-= table[index] + y_table[index_attack] + y_table[index_defense];
993 template <osl::Player P>
996 const PieceMask promoted,
999 PieceMask attack = promoted & state.piecesOnBoard(P);
1001 const Square self_king = state.kingSquare<P>();
1004 while (attack.any())
1006 const Piece p = state.pieceOf(attack.takeOneBit());
1007 const int x_diff = (P ==
BLACK ? p.
square().
x() - king.
x() :
1011 if (x_diff > min_left)
1013 if (min_left != -10)
1016 adjust<1>(-min_left, indexY<true, P>(king, -min_left),
1017 indexY<false, P>(self_king, -min_left),
result);
1019 adjust<-1>(-min_left, indexY<true, P>(king, -min_left),
1020 indexY<false, P>(self_king, -min_left),
result);
1027 adjust<1>(-x_diff, indexY<true, P>(king, -x_diff),
1028 indexY<false, P>(self_king, -x_diff),
1031 adjust<-1>(-x_diff, indexY<true, P>(king, -x_diff),
1032 indexY<false, P>(self_king, -x_diff),
1038 if (x_diff < min_right)
1040 if (min_right != 10)
1043 adjust<1>(min_right, indexY<true, P>(king, min_right),
1044 indexY<false, P>(self_king, min_right),
1047 adjust<-1>(min_right, indexY<true, P>(king, min_right),
1048 indexY<false, P>(self_king, min_right),
1053 else if (x_diff != 0)
1056 adjust<1>(x_diff, indexY<true, P>(king, x_diff),
1057 indexY<false, P>(self_king, x_diff),
1060 adjust<-1>(x_diff, indexY<true, P>(king, x_diff),
1061 indexY<false, P>(self_king, x_diff),
1072 PieceMask promoted_pieces = state.promotedPieces();
1073 promoted_pieces.clearBit<
ROOK>();
1074 promoted_pieces.clearBit<
BISHOP>();
1075 if (promoted_pieces.none())
1078 evalOne<BLACK>(state, promoted_pieces,
result);
1079 evalOne<WHITE>(state, promoted_pieces,
result);
1104 for (
size_t i = 0; i < ONE_DIM; ++i)
1107 table[i][s] = weights.
value(i + ONE_DIM*s);
1114 for (
size_t i = 0; i < ONE_DIM; ++i)
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++)
1124 int index=((ptype + (same_turn ? 0 :
PTYPE_SIZE) +
1125 (has_support ? 0 : PTYPE_SIZE*2))* 9 + x_diff) * 17 +
1127 int index0=ptype + (same_turn ? 0 :
PTYPE_SIZE) +
1128 (has_support ? 0 : PTYPE_SIZE * 2);
1136 int black_turn_king_defense,
1137 int white_turn_king_attack,
1138 int white_turn_king_defense,
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];
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];
1159 CArray<Square, 2> kings = {{state.kingSquare<
BLACK>(),
1160 state.kingSquare<
WHITE>()}};
1161 PieceMask black_attacked = state.effectedMask(
WHITE) & state.piecesOnBoard(
BLACK);
1163 mask_t black_ppawn = state.promotedPieces().getMask<
PAWN>() & black_attacked.selectBit<
PAWN>();
1164 black_attacked.clearBit<
PAWN>();
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())
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,
1183 while (black_without_support.any())
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,
1199 PieceMask white_attacked = state.effectedMask(
BLACK) & state.piecesOnBoard(
WHITE);
1201 mask_t white_ppawn = state.promotedPieces().getMask<
PAWN>() & white_attacked.selectBit<
PAWN>();
1202 white_attacked.clearBit<
PAWN>();
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())
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,
1221 while (white_without_support.any())
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,
1238 template<osl::Player P>
1241 const NumEffectState &state,
1243 const CArray<PieceMask, 2> &effected,
1248 eval(state, result);
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)
1261 new_mask[0].selectBit<
PAWN>() & state.promotedPieces().template getMask<PAWN>();
1263 new_mask[1].template selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
1264 new_mask[0].clearBit<
PAWN>();
1265 new_mask[1].clearBit<
PAWN>();
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);
1276 if (effected_mask[
alt(P)].test(p.
number()))
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,
1282 const int index_king_white_turn_attack =
1283 indexK<true>(kings[
alt(P)],
WHITE == P,
1285 const int index_king_black_turn_defense =
1286 indexK<false>(kings[P], BLACK == P,
1288 const int index_king_white_turn_defense =
1289 indexK<false>(kings[P], WHITE == P,
1292 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1293 index_king_white_turn_attack, index_king_white_turn_defense,
1296 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1297 index_king_white_turn_attack, index_king_white_turn_defense,
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,
1307 const int index_king_white_turn_attack =
1308 indexK<true>(kings[
alt(P)],
WHITE == P,
1310 const int index_king_black_turn_defense =
1311 indexK<false>(kings[P], BLACK == P,
1313 const int index_king_white_turn_defense =
1314 indexK<false>(kings[P], WHITE == P,
1317 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1318 index_king_white_turn_attack, index_king_white_turn_defense,
1321 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1322 index_king_white_turn_attack, index_king_white_turn_defense,
1328 PieceMask captured_mask =
1329 effected_mask[P] & (~state.piecesOnBoard(
BLACK)) &
1330 (~state.piecesOnBoard(
WHITE));
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,
1336 const int index_king_white_turn_attack =
1337 indexK<true>(kings[P],
BLACK == P,
1339 const int index_king_black_turn_defense =
1340 indexK<false>(kings[
alt(P)], WHITE == P,
1342 const int index_king_white_turn_defense =
1343 indexK<false>(kings[
alt(P)], BLACK == P,
1346 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
1347 index_king_white_turn_attack, index_king_white_turn_defense,
1350 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
1351 index_king_white_turn_attack, index_king_white_turn_defense,
1355 updateEffectChanged<BLACK>(state, effected_mask, new_mask, p.
number(),
1357 updateEffectChanged<WHITE>(state, effected_mask, new_mask, p.
number(),
1368 for (
size_t i = 0; i < ONE_DIM; ++i)
1371 table[i][s] = weights.
value(i + ONE_DIM*s);
1378 for (
size_t i = 0; i < ONE_DIM; ++i)
1390 i < PtypeTraits<KNIGHT>::indexLimit;
1393 const Piece knight = state.pieceOf(i);
1398 const Piece up_piece = state.pieceAt(up);
1401 state.countEffect(knight.
owner(), up) <=
1402 state.countEffect(
alt(knight.
owner()), up)) ||
1403 (state.hasEffectByPtypeStrict<
PAWN>(
alt(knight.
owner()), up) &&
1405 state.countEffect(knight.
owner(), up) <
1406 state.countEffect(
alt(knight.
owner()), up)))
1408 const int y = knight.
square().
y();
1411 result += table[y - 1];
1415 result -= table[9 - y];
1419 state.hasPieceOnStand<
PAWN>(up_piece.
owner()))
1423 const int index = up_piece.
ptype() * 9 + y - 1;
1426 result += opp_table[index];
1430 result -= opp_table[index];
1444 for (
size_t i = 0; i < ONE_DIM; ++i)
1447 table[i][s] = weights.
value(i + ONE_DIM*s);
1453 CArray<PieceMask, 40> &attacked_mask,
1457 PieceMask black_attacked = state.effectedMask(
WHITE) & state.piecesOnBoard(
BLACK);
1459 mask_t black_ppawn = state.promotedPieces().getMask<
PAWN>() & black_attacked.selectBit<
PAWN>();
1460 black_attacked.clearBit<
PAWN>();
1462 while (black_attacked.any())
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;
1470 while (attacking.any())
1472 const Piece attack = state.pieceOf(attacking.takeOneBit());
1473 const int index_black_turn = index(
true, with_support,
1475 const int index_white_turn = index(
false, with_support,
1477 adjust<1>(index_black_turn, index_white_turn,
result);
1480 PieceMask white_attacked = state.effectedMask(
BLACK) & state.piecesOnBoard(
WHITE);
1482 mask_t white_ppawn = state.promotedPieces().getMask<
PAWN>() & white_attacked.selectBit<
PAWN>();
1483 white_attacked.clearBit<
PAWN>();
1485 while (white_attacked.any())
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())
1494 const Piece attack = state.pieceOf(attacking.takeOneBit());
1495 const int index_black_turn = index(
false, with_support,
1497 const int index_white_turn = index(
true, with_support,
1499 adjust<-1>(index_black_turn, index_white_turn,
result);
1504 template<osl::Player P>
1507 const NumEffectState &state,
1509 const CArray<PieceMask, 2> &effected,
1510 CArray<PieceMask, 40> &attacked_mask,
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)
1521 new_mask[0].selectBit<
PAWN>() & state.promotedPieces().template getMask<PAWN>();
1523 new_mask[1].selectBit<
PAWN>() & state.promotedPieces().template getMask<PAWN>();
1524 new_mask[0].clearBit<
PAWN>();
1525 new_mask[1].clearBit<
PAWN>();
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);
1534 int captured_number = -1;
1537 PieceMask captured_mask =
1538 effected_mask[P] & (~state.piecesOnBoard(
BLACK)) &
1539 (~state.piecesOnBoard(
WHITE));
1540 captured_number = captured_mask.takeOneBit();
1544 if (effected_mask[
alt(P)].test(p.number()))
1546 const bool has_support = effected_mask[P].test(p.number());
1547 PieceMask attacking = attacked_mask[p.number()];
1548 if (captured_number != -1)
1550 if (attacking.test(captured_number))
1562 attacking.reset(captured_number);
1565 while (attacking.any())
1567 const Piece attack = state.pieceOf(attacking.takeOneBit());
1581 if (new_mask[
alt(P)].test(p.number()))
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())
1589 const Piece attack = state.pieceOf(attacking.takeOneBit());
1592 evalOnePiece<true>(P, p.ptype(), attack.
ptype(),
1597 evalOnePiece<false>(P, p.ptype(), attack.
ptype(),
1602 if (captured_number != -1)
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()))
1618 attacking.reset(p.number());
1620 while (attacking.any())
1622 const Piece attack = state.pieceOf(attacking.takeOneBit());
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);
1641 osl::CArray<osl::MultiInt, 512*512>
1645 for (
int i = 0; i < ONE_DIM; ++i)
1648 table[i][s] = weights.
value(i + ONE_DIM*s);
1651 for (
int j=i+1; j<PTYPE_SIZE*2*
PTYPE_SIZE; ++j) {
1652 table[index2(j,i)] = table[index2(i,j)];
1655 template <osl::Player Owner>
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>();
1666 while (attacked.any())
1668 const Piece piece = state.pieceOf(attacked.takeOneBit());
1669 pieces.push_back(piece);
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]);
1676 result += table[index2(i0, i1)];
1678 result -= table[index2(i0, i1)];
1687 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
1703 for (
size_t i = 0; i < ONE_DIM; ++i)
1706 table[i][s] = weights.
value(i + ONE_DIM*s);
1712 for (
size_t i = 0; i < ONE_DIM; ++i)
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){
1733 for(
int x=0;x<5;x++){
1734 for(
int k=0;k<160;k+=40)
1736 for(
int j=1;j<size;j++){
1737 for(
int k=0;k<160;k+=40)
1741 for(
int y=0;y<9;y++){
1742 for(
int k=0;k<160;k+=40)
1744 for(
int j=1;j<size;j++){
1745 for(
int k=0;k<160;k+=40)
1754 for (
size_t i = 0; i < ONE_DIM; ++i)
1763 for(
int x=0;x<5;x++){
1764 for(
int k=0;k<160;k+=40)
1766 for(
int j=1;j<size;j++){
1767 for(
int k=0;k<160;k+=40)
1771 for(
int y=0;y<9;y++){
1772 for(
int k=0;k<160;k+=40)
1774 for(
int j=1;j<size;j++){
1775 for(
int k=0;k<160;k+=40)
1782 template<osl::Player P,osl::Ptype T>
1785 const osl::CArray2d<int, 2, osl::PTYPE_SIZE> &ptype_board_count,
1786 const osl::CArray<int,2> &kings_x,
1787 const osl::CArray<int,2> &kings_y)
1791 int j=
static_cast<int>(T);
1792 if (ptype_count[i][j] != 0)
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]);
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];
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]);
1812 if (ptype_board_count[i][j] != 0)
1815 indexBoardCountX<T>(ptype_board_count[i][j], kings_x[i]);
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]);
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];
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]);
1840 #if (defined __GNUC__ && ! defined __clang__)
1844 const NumEffectState &state,
1845 const CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
1846 const CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
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() }};
1855 kings_x[0] = 10 - kings_x[0];
1857 kings_x[1] = 10 - kings_x[1];
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);
1887 template<osl::Player P>
1889 const NumEffectState &state,
1891 CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
1892 CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
1894 unsigned int &ptypeo_mask)
1896 assert(last_move.
player()==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() }};
1903 kings_x[0] = 10 - kings_x[0];
1905 kings_x[1] = 10 - kings_x[1];
1913 if(--ptype_count[altP][capturedPtype]==0)
1915 --ptype_board_count[altP][capturedPtype];
1917 ++ptype_count[P][base_captured];
1920 eval(state, ptype_count, ptype_board_count, last_value_and_out);
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]);
1934 const int count = --ptype_count[altP][capturedPtype];
1937 const int board_count = --ptype_board_count[altP][capturedPtype];
1939 const int c_count = ++ptype_count[P][base_captured];
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]);
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];
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]);
1962 if(P==
BLACK) last_value_and_out+= sum;
1963 else last_value_and_out-= sum;
1969 for (
size_t i = 0; i < ONE_DIM; ++i)
1972 table[i][s] = weights.
value(i + ONE_DIM*s);
1984 i < PtypeTraits<LANCE>::indexLimit;
1987 const Piece lance = state.pieceOf(i);
1990 const Square self_king = state.kingSquare(lance.
owner());
2000 result += table[index1];
2001 result += table[index2];
2005 result -= table[index1];
2006 result -= table[index2];
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);
2017 result += table[index1];
2018 result += table[index2];
2022 result -= table[index1];
2023 result -= table[index2];
2036 for (
size_t i = 0; i < ONE_DIM; ++i)
2038 for (
int s = 0; s <
NStages; ++s)
2040 table[i][s] = weights.
value(i + ONE_DIM*s);
2047 const CArray2d<int, 2, 9> &pawns)
2052 const Piece piece = state.pieceOf(i);
2063 result += table[idx];
2067 result -= table[idx];
2074 template<osl::Player P>
2078 const CArray2d<int, 2, 9> &pawns,
2082 assert(P==moved.
player());
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)
2092 if (y == moved.
to().
y())
2096 const int idx_new = index(P, p.
ptype(), y, new_pawn_y);
2099 last_value += table[idx_new];
2103 last_value -= table[idx_new];
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);
2113 last_value -= table[idx_old];
2114 last_value += table[idx_new];
2118 last_value += table[idx_old];
2119 last_value -= table[idx_new];
2128 const int pawn_y = pawns[P][moved.
from().
x() - 1];
2129 const int idx = index(P, moved.
oldPtype(), moved.
from().
y(),
2133 last_value -= table[idx];
2137 last_value += table[idx];
2141 const int pawn_y = pawns[P][moved.
to().
x() - 1];
2142 const int idx = index(P, moved.
ptype(), moved.
to().
y(),
2146 last_value += table[idx];
2150 last_value -= table[idx];
2157 if (captured ==
PAWN)
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)
2167 const int idx_old = index(
alt(P), p.
ptype(), y,
2169 const int idx_new = index(
alt(P), p.
ptype(), y,
2173 last_value += table[idx_old];
2174 last_value -= table[idx_new];
2178 last_value -= table[idx_old];
2179 last_value += table[idx_new];
2186 const int pawn_y = pawns[
alt(P)][moved.
to().
x() - 1];
2187 const int idx = index(
alt(P), captured, moved.
to().
y(),
2191 last_value += table[idx];
2195 last_value -= table[idx];
2209 for (
size_t i = 0; i < ONE_DIM; ++i)
2212 table[i][s] = weights.
value(i + ONE_DIM*s);
2219 for (
size_t i = 0; i < ONE_DIM; ++i)
2223 weights.
value(i + ONE_DIM*s);
2227 template <osl::Player P>
2230 const CArray2d<int, 2, 3> &gs_count)
2234 const Square king = state.kingSquare<P>();
2235 for (
size_t i = 0; i < gs_count.size2(); ++i)
2237 total += gs_count[P][i];
2240 result += table[index<P>(king, i, total)];
2243 result += combination_table[
2244 indexCombination<P>(king, gs_count[P][0],
2245 gs_count[P][1], gs_count[P][2])];
2251 const CArray2d<int, 2, 3> &gs_count)
2253 return evalOne<BLACK>(state, gs_count) + evalOne<WHITE>(state, gs_count);
2263 static CArray<MultiInt, 8192> orig_table;
2264 for (
size_t i = 0; i < ONE_DIM; ++i)
2266 for (
int s = 0; s <
NStages; ++s)
2268 orig_table[i][s] = weights.
value(i + ONE_DIM*s);
2271 for(
int i=0;i<8192;i++){
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;
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];
2295 return evalOne<BLACK>(ptypeo_mask) + evalOne<WHITE>(ptypeo_mask);
2299 osl::CArray<osl::MultiInt, 5*2>
2304 const CArray<bool,2>& has_silver,
2309 return std::make_pair(0,0);
2312 return std::make_pair(0,0);
2313 const CArray<Offset,2> offset = {{
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))
2320 const Piece p = state.pieceAt(next2);
2327 return std::make_pair(
playerToMul(owner), state.hasEffectAt(owner, next2) ? 1 : 2);
2329 return std::make_pair(0,0);
2334 const CArray<bool,2>& has_silver,
Square& silver_drop)
2338 return std::make_pair(0,0);
2341 return std::make_pair(0,0);
2342 const CArray<Offset,2> offset = {{
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);
2352 if (! state.pieceAt(next_down).isEmpty() || state.hasEffectAt(owner, next_down))
2354 const Piece p = state.pieceAt(next2);
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(
playerToMul(owner), 3 + recaputure);
2365 return std::make_pair(0,0);
2371 silver_drop.fill(std::make_pair(
Square(),0));
2373 const CArray<bool,2> has_silver = {{
2377 if (! has_silver[
BLACK] && ! has_silver[
WHITE])
2381 i < PtypeTraits<ROOK>::indexLimit; ++i)
2383 const Piece rook = state.pieceOf(i);
2384 std::pair<int,int> match = matchRook(state, rook, has_silver, drop);
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;
2392 if (match.first > 0)
2394 result[
BLACK] += table[match.second*2+1];
2395 result[
WHITE] += value_attack;
2397 else if (match.first < 0)
2399 result[
BLACK] -= value_attack;
2400 result[
WHITE] -= table[match.second*2+1];
2406 i < PtypeTraits<GOLD>::indexLimit; ++i)
2408 const Piece gold = state.pieceOf(i);
2409 std::pair<int,int> match = matchGold(state, gold, has_silver, drop);
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;
2417 if (match.first > 0)
2419 result[
BLACK] += table[match.second*2+1];
2420 result[
WHITE] += value_attack;
2422 else if (match.first < 0)
2424 result[
BLACK] -= value_attack;
2425 result[
WHITE] -= table[match.second*2+1];
2434 for (
int i = 0; i < ONE_DIM; ++i)
2437 table[i][s] = weights.
value(i + ONE_DIM*s);
2441 osl::CArray<osl::MultiInt, 256*2*2>
2445 for (
int i = 0; i < ONE_DIM; ++i)
2448 table[i][s] = weights.
value(i + ONE_DIM*s);
2467 for (
Piece p=state.pieceAt(sq); p.
isEmpty(); sq+=offset, p=state.pieceAt(sq))
2471 if (! state.hasEffectAt(defense, sq)
2472 || (state.hasEffectAt(
alt(defense), sq)
2473 && ! state.hasEffectNotBy(defense, king, sq)))
2476 return (sq == b) ? drop_position :
Square();
2484 const Piece p = state.pieceAt(center);
2486 || (state.hasEffectAt(defense, center)
2487 && (! state.hasEffectAt(
alt(defense), center)
2488 || state.hasEffectNotBy(defense, king, center))))
2490 return state.isEmptyBetween(center, a, !maybe_empty)
2491 && state.isEmptyBetween(center, b, !maybe_empty);
2499 const Piece king = state.kingPiece(defense);
2500 const int cx = b.
x() - a.
x(), cy = b.
y() - a.
y();
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);
2507 const CArray<Square,2> centers = {{
2511 for (
size_t i=0; i<centers.size(); ++i) {
2512 if (! centers[i].isOnBoardRegion())
2514 if (testCenter(state, defense, a, b, king, centers[i], maybe_empty))
2525 const Piece king = state.kingPiece(defense);
2526 const CArray<Square,2> centers = {{
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)
2533 assert(centers[i].isOnBoardRegion());
2534 if (testCenter(state, defense, a, b, king, centers[i]))
2540 template <osl::Player Defense>
2543 std::pair<Square,int>& bishop_drop,
2544 std::pair<Square,int>& rook_drop)
2547 for (
size_t i=0; i<target.size(); ++i)
2549 const Piece pi = target[i];
2551 for (
size_t j=i+1; j<target.size(); ++j)
2553 const Piece pj = target[j];
2555 if (state.hasPieceOnStand<
BISHOP>(
alt(Defense)))
2558 = isBishopForkSquare(state, Defense, pi.
square(), pj.
square());
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) {
2563 bishop_drop.second = -value_attack[0];
2564 bishop_drop.first =
center;
2566 if (Defense ==
BLACK)
2568 result[
BLACK] += table[index+1];
2569 result[
WHITE] += value_attack;
2573 result[
BLACK] -= value_attack;
2574 result[
WHITE] -= table[index+1];
2578 if (state.hasPieceOnStand<
ROOK>(
alt(Defense)))
2581 = isRookForkSquare(state, Defense, pi.
square(), pj.
square());
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) {
2586 rook_drop.second = -value_attack[0];
2587 rook_drop.first =
center;
2589 if (Defense ==
BLACK)
2591 result[
BLACK] += table[index+1];
2592 result[
WHITE] += value_attack;
2596 result[
BLACK] -= value_attack;
2597 result[
WHITE] -= table[index+1];
2603 assert(bishop_drop.second == 0 || ! bishop_drop.first.isPieceStand());
2609 CArray<std::pair<Square,int>,2>& bishop_drop,
2610 CArray<std::pair<Square,int>,2>& rook_drop)
2612 bishop_drop.fill(std::make_pair(
Square(),0));
2613 rook_drop.fill(std::make_pair(
Square(),0));
2615 const CArray<bool,2> has_bishop = {{
2619 const CArray<bool,2> has_rook = {{
2626 PieceMask notcovered = ~state.effectedMask(
BLACK);
2627 notcovered &= ~state.effectedMask(
WHITE);
2628 notcovered.clearBit<
PAWN>();
2629 notcovered.setBit<
KING>();
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]);
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]);
2649 osl::CArray<osl::MultiInt, 256*2*2>
2653 for (
int i = 0; i < ONE_DIM; ++i)
2656 table[i][s] = weights.
value(i + ONE_DIM*s);
2663 table[(index((
Ptype)j,(
Ptype)i)+DROP_DIM)*2+1] = table[(index((
Ptype)i,(
Ptype)j)+DROP_DIM)*2+1];
2667 template <osl::Player Defense>
2670 BoardMask& knight_fork_squares,
2671 std::pair<Square,int>& knight_drop)
2673 knight_fork_squares.clear();
2675 const int y_min = 3-z*2, y_max = 9-z*2;
2676 CArray<PieceVector,10> pieces;
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());
2685 pieces[y].push_back(p);
2689 for (
int y=y_min; y<=y_max; ++y){
2690 if (pieces[y].size() < 2)
2693 for (
size_t i=0; i<pieces[y].size(); ++i)
2695 const Piece pi = pieces[y][i];
2698 const int xi = pi.
square().
x();
2699 for (
size_t j=i+1; j<pieces[y].size(); ++j)
2701 const Piece pj = pieces[y][j];
2704 const int xj = pj.
square().
x();
2705 if (abs(xi -xj) != 2)
2708 knight_fork_squares.set(drop);
2709 if (! state[drop].isEmpty() || state.hasEffectAt(Defense, drop))
2715 const MultiInt value_attack = table[found];
2716 if (Defense ==
BLACK)
2718 result[
BLACK] += table[found+1];
2719 result[
WHITE] += value_attack;
2723 result[
BLACK] -= value_attack;
2724 result[
WHITE] -= table[found+1];
2726 if (has_knight && -value_attack[0] > knight_drop.second) {
2727 knight_drop.second = -value_attack[0];
2738 CArray<BoardMask,2>& knight_fork_squares,
2739 CArray<std::pair<Square,int>,2>& knight_drop)
2741 knight_drop.fill(std::make_pair(
Square(),0));
2743 const CArray<bool,2> has_knight = {{
2748 const CArray<bool,2> may_have_knight = {{
2759 + may_have_knight[
BLACK] + may_have_knight[
WHITE] == 0) {
2760 knight_fork_squares[
BLACK].invalidate();
2761 knight_fork_squares[
WHITE].invalidate();
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)]);
2771 knight_fork_squares[
alt(Defense)].invalidate();
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)]);
2780 knight_fork_squares[
alt(Defense)].invalidate();
2785 template <osl::Player P, osl::Player Defense>
2788 BoardMask& knight_fork_squares)
2790 assert(! knight_fork_squares.isInvalid());
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>());
2809 if (! isTarget(moved.
ptype())
2810 || (P ==
BLACK && to.y() < 3) || (P ==
WHITE && to.y() > 7))
2815 if (state[l2].isOnBoardByOwner<P>()) {
2816 knight_fork_squares.set(l.
neighbor<P,
U>().template neighbor<P,U>());
2822 if (state[r2].isOnBoardByOwner<P>()){
2823 knight_fork_squares.set(r.
neighbor<P,
U>().template neighbor<P,U>());
2828 template <osl::Player Defense>
2832 const BoardMask& knight_fork_squares,
2833 std::pair<Square,int>& knight_drop)
2836 BoardMask mask = knight_fork_squares;
2837 while (mask.any()) {
2838 Square sq = mask.takeOneBit();
2839 if (! state[sq].isEmpty() || state.hasEffectAt(Defense, sq))
2844 std::cerr << state << Defense <<
' ' << pi <<
' ' << pj <<
"\n";
2846 assert(pj.isOnBoardByOwner<Defense>());
2847 int found = index(pi.
ptype(), pj.ptype());
2851 const MultiInt value_attack = table[found];
2852 if (Defense ==
BLACK)
2854 result[
BLACK] += table[found+1];
2855 result[
WHITE] += value_attack;
2859 result[
BLACK] -= value_attack;
2860 result[
WHITE] -= table[found+1];
2862 if (has_knight && -value_attack[0] > knight_drop.second) {
2863 knight_drop.second = -value_attack[0];
2864 knight_drop.first = sq;
2870 template <osl::Player P>
2873 CArray<BoardMask,2>& knight_fork_squares,
2874 CArray<std::pair<Square,int>,2>& knight_drop)
2876 knight_drop.fill(std::make_pair(
Square(),0));
2878 const CArray<bool,2> has_knight = {{
2882 const CArray<bool,2> may_have_knight = {{
2893 + may_have_knight[
BLACK] + may_have_knight[
WHITE] == 0) {
2894 knight_fork_squares[
BLACK].invalidate();
2895 knight_fork_squares[
WHITE].invalidate();
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)]);
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)]);
2913 knight_fork_squares[
alt(Defense)].invalidate();
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)]);
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)]);
2930 knight_fork_squares[
alt(Defense)].invalidate();
2938 for (
size_t i = 0; i < ONE_DIM; ++i)
2941 table[i][s] = weights.
value(i + ONE_DIM*s);
2947 const CArray<std::pair<Square,Ptype>,5> pattern = {{
2955 bool match = state.kingSquare(
BLACK).x() >= 5;
2957 for (
size_t i=0; i<pattern.size(); ++i) {
2958 const Piece p = state.pieceAt(pattern[i].first);
2967 match = state.kingSquare(
WHITE).x() <= 5;
2969 for (
size_t i=0; i<pattern.size(); ++i) {
2970 const Piece p = state.pieceAt(pattern[i].first.rotate180());
2984 osl::CArray<osl::MultiInt, osl::PTYPE_SIZE>
2988 for (
size_t i = 0; i < ONE_DIM; ++i)
2991 table[i][s] = weights.
value(i + ONE_DIM*s);
2995 template <osl::Player P>
2999 CArray<int,PTYPE_SIZE>
count = {{ 0 }};
3000 for (
int x=1; x<=9; ++x) {
3002 if (! state[target].isEmpty())
3004 int a = state.countEffect(P, target);
3005 const int d = state.countEffect(
alt(P), target);
3006 if (a > 0 && a == d)
3010 const Ptype ptype = state.findCheapAttack(P, target).ptype();
3027 return evalOne<BLACK>(state, 3) + evalOne<WHITE>(state, 7);
3030 template <osl::Player P>
3048 template void PawnAdvanceAll::
3049 evalWithUpdateBang<BLACK>(
const NumEffectState &,
Move,
MultiInt&);
3050 template void PawnAdvanceAll::
3051 evalWithUpdateBang<WHITE>(
const NumEffectState &,
Move,
MultiInt&);
3053 evalWithUpdate<BLACK>(
const NumEffectState &,
Move,
MultiInt const&);
3055 evalWithUpdate<WHITE>(
const NumEffectState &,
Move,
MultiInt const&);
3057 evalWithUpdate<BLACK>(
const NumEffectState &,
Move,
MultiInt const&);
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&);
3065 template void osl::eval::ml::NonPawnAttacked::
3066 evalWithUpdateBang<BLACK>(
const NumEffectState &state,
3068 const CArray<PieceMask, 2> &effected,
3070 template void osl::eval::ml::NonPawnAttacked::
3071 evalWithUpdateBang<WHITE>(
const NumEffectState &state,
3073 const CArray<PieceMask, 2> &effected,
3075 template void osl::eval::ml::NonPawnAttackedPtype::
3076 evalWithUpdateBang<BLACK>(
3077 const NumEffectState &state,
3079 const CArray<PieceMask, 2> &effected,
3080 CArray<PieceMask, 40> &attacked_mask,
3082 template void osl::eval::ml::NonPawnAttackedPtype::
3083 evalWithUpdateBang<WHITE>(
3084 const NumEffectState &state,
3086 const CArray<PieceMask, 2> &effected,
3087 CArray<PieceMask, 40> &attacked_mask,
3089 template void osl::eval::ml::PtypeYPawnY::
3090 evalWithUpdateBang<BLACK>(
const NumEffectState &state,
3092 const CArray2d<int, 2, 9> &pawns,
3094 template void osl::eval::ml::PtypeYPawnY::
3095 evalWithUpdateBang<WHITE>(
const NumEffectState &state,
3097 const CArray2d<int, 2, 9> &pawns,
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,
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,
3110 unsigned int &ptypeo_mask);
3113 evalWithUpdate<BLACK>(
const NumEffectState&,
Move, CArray<BoardMask,2>&,
3114 CArray<std::pair<Square,int>,2>&);
3116 evalWithUpdate<WHITE>(
const NumEffectState&,
Move, CArray<BoardMask,2>&,
3117 CArray<std::pair<Square,int>,2>&);