My Project
stateInfo.cc
Go to the documentation of this file.
1/* stateInfo.cc
2 */
9#include "osl/hashKey.h"
11#include <iostream>
12
15{
16 const osl::Player turn = state->turn();
17 threatmate_move = Move();
18 attack_shadow.fill(false); // need everytime
19 pin[BLACK] = state->pin(BLACK);
20 pin[WHITE] = state->pin(WHITE);
21 move_candidate_exists[BLACK] = king8Info(BLACK).hasMoveCandidate<WHITE>(*state);
22 move_candidate_exists[WHITE] = king8Info(WHITE).hasMoveCandidate<BLACK>(*state);
23
24 checkmate_defender[BLACK] = findCheckmateDefender(*state, BLACK);
25 checkmate_defender[WHITE] = findCheckmateDefender(*state, WHITE);
26
27 sendoffs.clear();
28 if (state->hasChangedEffects())
29 changed_effects = state->changedEffects(alt(turn));
30 else
31 changed_effects.invalidate();
32 threatened[turn] = state->inCheck(turn)
33 ? state->kingPiece(turn) : state->findThreatenedPiece(turn);
34 threatened[alt(turn)] = state->findThreatenedPiece(alt(turn));
35
36 {
37 possible_threatmate_ptype
38 = checkmate::Immediate_Checkmate_Table.dropPtypeMask(king8Info(alt(state->turn())));
39 const Square king = state->kingSquare(alt(state->turn()));
40 const CArray<Direction,2> directions = {{ UUL, UUR }};
41 for (Direction d: directions) {
42 Square knight_attack = king - Board_Table.getOffset(state->turn(), d);
43 if (state->pieceAt(knight_attack).isEmpty()
44 && ! state->hasEffectAt(alt(state->turn()), knight_attack)) {
45 possible_threatmate_ptype |= (1<<(KNIGHT-PTYPE_BASIC_MIN));
46 break;
47 }
48 }
49 for (int p=PTYPE_BASIC_MIN; p<=PTYPE_MAX; ++p) {
50 if (possible_threatmate_ptype & (1<<p))
51 if (state->hasPieceOnStand(state->turn(), static_cast<Ptype>(p)))
52 p &= ~(1<<p);
53 }
54 }
55 bookmove.fill(Move());
56}
57
60{
61 copy.copyFrom(*state);
62 const osl::Player turn = state->turn();
63 const Square king = state->kingSquare(alt(turn));
64 effect_util::SendOffSquare::find(turn, *state, king, sendoffs);
65
66 updatePinnedGenerals(BLACK);
67 updatePinnedGenerals(WHITE);
68
69 makePinOfLongPieces();
70 for (int d=SHORT8_DIRECTION_MIN; d<=SHORT8_DIRECTION_MAX; ++d) {
71 Piece p = state->pieceAt(state->kingMobilityAbs(alt(turn), (Direction)d));
72 if (p.isOnBoardByOwner(alt(turn)))
73 king8_long_pieces.push_back(p);
74 }
75 BlockLong::updateCache(*this);
76 if (! history->hasLastMove() || !history->lastMove().isNormal()) {
77 last_move_ptype5 = PTYPE_EMPTY;
78 last_add_effect = PieceMask();
79 } else {
80 last_move_ptype5 = unpromote(history->lastMove().ptype());
81 if (last_move_ptype5 == SILVER)
82 last_move_ptype5 = GOLD;
83 else if (last_move_ptype5 == KNIGHT)
84 last_move_ptype5 = LANCE;
85 else if (isMajor(last_move_ptype5))
86 last_move_ptype5 = KNIGHT;
87 last_add_effect = state->effectedMask(alt(turn))
88 & state->effectedChanged(alt(turn));
89 }
90 PatternCommon::updateCache(*this); // depends on attack_shadow, last_add_effect
91 {
92 MoveVector all;
93 static const BookInMemory& book = BookInMemory::instance();
94 book.find(HashKey(*state), all);
95 for (size_t i=0; i<bookmove.size(); ++i)
96 if (all.size() > i)
97 bookmove[i] = all[i];
98 }
99 dirty = false;
100}
101
104{
105 using namespace osl;
106 if (state->inCheck())
107 return;
108 for (int i=0; i<40; ++i) {
109 const Piece p = state->pieceOf(i);
110 if (!p.isOnBoard() || p.ptype() == KING)
111 continue;
112 CArray<mask_t,2> long_effect = {{
113 state->longEffectAt(p.square(), BLACK),
114 state->longEffectAt(p.square(), WHITE),
115 }};
116 if (long_effect[0].none() || long_effect[1].none()) continue;
117 CArray<Piece,2> attack_piece;
118 {
119 attack_piece[0] = state->findLongAttackAt(p, U);
120 attack_piece[1] = state->findLongAttackAt(p, D);
121 if (attack_piece[0].isPiece() && attack_piece[1].isPiece()
122 && attack_piece[0].owner() != attack_piece[1].owner()) {
123 pin_by_opposing_sliders.push_back(p);
124 continue;
125 }
126 }
127 if ((long_effect[0] & mask_t::makeDirect(PtypeFuns<ROOK>::indexMask)).any()
128 && (long_effect[0] & mask_t::makeDirect(PtypeFuns<ROOK>::indexMask)).any())
129 {
130 attack_piece[0] = state->findLongAttackAt(p, L);
131 attack_piece[1] = state->findLongAttackAt(p, R);
132 if (attack_piece[0].isPiece() && attack_piece[1].isPiece()
133 && attack_piece[0].owner() != attack_piece[1].owner()) {
134 pin_by_opposing_sliders.push_back(p);
135 continue;
136 }
137 }
138 if ((long_effect[0] & mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)).any()
139 && (long_effect[0] & mask_t::makeDirect(PtypeFuns<BISHOP>::indexMask)).any())
140 {
141 attack_piece[0] = state->findLongAttackAt(p, UL);
142 attack_piece[1] = state->findLongAttackAt(p, DR);
143 if (attack_piece[0].isPiece() && attack_piece[1].isPiece()
144 && attack_piece[0].owner() != attack_piece[1].owner()) {
145 pin_by_opposing_sliders.push_back(p);
146 continue;
147 }
148 attack_piece[0] = state->findLongAttackAt(p, UR);
149 attack_piece[1] = state->findLongAttackAt(p, DL);
150 if (attack_piece[0].isPiece() && attack_piece[1].isPiece()
151 && attack_piece[0].owner() != attack_piece[1].owner()) {
152 pin_by_opposing_sliders.push_back(p);
153 continue;
154 }
155 }
156 }
157}
158
159std::pair<osl::Piece,osl::Square> osl::move_probability::
161{
162 const King8Info king8info = state.king8Info(king);
163 const unsigned int spaces = king8info.spaces();
164 if (spaces == 0 || (spaces & (spaces-1)))
165 return std::make_pair(Piece::EMPTY(), Square());
166 const Square sq = state.kingSquare(king)
167 + Board_Table.getOffset(king, (Direction)misc::BitOp::bsf(spaces));
168 assert(state.pieceAt(sq).isEmpty());
169 if (state.countEffect(king, sq) != 2 || ! state.hasEffectAt(alt(king), sq))
170 return std::make_pair(Piece::EMPTY(), Square());
171 unsigned int drop_candidate = king8info.libertyDropMask();
172 drop_candidate &= 0xff00;
173 drop_candidate += spaces;
174 mask_t drop_ptype=mask_t::makeDirect
175 (checkmate::Immediate_Checkmate_Table.dropPtypeMaskOf(drop_candidate));
176 while(drop_ptype.any()){
177 Ptype ptype=static_cast<Ptype>(drop_ptype.takeOneBit()+PTYPE_BASIC_MIN);
178 if (state.hasPieceOnStand(alt(king),ptype))
179 return std::make_pair(state.findCheapAttack(king, sq), sq);
180 }
181 return std::make_pair(Piece::EMPTY(), Square());
182}
183
186{
187 exchange_pins[owner].clear();
188 PieceMask attacked = state->piecesOnBoard(owner)
189 & state->effectedMask(owner) & state->effectedMask(alt(owner));
190 while (attacked.any()) {
191 const Piece p = state->pieceOf(attacked.takeOneBit());
192 const int a = state->countEffect(alt(owner), p.square());
193 const int d = state->countEffect(owner, p.square());
194 if (d != a)
195 continue;
196 const Piece attack_p = state->findCheapAttack(alt(owner), p.square());
197 const Piece support = state->findCheapAttack(owner, p.square());
198 if (support.ptype() == PAWN || support.ptype() == LANCE)
199 continue;
200 unsigned int directions = Ptype_Table.getMoveMask(support.ptype());
201 while (directions) {
202 Direction d = static_cast<Direction>(misc::BitOp::bsf(directions));
203 directions &= directions-1;
204 Square target = support.square() + Board_Table.getOffset(owner, d);
205 if (target == p.square())
206 continue;
207 Piece tp = state->pieceAt(target);
208 if (tp.isEmpty() || tp.isOnBoardByOwner(owner)) {
209 assert(state->hasEffectByPiece(support, target));
210 if (state->countEffect(owner, target)
211 <= state->countEffect(alt(owner), target)+1
212 - state->hasEffectByPiece(attack_p, target)
213 && ! state->hasEffectIf(support.ptypeO(), target, p.square()))
214 exchange_pins[owner].push_back
215 (PinnedGeneral(support, p, target));
216 }
217 }
218 }
219}
220
223{
224 if (state.inCheck())
225 return Move();
226 NumEffectState copy(state);
227 copy.changeTurn();
228 checkmate::FixedDepthSearcher searcher(copy);
229
230 Move best_move;
231 const ProofDisproof pdp
232 = searcher.hasCheckmateMoveOfTurn(2, best_move);
233 if (pdp.isCheckmateSuccess())
234 return best_move;
235 if (pdp.isFinal())
236 return Move();
237 if (last_move.isNormal() && Neighboring8Direct::hasEffect
238 (state, last_move.ptypeO(), last_move.to(), state.kingSquare(state.turn()))) {
239 const ProofDisproof pdp4
240 = searcher.hasCheckmateMoveOfTurn(4, best_move);
241 if (pdp4.isCheckmateSuccess())
242 return best_move;
243 if (state.hasPieceOnStand<GOLD>(alt(state.turn()))) {
244 const ProofDisproof pdp6
245 = searcher.hasCheckmateMoveOfTurn(6, best_move);
246 if (pdp6.isCheckmateSuccess())
247 return best_move;
248 }
249 }
250 return Move();
251}
252
254{
255 for (int x=1; x<=9; ++x) {
256 for (int y=1; y<=9; ++y) {
257 const Square position(x,y);
258 if (! (l.pattern_cache[position.index()]
259 == r.pattern_cache[position.index()]))
260 return false;
261 }
262 }
263 return HashKey(*l.state) == HashKey(*r.state)
264 && *l.history == *r.history
267 && l.threatened == r.threatened
270 && l.progress16 == r.progress16
273 && l.pin == r.pin && l.threatmate_move == r.threatmate_move
274 && l.sendoffs == r.sendoffs
278 && HashKey(l.copy) == HashKey(r.copy);
279}
280
281// ;;; Local Variables:
282// ;;; mode:c++
283// ;;; c-basic-offset:2
284// ;;; End:
const Offset getOffset(Direction dir) const
Definition boardTable.h:47
size_t size() const
Definition container.h:243
圧縮していない moveの表現 .
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
bool isNormal() const
INVALID でも PASS でもない.
const Square to() const
利きを持つ局面
const checkmate::King8Info king8Info(Player king) const
int countEffect(Player player, Square target) const
利きの数を数える.
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
const Piece findCheapAttack(Player P, Square square) const
bool inCheck(Player P) const
Pの玉が王手状態
駒番号のビットセット.
Definition pieceMask.h:21
bool any() const
Definition pieceMask.h:57
PtypeO ptypeO() const
Definition basic_type.h:824
Ptype ptype() const
Definition basic_type.h:821
const Square square() const
Definition basic_type.h:832
bool isEmpty() const
Definition basic_type.h:913
bool isOnBoardByOwner() const
piece がプレイヤーPの持ち物でかつボード上にある駒の場合は true.
Definition basic_type.h:852
bool isOnBoard() const
Definition basic_type.h:985
int getMoveMask(Ptype ptype) const
Definition ptypeTable.h:84
bool hasPieceOnStand(Player player, Ptype ptype) const
Player turn() const
void changeTurn()
手番を変更する
Square kingSquare() const
Definition simpleState.h:94
const Piece pieceAt(Square sq) const
unsigned int index() const
Definition basic_type.h:572
void find(const HashKey &key, MoveVector &out) const
深さ固定で,その深さまで depth first searchで読む詰将棋.
const ProofDisproof hasCheckmateMoveOfTurn(int depth, Move &best_move)
敵玉の8近傍の状態を表す.
Definition king8Info.h:29
unsigned int libertyDropMask() const
0-15bit
Definition king8Info.h:59
unsigned int spaces() const
Definition king8Info.h:73
証明数(proof number)と反証数(disproof number).
bool operator==(const PinnedGeneral &l, const PinnedGeneral &r)
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
@ PTYPE_MAX
Definition basic_type.h:105
@ PAWN
Definition basic_type.h:95
@ KING
Definition basic_type.h:93
@ KNIGHT
Definition basic_type.h:97
@ PTYPE_EMPTY
Definition basic_type.h:85
@ SILVER
Definition basic_type.h:98
@ PTYPE_BASIC_MIN
Definition basic_type.h:103
@ GOLD
Definition basic_type.h:94
@ LANCE
Definition basic_type.h:96
const PtypeTable Ptype_Table
Definition tables.cc:97
Ptype unpromote(Ptype ptype)
ptypeがpromote後の型の時に,promote前の型を返す. promoteしていない型の時はそのまま返す
Definition basic_type.h:157
const BoardTable Board_Table
Definition tables.cc:95
Direction
Definition basic_type.h:310
@ SHORT8_DIRECTION_MIN
Definition basic_type.h:312
@ UUR
Definition basic_type.h:323
@ UUL
Definition basic_type.h:322
@ SHORT8_DIRECTION_MAX
Definition basic_type.h:321
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
bool isMajor(Ptype ptype)
Definition basic_type.h:185
constexpr Player alt(Player player)
Definition basic_type.h:13
void updatePinnedGenerals(Player owner)
Definition stateInfo.cc:185
static std::pair< Piece, Square > findCheckmateDefender(const NumEffectState &state, Player king)
Definition stateInfo.cc:160
CArray< Piece, 2 > threatened
Definition stateInfo.h:26
const NumEffectState * state
Definition stateInfo.h:22
CArray2d< bool, 40, 2 > attack_shadow
Definition stateInfo.h:31
static Move findShortThreatmate(const NumEffectState &, Move last_move)
Definition stateInfo.cc:222
CArray< bool, 2 > move_candidate_exists
Definition stateInfo.h:39
CArray< pinned_gs_t, 2 > exchange_pins
Definition stateInfo.h:38
CArray< std::pair< Piece, Square >, 2 > checkmate_defender
Definition stateInfo.h:42
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