My Project
feature_.cc
Go to the documentation of this file.
1 /* feature.cc
2  */
5 #include <iostream>
6 
9 {
10 }
11 
12 ␌
15 {
16  for (int x=1; x<=9; ++x) {
17  for (int y=1; y<=9; ++y) {
18  const Square position(x,y);
19  updateCacheOne(position, info);
20  }
21  }
22 }
23 
25 updateCacheOne(Square position, StateInfo& info)
26 {
27  const NumEffectState& state = *info.state;
29  = info.pattern_cache[position.index()];
30  cache.fill(-1);
31  const CArray<Square,2> kings = {{
32  state.kingSquare(BLACK),
33  state.kingSquare(WHITE),
34  }};
35  const Player turn = state.turn();
36  int cur = 0;
37 
38  Piece target = state.pieceAt(position);
39  PtypeO ptypeo = target.ptypeO();
40  if (turn == WHITE)
41  ptypeo = altIfPiece(ptypeo);
42  size_t basic = ptypeOIndex(ptypeo)*SquareDim;
43  std::pair<Ptype,Ptype> pair;
44  ToEffect::supportAttack(state, position,
45  info.pin[turn], info.pin[alt(turn)],
46  turn, pair);
47  int effect9 = classifyEffect9(state, turn, position);
48  cache[cur++] = basic + pair.first;
49  cache[cur++] = basic + AttackBase + pair.second;
50  cache[cur++] = basic + EffectBase + effect9;
51  assert(pair.first != PTYPE_EDGE);
52  assert(pair.second != PTYPE_EDGE);
53  if (isPiece(ptypeo)) {
54  if (info.attack_shadow[target.number()][turn])
55  cache[cur++] = basic + PTYPE_EDGE;
56  if (info.attack_shadow[target.number()][alt(turn)])
57  cache[cur++] = basic + AttackBase + PTYPE_EDGE;
58  }
59  assert(basic + EffectBase + effect9 < PatternCacheSize);
60  int op_king_distance = abs(kings[alt(turn)].x()-position.x())
61  + abs(kings[alt(turn)].y()-position.y());
62  if (op_king_distance == 0) // KING
63  op_king_distance = state.king8Info(alt(turn)).libertyCount();
64  else
65  --op_king_distance;
66  if (op_king_distance < OpKingSize)
67  cache[cur++] = basic + OpKingBase + op_king_distance;
68  int my_king_distance = abs(kings[turn].x()-position.x())
69  + abs(kings[turn].y()-position.y());
70  if (my_king_distance == 0) // KING
71  my_king_distance = state.king8Info(turn).libertyCount();
72  else
73  --my_king_distance;
74  if (my_king_distance < MyKingSize)
75  cache[cur++] = basic + MyKingBase + my_king_distance;
76  // promotion
77  if (position.canPromote(turn))
78  cache[cur++] = basic + PromotionBase;
79  else if (position.canPromote(alt(turn)))
80  cache[cur++] = basic + PromotionBase + 1;
81  if (target.isPiece()) {
82  // pin or open
83  if (state.pinOrOpen(turn).test(target.number()))
84  cache[cur++] = basic + PinOpenBase + (target.owner() == turn);
85  if (state.pinOrOpen(alt(turn)).test(target.number()))
86  cache[cur++] = basic + PinOpenBase + 2 + (target.owner() == alt(turn));
87  // last to
88  if (info.history->hasLastMove()) {
89  if (info.history->lastMove().to() == position)
90  cache[cur++] = basic + LastToBase;
91  for (int i=1; i<4; ++i) {
92  if (! info.history->hasLastMove(i+1))
93  break;
94  if (info.history->lastMove(i+1).to() == position)
95  cache[cur++] = basic + LastToBase + i;
96  }
97  }
98  }
99  // last effect changed
100  if (info.history->hasLastMove()) {
101  if (info.changed_effects.test(position))
102  cache[cur++] = basic + LastEffectChangedBase;
103  if (target.isPiece() && info.last_add_effect.test(target.number())) {
104  int ptype_index = info.last_move_ptype5 - PTYPE_BASIC_MIN + 1;
105  cache[cur++] = basic + LastEffectChangedBase + ptype_index;
106  }
107  }
108 }
109 
110 ␌
111 
114 {
115  const NumEffectState& state = *info.state;
116  for (int i=PtypeTraits<LANCE>::indexMin;
117  i<PtypeTraits<LANCE>::indexLimit; ++i) {
118  const Piece p = state.pieceOf(i);
119  if (! p.isOnBoard() || p.isPromoted())
120  continue;
121  const Direction d = p.owner() == BLACK ? U : D;
122  makeLongAttackOne(info, p, d);
123  }
125  i<PtypeTraits<BISHOP>::indexLimit; ++i) {
126  const Piece p = state.pieceOf(i);
127  if (! p.isOnBoard())
128  continue;
129  makeLongAttackOne(info, p, UL);
130  makeLongAttackOne(info, p, UR);
131  makeLongAttackOne(info, p, DL);
132  makeLongAttackOne(info, p, DR);
133  }
134  for (int i=PtypeTraits<ROOK>::indexMin;
135  i<PtypeTraits<ROOK>::indexLimit; ++i) {
136  const Piece p = state.pieceOf(i);
137  if (! p.isOnBoard())
138  continue;
139  makeLongAttackOne(info, p, L);
140  makeLongAttackOne(info, p, R);
141  makeLongAttackOne(info, p, U);
142  makeLongAttackOne(info, p, D);
143  }
144 }
145 
148  Piece piece, Direction d)
149 {
150  const NumEffectState& state = *info.state;
152  = info.long_attack_cache[piece.number()][d];
153  const Player turn = state.turn();
154  const PtypeO attacking = (turn == BLACK)
155  ? piece.ptypeO() : alt(piece.ptypeO());
156  Square attack_to = state.mobilityOf(d, piece.number());
157  Square attack_to2 = attack_to;
158  assert(! attack_to.isPieceStand());
159  if (attack_to.isEdge())
160  attack_to -= Board_Table.getOffsetForBlack(d);
161  else {
162  const Offset o = Board_Table.getOffsetForBlack(d);
163  attack_to2 += o; // allow edge if neighboring
164  if (state.pieceAt(attack_to2).isEmpty()) {
165  do {
166  attack_to2 += o;
167  } while (state.pieceAt(attack_to2).isEmpty());
168  if (state.pieceAt(attack_to2).isEdge())
169  attack_to2 -= o;
170  }
171  }
172  PtypeO attacked = state.pieceOnBoard(attack_to).ptypeO();
173  if (isPiece(attacked) && turn == WHITE)
174  attacked = alt(attacked);
175  int index = (longAttackIndex(attacking)*PTYPEO_SIZE
176  + ptypeOIndex(attacked))*OptionSize;
177  out.push_back(index);
178  if (attack_to.isNeighboring8(state.kingSquare(turn)))
179  out.push_back(index + 1); // 1,King8
180  if (! state.hasEffectAt(turn, attack_to))
181  out.push_back(index + 2); // 2,HasSupport;
182  if (attack_to.canPromote(alt(turn)))
183  out.push_back(index + 3); // 3,Promotable;
184  Piece attacked2 = state.pieceAt(attack_to2);
185  if (attacked2.isOnBoardByOwner(turn)) {
186  out.push_back(index + 4); // 4,Shadowing;
187  if (! state.hasEffectAt(turn, attack_to2))
188  out.push_back(index + 5); // 5,
189  if (attack_to2.canPromote(alt(turn)))
190  out.push_back(index + 6); // 6,
191  info.attack_shadow[attacked2.number()][piece.owner()] = true;
192  }
193  if (info.threatmate_move.isNormal()) {
194  Square threat_at = info.threatmate_move.to();
195  if (threat_at == attack_to
196  || (! Board_Table.getShortOffsetNotKnight(Offset32(threat_at, attack_to)).zero()
197  && Board_Table.isBetween(threat_at,
198  piece.square(), attack_to)))
199  out.push_back(index + 7); // 7, threatmate block?
200  }
201 }
202 
203 ␌
206 {
207  return ! checkmate::CheckmateIfCapture::effectiveAttack(state, move, 0);
208 }
209 
210 
211 // ;;; Local Variables:
212 // ;;; mode:c++
213 // ;;; c-basic-offset:2
214 // ;;; End:
const Offset getShortOffsetNotKnight(Offset32 offset32) const
Longの利きの可能性のあるoffsetの場合は, 反復に使う offsetを Knight以外のShortの利きのoffsetの場合はそれ自身を返す.
Definition: boardTable.h:119
bool isBetween(Square t, Square p0, Square p1) const
p0, p1の間にtがあるかどうか.
Definition: boardTable.h:172
const Offset getOffsetForBlack(Direction dir) const
黒にとってのoffsetを返す
Definition: boardTable.h:37
void fill(const T_simple &value=T_simple())
Definition: container.h:67
void push_back(const T &e)
Definition: container.h:204
圧縮していない moveの表現 .
Definition: basic_type.h:1052
bool isNormal() const
INVALID でも PASS でもない.
Definition: basic_type.h:1088
const Square to() const
Definition: basic_type.h:1132
利きを持つ局面
const checkmate::King8Info king8Info(Player king) const
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
Square mobilityOf(Direction d, int num) const
PieceMask pinOrOpen(Player king) const
差が uniqになるような座標の差分.
Definition: offset32.h:17
座標の差分
Definition: basic_type.h:430
bool test(int num) const
Definition: pieceMask.h:45
PtypeO ptypeO() const
Definition: basic_type.h:824
bool isPromoted() const
promoteした駒かどうかをチェックする
Definition: basic_type.h:898
const Square square() const
Definition: basic_type.h:832
bool isEmpty() const
Definition: basic_type.h:913
bool isEdge() const
Definition: basic_type.h:919
Player owner() const
Definition: basic_type.h:963
bool isPiece() const
Definition: basic_type.h:953
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition: basic_type.h:852
int number() const
Definition: basic_type.h:828
bool isOnBoard() const
Definition: basic_type.h:985
const Piece pieceOnBoard(Square sq) const
Definition: simpleState.h:170
Player turn() const
Definition: simpleState.h:220
const Piece pieceOf(int num) const
Definition: simpleState.h:76
Square kingSquare() const
Definition: simpleState.h:94
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
unsigned int index() const
Definition: basic_type.h:572
bool isPieceStand() const
Definition: basic_type.h:576
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
bool isNeighboring8(Square to) const
Definition: basic_type.cc:202
bool canPromote() const
Definition: basic_type.h:659
bool isEdge() const
onBoardから8近傍のオフセットを足した点がedgeかどうかの判定 そこそこ速くなった.
Definition: basic_type.h:591
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
unsigned int libertyCount() const
libertyの数
Definition: king8Info.h:82
bool test(unsigned int i) const
Definition: boardMask.h:52
bool hasLastMove(size_t last=1) const
Definition: moveStack.h:27
const Move lastMove(size_t last=1) const
Definition: moveStack.h:28
static void makeLongAttackOne(StateInfo &info, Piece piece, Direction d)
Definition: feature_.cc:147
static void updateCache(StateInfo &)
Definition: feature_.cc:113
static bool hasSafeCapture(NumEffectState &state, Move)
Definition: feature_.cc:205
static void updateCacheOne(Square target, StateInfo &info)
Definition: feature_.cc:25
static void updateCache(StateInfo &info)
Definition: feature_.cc:14
static void supportAttack(const NumEffectState &state, Square to, const PieceMask &my_pin, const PieceMask &op_pin, Player turn, std::pair< Ptype, Ptype > &out)
@ PTYPE_EDGE
Definition: basic_type.h:86
@ PTYPE_BASIC_MIN
Definition: basic_type.h:103
const int PTYPEO_SIZE
Definition: basic_type.h:308
const BoardTable Board_Table
Definition: tables.cc:95
Direction
Definition: basic_type.h:310
@ R
Definition: basic_type.h:317
@ D
Definition: basic_type.h:319
@ UL
Definition: basic_type.h:313
@ DR
Definition: basic_type.h:320
@ U
Definition: basic_type.h:314
@ L
Definition: basic_type.h:316
@ UR
Definition: basic_type.h:315
@ DL
Definition: basic_type.h:318
unsigned int ptypeOIndex(PtypeO ptypeo)
Definition: basic_type.h:205
Player
Definition: basic_type.h:8
@ WHITE
Definition: basic_type.h:10
@ BLACK
Definition: basic_type.h:9
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
Definition: basic_type.h:120
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
constexpr Player alt(Player player)
Definition: basic_type.h:13
PtypeO altIfPiece(PtypeO ptypeO)
Pieceの時にはowner を反転する
Definition: basic_type.h:281
static bool effectiveAttack(NumEffectState &state, Move move, int depth)
move を指した後,alt(move.player())が取ると詰みかどうか.
const NumEffectState * state
Definition: stateInfo.h:22
CArray2d< bool, 40, 2 > attack_shadow
Definition: stateInfo.h:31
const MoveStack * history
Definition: stateInfo.h:23
CArray< pattern_square_t, Square::SIZE > pattern_cache
Definition: stateInfo.h:30
CArray< PieceMask, 2 > pin
Definition: stateInfo.h:34
CArray2d< long_attack_t, 40, 8 > long_attack_cache
Definition: stateInfo.h:28