3#ifndef OSL_MOVE_PROBABILITY_FEATURE_H
4#define OSL_MOVE_PROBABILITY_FEATURE_H
14 namespace move_probability
32 const int a = std::min(2, state.
countEffect(player, to));
52 return (move.
see > 0) ? 0 : ((move.
see == 0) ? 1 : 2);
59 if (ry == 0)
return 0;
60 return ry > 0 ? 1 : -1;
71 return w[offset+index];
92 return w[offset +
match];
104 int index = see / 128;
106 index = std::min(10, index);
108 }
else if (see == 0) {
112 index = std::max(0, index);
121 const int promote_index = to.
canPromote(player)
123 double sum = w[offset+see_index+promote_index*
SeeClass];
125 sum += w[offset+see_index+progress_index*
SeeClass];
150 return w[offset+index];
182 return w[index + offset];
198 return std::max(-3, std::min(to.
y() - from.
y(), 3));
207 const int from_to = move.
isDrop() ? 0
209 double sum = w[offset + index + from_to + 3];
211 sum += w[offset + index + 7];
212 sum += w[offset + index + state.
progress8()+8];
226 return std::max(-3, std::min(to.
x() - from.
x(), 3));
231 int to = move.
to().
x();
239 double sum = w[offset + index + from_to + 3];
241 sum += w[offset + index + 7];
242 sum += w[offset + index + state.
progress8()+8];
264 const int from_to = move.
isDrop() ? 0
267 size_t index = ((to.
y()-my_king.
y()+8)*
PTYPE_SIZE + ptype)*16;
269 double sum = w[offset + index + from_to + 3];
271 sum += w[offset + index + 7];
272 sum += w[offset + index + state.
progress8()+8];
276 sum += w[offset +
ONE_DIM + index + from_to + 3];
278 sum += w[offset +
ONE_DIM + index + 7];
300 const int from_to = move.
isDrop() ? 0
302 int dx = to.
x() - my_king.
x(), fx = from_to;
309 double sum = w[offset + index + fx + 3];
311 sum += w[offset + index + 7];
312 sum += w[offset + index + state.
progress8()+8];
314 dx = to.
x() - op_king.
x(), fx = from_to;
321 sum += w[offset +
ONE_DIM + index + fx + 3];
323 sum += w[offset +
ONE_DIM + index + 7];
346 return w[index + offset];
371 std::pair<Ptype,Ptype>& out)
373 out.first =
find(state, to, my_pin, turn).
ptype();
374 out.second =
find(state, to, op_pin,
alt(turn)).
ptype();
377 std::pair<Ptype,Ptype>& out)
382 info.
pin[
alt(turn)], turn, out);
390 std::pair<Ptype,Ptype> pair;
402 return w[index + offset];
429 size_t index = ptype;
430 for (
int i=0; i<3; ++i) {
431 index *= 2; index += me[i];
432 index *= 2; index += op[i];
435 return w[index + offset];
458 size_t index = ptype;
459 for (
int i=0; i<3; ++i) {
466 return w[index + offset];
491 const double *w,
Square position)
const
495 return w[offset + basic];
500 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i)
501 sum += w[offset + cache[i]];
509 template<
bool TestPromotable>
537 if (move.
from() != target)
538 sum +=
addOne(state, offset+basic, w, target);
540 sum +=
addOne(state, offset+basic_from, w, target);
544 if (move.
from() != target)
545 sum +=
addOne(state, offset+basic, w, target);
547 sum +=
addOne(state, offset+basic_from, w, target);
550 static std::string
name(
int x,
int y)
552 return std::string(
"Pattern")
553 + (TestPromotable ?
"P" :
"")
554 +
"X" + (
char)(
'2'+x) +
"Y"+(
char)(
'2'+y);
653 const int dy = (player ==
BLACK) ? -1 : 1;
663 return std::make_pair(u, uu);
681 const int index0 = (u.first*
PTYPE_SIZE*2+u.second)*2 + pawn_drop;
682 double sum = w[offset + index0];
686 sum += w[offset + index1*9+effect];
717 if (ptype ==
LANCE) index = 0;
718 else if (ptype ==
BISHOP) index = 1;
719 else if (ptype ==
ROOK) index = 2;
728 Square to,
const double *w,
int offset)
736 for (
int index: cache) {
738 sum += w[index+offset];
747 Square target,
const double *w,
int offset)
754 sum +=
addPiece(state, piece, target, w, offset);
760 sum +=
addPiece(state, piece, target, w, offset);
770 return findAll(state, P, target, w, offset);
861 directions &= directions-1;
862 sum +=
addOne(d, state, move, offset, w);
863 }
while (directions);
903 dx1 = std::min(dx1, 3);
904 dx2 = std::min(dx2, 3);
910 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i) {
932 int offset,
const double *w)
938 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i) {
939 sum += w[offset + type + cache[i]];
943 template <Direction D,Ptype Type>
946 int offset,
const double *w)
950 Square target = to + diff;
970 sum +=
addSquare(target, info, offset, w);
990 sum += addOne<UR,BISHOP>(state, move.
move.
to(), offset, w);
991 sum += addOne<UL,BISHOP>(state, move.
move.
to(), offset, w);
992 sum += addOne<DR,BISHOP>(state, move.
move.
to(), offset, w);
993 sum += addOne<DL,BISHOP>(state, move.
move.
to(), offset, w);
1013 sum += BishopAttack::addOne<R,ROOK>(state, to, offset, w);
1014 sum += BishopAttack::addOne<L,ROOK>(state, to, offset, w);
1016 const int scale = pawn_drop ? 1 : 2;
1017 sum += BishopAttack::addOne<U,ROOK>(state, to, offset+
DirectionSize*scale, w);
1018 sum += BishopAttack::addOne<D,ROOK>(state, to, offset+
DirectionSize*scale, w);
1050 if (move.
to() == threatmate.
to()
1060 if (effect.
offset() == threatmate.
to()-threatmate.
from())
1068 (state, move.
ptypeO(), move.
to(), king))
1092 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i) {
1100 sum += w[offset + base + PatternAny];
1101 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i) {
1102 sum += w[offset + base + cache[i]];
1109 sum += w[offset + base + PatternAny];
1110 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i) {
1111 sum += w[offset + base + cache[i]];
1117 sum += w[offset + base + PatternAny];
1118 for (
size_t i=0; i<cache.
size() && cache[i] >= 0; ++i) {
1119 sum += w[offset + base + cache[i]];
1173 int offset,
const double *w)
1180 if (to != defense.attack)
1182 assert(defense.general.owner() != move.
player());
1183 assert(defense.covered.owner() != move.
player());
1184 if (defense.general.square() == move.
to()+up)
1189 if (defense.covered.square().canPromote(state.
turn())
1192 const int b = defense.general.ptype() *
PTYPE_SIZE;
1193 const int c = defense.covered.ptype();
1196 sum += w[offset+1] * see/1024.0;
1197 sum += w[offset + a];
1198 sum += w[offset + b];
1199 sum += w[offset + c];
1200 sum += w[offset + a + b];
1201 sum += w[offset + a + c];
1202 sum += w[offset + b + c];
1203 if (defense.covered.square().canPromote(state.
turn())) {
1207 if (defense.covered.square().isNeighboring8(king)) {
1208 sum += w[offset + a +
KING];
1209 sum += w[offset + b +
KING];
1211 sum += w[offset + a + b + c];
1250 sum += w[offset + ptype_index + capture_index];
1251 sum += w[offset + capture_index];
1306 stand_pawn = std::min(2, stand_pawn);
1313 int index = (king_x * 3 + stand_pawn) * 2 + has_other;
1314 return w[offset + index];
1332 int to_x = move.
to().
x();
1335 || last_move.
to().
x() != to_x
1336 || last_move.
from().
x() != to_x)
1351 int index = ((king_x * 3 + stand_pawn) * 2 + has_other) * 2 + follow_pawn_capture;
1352 return w[offset + index];
1374 const Square front = last_move.
to()-diff, front2 = front-diff;
1385 const int ptype_index = moved*
PTYPE_SIZE+threatened;
1389 + (has_pawn ? pawn_index : 0);
1390 assert(effect_index >= 0);
1391 return w[offset + threatened]
1392 + w[offset + ptype_index]
1393 + w[offset + effect_index + ptype_index];
1416 double sum = w[offset + index];
1421 (*si.
state, my_last_move.
ptypeO(), my_last_move.
to(), king))
1422 sum += w[offset + index + 1];
1440 int dx = center.
x() - to.
x();
1441 const int dy = center.
y() - to.
y();
1442 if (abs(dx) >= 3 || abs(dy) >= 3)
1444 if ((king ==
BLACK && center.
x() > 5)
1445 || (king ==
WHITE && center.
x() >= 5))
1447 int sq_index = (dx+2)*5 + dy+2;
1453 return w[offset + index];
1481 if ((ki.
liberty() & (1<<d)) == 0)
1563 while (attacked.
any()) {
1569 while (copy.
any()) {
1574 sum += w[offset+index_a];
1575 sum += w[offset+b.
ptype()];
1576 sum += w[offset+index_a+b.
ptype()];
1602 sum += w[offset+1] * mi.
see/1024.0;
1639 bool can_promote =
false;
1641 if (to == move.
to())
1643 while (state[to].isEmpty()) {
1649 assert(state[to] != piece);
1655 && state[to].isOnBoardByOwner(
alt(mi.
player))
1658 sum += w[offset+1]*mi.
see/1024.0;
1669 sum += w[offset + index + state[to].ptype()];
1671 else if (can_promote) {
1673 sum += w[offset+1]*mi.
see/1024.0;
1681 sum += w[offset + index];
1713 if (! move.
isDrop() && state[move.
from()] == target) {
1714 sum += w[offset + t0];
1715 sum += w[offset + t1];
1716 sum += w[offset + t2];
1724 sum += w[offset + t0 + move.
ptype()];
1725 sum += w[offset + t1 + move.
ptype()];
1726 sum += w[offset + t2 + move.
ptype()];
1734 sum += w[offset + t0 + move.
ptype()];
1735 sum += w[offset + t1 + move.
ptype()];
1736 sum += w[offset + t2 + move.
ptype()];
const Offset getOffset(Direction dir) const
const Offset getShortOffsetNotKnight(Offset32 offset32) const
Longの利きの可能性のあるoffsetの場合は, 反復に使う offsetを Knight以外のShortの利きのoffsetの場合はそれ自身を返す.
bool isBetween(Square t, Square p0, Square p1) const
p0, p1の間にtがあるかどうか.
Direction getLongDirection(Offset32 offset32) const
const Offset offset() const
返り値が0なら長い利きがない, 0以外なら辿るのに必要なoffset (2005/3/25 に仕様変更 - 長い利きだが隣の場合もoffsetを返す)
bool hasEffect() const
短い利きがあるか,間がemptyなら長い利きがある
bool isMember(const T &e, const_iterator first, const_iterator last) const
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
PtypeO oldPtypeO() const
移動前のPtypeO, i.e., 成る手だった場合成る前
Ptype capturePtype() const
bool isNormal() const
INVALID でも PASS でもない.
bool isCaptureOrPromotion() const
Ptype oldPtype() const
移動前のPtype, i.e., 成る手だった場合成る前
const Square from() const
const NumBitmapEffect effectSetAt(Square sq) const
const Piece selectCheapPiece(PieceMask effect) const
利きの中から安そうな駒を選ぶ
const PieceMask effectedMask(Player pl) const
pl からの利きが(1つ以上)ある駒一覧
int countEffect(Player player, Square target) const
利きの数を数える.
bool hasEffectByPiece(Piece attack, Square target) const
駒attack が target に利きを持つか (旧hasEffectToと統合)
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
const Piece findCheapAttack(Player P, Square square) const
bool hasEffectIf(PtypeO ptypeo, Square attacker, Square target) const
attackerにptypeoの駒がいると仮定した場合にtargetに利きがあるかどうか を stateをupdateしないで確かめる.
bool inCheck(Player P) const
Pの玉が王手状態
const mask_t longEffectAt(Square target) const
const PieceMask & piecesOnBoard(Player p) const
const mask_t getMask(int num) const
void clearBit()
unpromote(PTYPE) の駒のbit を消す
static const CArray< Ptype, 7 > order
持駒の表示で良く使われる順番.
bool isPromoted() const
promoteした駒かどうかをチェックする
const Square square() const
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
const EffectContent getEffect(PtypeO ptypeo, Square from, Square to) const
fromにいるptypeoがtoに利きを持つか?
int getMoveMask(Ptype ptype) const
const Piece pieceOnBoard(Square sq) const
bool hasPieceOnStand(Player player, Ptype ptype) const
const Piece kingPiece() const
bool canDropPawnTo(Player player, int x) const
xの筋に歩を打てる
const Piece pieceOf(int num) const
bool isEmptyBetween(Square from, Square to, Offset offset, bool pieceExistsAtTo=false) const
Square kingSquare() const
int countPiecesOnStand(Player pl, Ptype ptype) const
持駒の枚数を数える
const Piece pieceAt(Square sq) const
unsigned int index() const
bool isPieceStand() const
int y() const
将棋としてのY座標を返す.
bool isNeighboring8(Square to) const
const Square squareForBlack(Player player) const
bool isOnBoard() const
盤面上を表すかどうかの判定. 1<=x() && x()<=9 && 1<=y() && y()<=9 Squareの内部表現に依存する.
bool isOnBoardRegion() const
squareがONBOARD_MINとONBOARD_MAXの間にある
int x() const
将棋としてのX座標を返す.
unsigned int liberty() const
8-15 bit 目を 0-7bitにshiftして返す
unsigned int libertyCount() const
libertyの数
bool hasLastMove(size_t last=1) const
const Move lastMove(size_t last=1) const
const mask_t selectLong() const
static bool hasEffect(const NumEffectState &state, PtypeO ptypeo, Square from, Square target)
ptypeo の駒がfromからtargetの8近傍に直接の利きを持つか
static double addOne(Direction dir, const StateInfo &state, const MoveInfo &move, int offset, const double *w)
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
AttackFromOpposingSliders()
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
AttackToOpposingSliders()
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
static double addSquare(Square target, const StateInfo &info, int offset, const double *w)
static double addOne(const StateInfo &info, Square to, int offset, const double *w)
static double findAll(const StateInfo &state, Move move, const double *w, int offset=0)
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
static void makeLongAttackOne(StateInfo &info, Piece piece, Direction d)
static void updateCache(StateInfo &)
static double findAll(const StateInfo &state, Move move, const double *w, int offset=0)
static int longAttackIndex(osl::PtypeO ptypeo)
static double findAll(const StateInfo &state, Player P, Square target, const double *w, int offset)
static double addPiece(const StateInfo &state, Piece piece, Square to, const double *w, int offset)
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
static int ptypeSupport(Ptype moved, bool has_support)
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
static bool isDefendingThreatmate(Move move, Move threatmate, const NumEffectState &state)
static bool isKingMove(Move move)
static bool isOpeningKingRoad(Move move, Square king)
double match(const StateInfo &info, const MoveInfo &move, int offset, const double *w) const
static bool isDefendingKing8(Move move, Square king, const NumEffectState &state)
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
static int sign(const NumEffectState &state, Move move, Player player)
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
static int checkIndex(const MoveInfo &move)
static bool hasSafeCapture(NumEffectState &state, Move)
double match(const StateInfo &info, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
static bool defending(const NumEffectState &state, Move move, Square target)
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
virtual double match(const StateInfo &, const MoveInfo &, int offset, const double *) const =0
static int classifyEffect9(const NumEffectState &state, Player player, Square to)
Feature(std::string n, size_t d)
double match(const StateInfo &state_info, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state_info, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
static double addOne(Player king, Square center, const StateInfo &si, const MoveInfo &mi, int offset, const double *w)
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
static bool blockAll(const King8Info &ki, Square king, Move move, const NumEffectState &state, const CArray< Direction, 3 > &directions)
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &info, const MoveInfo &move, int offset, const double *w) const
static double match(const NumEffectState &state, Move move, int see, const StateInfo::pinned_gs_t &pinned_list, int offset, const double *w)
double match(const StateInfo &info, const MoveInfo &move, int offset, const double *w) const
static int longPtype(const NumEffectState &state, Square position, Player player)
MoveFromOpposingSliders()
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
PatternBase(int x, int y)
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
static std::string name(int x, int y)
PatternCommon(const std::string &name, int dim)
static void updateCacheOne(Square target, StateInfo &info)
double addOne(const StateInfo &state, int offset, const double *w, Square position) const
static void updateCache(StateInfo &info)
double matchPtype(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
std::pair< int, int > squareStatus(const NumEffectState &state, Player player, Square to, Square &front) const
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
static int seeIndex(int see)
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &info, const MoveInfo &move, int offset, const double *w) const
static int fromTo(Square to, Square from)
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
static int fromTo(Square to, Square from)
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
double match(const StateInfo &state, const MoveInfo &move, int offset, const double *w) const
double match(const StateInfo &si, const MoveInfo &mi, int offset, const double *w) const
double match(const StateInfo &state_info, const MoveInfo &info, int offset, const double *w) const
static const Piece find(const NumEffectState &state, Square to, const PieceMask &remove, Player player)
static size_t supportAttack(const StateInfo &info, Square to, Move move)
double match(const StateInfo &state, const MoveInfo &info, int offset, const double *w) const
static void supportAttack(const NumEffectState &state, Square to, const PieceMask &my_pin, const PieceMask &op_pin, Player turn, std::pair< Ptype, Ptype > &out)
static void supportAttack(const StateInfo &info, Square to, Move move, std::pair< Ptype, Ptype > &out)
PatternBase< false > Pattern
PatternBase< true > PatternPromotion
const PtypeTable Ptype_Table
Ptype getPtype(PtypeO ptypeO)
bool canPromote(Ptype ptype)
ptypeがpromote可能な型かどうかのチェック promote済みの場合はfalseを返す
constexpr Direction longToShort(Direction d)
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
const BoardTable Board_Table
Player getOwner(PtypeO ptypeO)
unsigned int ptypeOIndex(PtypeO ptypeo)
Offset32Base< 8, 9 > Offset32
constexpr int sign(Player player)
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
constexpr bool isLong(Direction d)
constexpr Player alt(Player player)
Ptype promote(Ptype ptype)
promote可能なptypeに対して,promote後の型を返す promote不可のptypeを与えてはいけない.
PtypeO captured(PtypeO ptypeO)
unpromoteすると共に,ownerを反転する.
bool isMember(Square position) const
static bool hasEffect(const NumEffectState &, Square target, Player attack)
target に attack の追加利きが一つでもあるか. 相手の影利きが先にある場合は対象としない.
static int bsf(Integer mask)
int standIndex(const NumEffectState &state) const
CArray< Move, 2 > bookmove
CArray< Piece, 2 > threatened
unsigned int possible_threatmate_ptype
const NumEffectState * state
PieceVector king8_long_pieces
const MoveStack * history
CArray< bool, 2 > move_candidate_exists
CArray< pinned_gs_t, 2 > exchange_pins
bool pinByOpposingSliders(Piece p) const
CArray< pattern_square_t, Square::SIZE > pattern_cache
King8Info king8Info(Player pl) const
CArray< PieceMask, 2 > pin
CArray2d< long_attack_t, 40, 8 > long_attack_cache
PieceVector pin_by_opposing_sliders