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;
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;
166 if (attack_count == 0)
168 const int defense_count = state.
countEffect(defense, target);
169 if (defense_count == 1)
171 else if (attack_count >= defense_count)
193 if (attack_count == 0)
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)
206template <
class MakeEffectState>
208#if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
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)];
234template <
class MakeEffectState>
236#if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
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];
270template <
class MakeEffectState>
277 CArray<int,2> result_o = last_value_o, result_e = last_value_e;
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);
308template <
bool Opening>
313 for (
size_t i = 0; i < weights.
dimension(); ++i)
315 table[i] = weights.
value(i);
319template <
bool Opening>
323 return evalCommon<MakeEffectStateSimple>(state, table);
325template <
bool Opening>
330 return evalWithUpdateCommon<MakeEffectStateSimple>
331 (new_state, last_move, last_value, table);
340 return evalWithUpdateCommon<MakeEffectStateSimple>
341 (new_state, last_move, last_value_opening, last_value_ending,
346template <
bool Opening>
351 for (
size_t i = 0; i < weights.
dimension(); ++i)
353 table[i] = weights.
value(i);
356template <
bool Opening>
360 return evalCommon<MakeEffectStateDefense>(state, table);
362template <
bool Opening>
367 return evalWithUpdateCommon<MakeEffectStateDefense>
368 (new_state, last_move, last_value, table);
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);
443 defense_effect = NOT_EMPTY;
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;
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);
646 adjust<1>(index(black_king),
647 indexY<BLACK>(black_king),
660 adjust<-1>(index(white_king),
661 indexY<WHITE>(white_king),
668template <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);
691template <osl::Player P>
698 if ((diff == 1) ^ (P ==
BLACK))
702 assert((diff == 1 && P ==
BLACK) || (diff == -1 && P ==
WHITE));
708 const int target_x = pos.
x() + diff;
709 for (
int y = pos.
y() - 1; y <= pos.
y() + 1; ++y)
711 Square target(target_x, y);
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)];
772 const table_t& table_o,
const table_t& table_e)
779 mask.
set(last_move.
from()); mask.set(last_move.
to());
780 if (mask.anyInRange(Board_Mask_Table3x3.
mask(black_king)))
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)];
793 if (mask.anyInRange(Board_Mask_Table3x3.
mask(white_king)))
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);
831 mask.
set(last_move.
from()); mask.set(last_move.
to());
832 if (mask.anyInRange(Board_Mask_Table3x3.
mask(black_king)))
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),
854 if (mask.anyInRange(Board_Mask_Table3x3.
mask(white_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),
878template <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))));
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;
1042template <osl::Player 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);
1054 result +=table[index(king,
Square(king.
x(), y))];
1056 result +=table[index(king,
Square(x, y))];
1058 result +=table[index(king,
Square(x, king.
y()))];
1062 result -=table[index(king,
Square(king.
x(), y))];
1064 result -=table[index(king,
Square(x, y))];
1066 result -=table[index(king,
Square(x, king.
y()))];
1075 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
const Square nextSquare(Player P, Square pos, Direction dr) const
next position from pos for player P.
void fill(const T_simple &value=T_simple())
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
const Square square() const
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
const Piece kingPiece() const
Square kingSquare() const
const Piece pieceAt(Square sq) const
int y() const
将棋としてのY座標を返す.
bool isOnBoard() const
盤面上を表すかどうかの判定. 1<=x() && x()<=9 && 1<=y() && y()<=9 Squareの内部表現に依存する.
int x() const
将棋としてのX座標を返す.
unsigned int liberty() const
8-15 bit 目を 0-7bitにshiftして返す
const BoardMask & mask(Square p) const
p中心の3x3 の範囲のbitを立てたもの, centeringなし
bool anyInRange(const BoardMask &mask) const
static MultiInt evalOne(const NumEffectState &state)
static void setUp(const Weights &weights, int stage)
static CArray< MultiInt, 4 > table
static int index(Square king, Square target)
static MultiInt eval(const NumEffectState &state)
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)
static CArray< int, ONE_DIM > r_defense_piece_table
static void setUp(const Weights &weights)
static int index(const Direction dir, EffectState state)
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 &)
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)
static const CArray< int, 2 > evalWithUpdate(const NumEffectState &new_state, Move last_move, const CArray< int, 2 > &last_value)
static void setUp(const Weights &weights)
static const CArray< int, 2 > eval(const NumEffectState &state)
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)
static const CArray< int, 2 > eval(const NumEffectState &state)
static const CArray< int, 2 > evalWithUpdate(const NumEffectState &new_state, Move last_move, const CArray< int, 2 > &last_value)
static void setUp(const Weights &weights)
static CArray< int, 32 > defense_table
static int indexY(Piece king, const Direction dir, EffectState state)
static int eval(const NumEffectState &state)
static CArray< int, 288 > empty_y_table
static CArray< int, 32 > empty_table
static void setUp(const Weights &weights)
static int index(const Direction dir, EffectState state)
static void effectState(const NumEffectState &state, const Player defense, const Direction dir, EffectState &empty, EffectState &)
static CArray< int, 288 > defense_y_table
static void setUp(const Weights &weights)
static CArray< MultiInt, 80 > table
static CArray< MultiInt, 720 > y_table
static void setUp(const Weights &weights)
static MultiInt eval(const NumEffectState &state)
static void evalWithUpdateBang(const NumEffectState &new_state, Move last_move, MultiIntPair &last_values_and_out)
static void evalWithUpdateBang(const NumEffectState &state, Move laste_move, MultiIntPair &last_values_and_out)
static int index(Square king, int diff)
static const MultiIntPair eval(const NumEffectState &state, const table_t &table)
static void adjust(int index, int index_y, MultiInt &out)
static void setUp(const Weights &weights, int stage)
static void setUp(const Weights &weights, int stage)
static CArray< MultiInt, ONE_DIM > table
static void setUp(const Weights &weights)
static void adjust(int index, int index_y, MultiInt &out)
static MultiIntPair eval(const NumEffectState &state)
static CArray< MultiInt, ONE_DIM > table
static void setUp(const Weights &weights)
static int index(const Square king)
constexpr Player indexToPlayer(int n)
constexpr int playerToIndex(Player player)
const BoardTable Board_Table
const PtypeO PTYPEO_EDGE __attribute__((unused))
constexpr Player alt(Player player)
EffectState operator()(const NumEffectState &state, const Player defense, const Direction dir) const
EffectState operator()(const NumEffectState &state, const Player defense, const Direction dir) const
static bool isBlocked(const NumEffectState &state, int diff)
static int index(Square king, int diff)
static const MultiIntPair eval(const NumEffectState &state, const table_t &table)
int value(size_t index) const