My Project
proofNumberTable.h
Go to the documentation of this file.
1/* proofNumberTable.h
2 */
3#ifndef OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
4#define OSL_CHECKMATE_PROOF_NUMBER_TABLE_H
10
11namespace osl
12{
13 namespace checkmate
14 {
16 {
17 public:
18 struct Liberty
19 {
21 uint8_t liberty;
24 explicit Liberty(uint8_t l=0, bool e=false) : liberty(l), has_effect(e)
25 {
26 }
27 };
28 private:
44 public:
45 void init();
46
50 const Liberty countLiberty(Ptype ptype, Direction d, unsigned int liberty_mask) const
51 {
52 assert((d != UUL) && (d != UUR));
53 assert(liberty_mask <= 0xff);
54 return liberties[liberty_mask][ptype][d];
55 }
63 Square king, King8Info info) const
64 {
65 assert(to.isNeighboring8(king));
66 assert(ptype != KNIGHT);
67 const unsigned int liberty_mask = info.liberty();
68 const Direction d =
69 (player == BLACK)
70 ? Board_Table.getShort8<BLACK>(to, king)
71 : Board_Table.getShort8<WHITE>(to, king);
72 return countLiberty(ptype, d, liberty_mask);
73 }
74 const Liberty countLibertyLong(Player player, Square to, Ptype ptype,
75 Square king, King8Info info) const
76 {
77 assert(! to.isNeighboring8(king));
78 const unsigned int liberty_mask = info.liberty();
79 const Offset32 offset32(king,to);
80 const Offset offset = Board_Table.getShortOffsetNotKnight(offset32);
81 if (offset.zero())
82 return Liberty(0, false);
83 if (to + offset + offset != king) // 2マス以上遠く
84 {
85 if (isMajor(ptype))
86 ptype = unpromote(ptype);
87 else if (ptype != LANCE)
88 return Liberty(0, false);
89 }
90 const Direction d =
91 (player == BLACK)
94 assert(isLong(d));
95 return countLiberty(ptype, d, liberty_mask);
96 }
100 int countLiberty(const NumEffectState& state, int liberty_count,
101 Move move, Square king, King8Info info) const
102 {
103 assert(liberty_count == misc::BitOp::countBit(info.liberty()));
104 const Player attack = move.player();
105 const Player defense = alt(attack);
106 const Square to = move.to();
107 const Ptype ptype = move.ptype();
108 if (ptype == KNIGHT)
109 return std::max(1,liberty_count + state.countEffect(defense, to));
110
111 const bool neighboring = to.isNeighboring8(king);
112 Liberty liberty = neighboring
113 ? countLibertyShortNotKnight(attack, to, ptype, king, info)
114 : countLibertyLong(attack, to, ptype, king, info);
115 if (liberty.liberty == 0)
116 return std::max(liberty_count-1,1);
117 if (! neighboring && liberty.has_effect)
118 {
119 // TODO: 詰将棋と協調できるなら liberty.liberty <=
120 // liberty_count を保つように調整したい,が.
121 ++liberty.liberty; // 合駒の分,もし両王手の場合は本来は不要
122 }
123
124 liberty.liberty += state.countEffect(defense, to);
125 if (move.isDrop())
126 {
127 if (neighboring)
128 {
129 if (state.countEffect(attack, to))
130 --liberty.liberty; // adjust king capture
131 }
132 assert(liberty.liberty);
133 return liberty.liberty;
134 }
135 // 移動: 銀のただすてなどは本当は利きをはずしたい
136 if (neighboring)
137 {
138 if (state.countEffect(attack, to) >= 2
139 || effect_util::AdditionalEffect::hasEffect(state, to, attack))
140 --liberty.liberty; // adjust king capture
141 }
142 assert(liberty.liberty);
143 return liberty.liberty;
144 }
146 int countLiberty(const NumEffectState& state, Move move) const;
147
149 int
150#ifdef __GNUC__
151 __attribute__ ((pure))
152#endif
153 libertyAfterAllDrop(const NumEffectState& state) const;
154 int
155#ifdef __GNUC__
156 __attribute__ ((pure))
157#endif
158 libertyAfterAllDrop(const NumEffectState& state, Player attack,
159 King8Info info) const;
161 int
162#ifdef __GNUC__
163 __attribute__ ((pure))
164#endif
165 libertyAfterAllMove(const NumEffectState& state) const;
166 int
167#ifdef __GNUC__
168 __attribute__ ((pure))
169#endif
170 libertyAfterAllMove(const NumEffectState& state, Player attack,
171 King8Info info, Square king) const;
173 int
174#ifdef __GNUC__
175 __attribute__ ((pure))
176#endif
177 libertyAfterAllCheck(const NumEffectState& state) const;
178
179 int
180#ifdef __GNUC__
181 __attribute__ ((pure))
182#endif
185 const ProofDisproof
186#ifdef __GNUC__
187 __attribute__ ((pure))
188#endif
189 attackEstimation(const NumEffectState& state) const;
190 const ProofDisproof
191#ifdef __GNUC__
192 __attribute__ ((pure))
193#endif
194 attackEstimation(const NumEffectState& state,
195 Player attack,
196 King8Info info, Square king) const;
197 };
198 // tables.ccに入れればconstにできる
200
202 {
204 public:
205 void init();
207 const King8Info
208#ifdef __GNUC__
209 __attribute__ ((pure))
210#endif
211 resetEdgeFromLiberty(Player king_player, Square king, King8Info info) const
212 {
213 uint64_t ret = info.uint64Value();
214 ret &= edge_mask[king_player][king.index()];
215 const uint64_t count = misc::BitOp::countBit((ret>>8)&0xffull);
216 ret |= count << 48;
217 return King8Info(ret);
218 }
219 };
220 extern EdgeTable Edge_Table;
221 }
222}
223
224#endif /* _CHECKMATE_IMMEDIATE_CHECKMATE_TABLE_H */
225// ;;; Local Variables:
226// ;;; mode:c++
227// ;;; c-basic-offset:2
228// ;;; End:
229
const Offset getShortOffsetNotKnight(Offset32 offset32) const
Longの利きの可能性のあるoffsetの場合は, 反復に使う offsetを Knight以外のShortの利きのoffsetの場合はそれ自身を返す.
Definition boardTable.h:119
Direction getLongDirection(Offset32 offset32) const
Definition boardTable.h:71
Direction getShort8(Square from, Square to) const
Definition boardTable.h:147
圧縮していない moveの表現 .
Ptype ptype() const
Player player() const
bool isDrop() const
const Square to() const
利きを持つ局面
int countEffect(Player player, Square target) const
利きの数を数える.
差が uniqになるような座標の差分.
Definition offset32.h:17
座標の差分
Definition basic_type.h:430
bool zero() const
Definition basic_type.h:502
unsigned int index() const
Definition basic_type.h:572
bool isNeighboring8(Square to) const
const King8Info resetEdgeFromLiberty(Player king_player, Square king, King8Info info) const
liberty から盤の淵(xかyが1か9)を取り除く.
CArray2d< uint64_t, 2, Square::SIZE > edge_mask
敵玉の8近傍の状態を表す.
Definition king8Info.h:29
uint64_t uint64Value() const
Definition king8Info.h:46
unsigned int liberty() const
8-15 bit 目を 0-7bitにshiftして返す
Definition king8Info.h:54
証明数(proof number)と反証数(disproof number).
int libertyAfterAllDrop(const NumEffectState &state) const
drop のみ
const ProofDisproof attackEstimation(const NumEffectState &state) const
全て
CArray2d< uint8_t, 0x100u, 0x100u > pmajor_liberty
龍や馬で王手をかけられる時のliberty: [liberty][move_mask]
int disproofAfterAllCheck(const NumEffectState &, Player, King8Info) const
CArray2d< uint8_t, 0x10000u, 8 > drop_liberty
全ての有効drop -> 最小liberty.
CArray2d< uint8_t, 0x100u, 0x100u > promote_liberty
王が1,2段目にいる時の移動王手によるliberty: [liberty][move_mask].
const Liberty countLibertyLong(Player player, Square to, Ptype ptype, Square king, King8Info info) const
int libertyAfterAllMove(const NumEffectState &state) const
移動 のみ
int libertyAfterAllCheck(const NumEffectState &state) const
全て
CArray2d< CArray< Liberty, DIRECTION_SIZE >, 0x100u, PTYPE_SIZE > liberties
一つの王手 -> Liberty: long なdirection は1マスあけた王手を意味する
CArray2d< uint8_t, 0x100u, 0x100u > other_move_liberty
それ以外の移動liberty: [liberty][move_mask]
const Liberty countLiberty(Ptype ptype, Direction d, unsigned int liberty_mask) const
dir 方向からの王手をかけた時のlibertyの予想
int countLiberty(const NumEffectState &state, int liberty_count, Move move, Square king, King8Info info) const
move は王手である必要がある
const Liberty countLibertyShortNotKnight(Player player, Square to, Ptype ptype, Square king, King8Info info) const
8近傍へのdropまたは取れない移動後のlibertyの予測値を返す.
ProofNumberTable Proof_Number_Table
Ptype
駒の種類を4ビットでコード化する
Definition basic_type.h:84
@ KNIGHT
Definition basic_type.h:97
@ LANCE
Definition basic_type.h:96
const int PTYPE_SIZE
Definition basic_type.h:107
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
@ UUR
Definition basic_type.h:323
@ UUL
Definition basic_type.h:322
Player
Definition basic_type.h:8
@ WHITE
Definition basic_type.h:10
@ BLACK
Definition basic_type.h:9
const PtypeO PTYPEO_EDGE __attribute__((unused))
bool isMajor(Ptype ptype)
Definition basic_type.h:185
constexpr bool isLong(Direction d)
Definition basic_type.h:350
constexpr Player alt(Player player)
Definition basic_type.h:13
uint8_t liberty
玉の自由度の予測値.
bool has_effect
false の場合は必ず空き王手
static bool hasEffect(const NumEffectState &, Square target, Player attack)
target に attack の追加利きが一つでもあるか. 相手の影利きが先にある場合は対象としない.
static int countBit(Integer mask)
Definition mask.h:160