attackKing.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
attackKing.cc
Go to the documentation of this file.
1
4 #include "osl/eval/endgame/attackKing.h"
5 #include "osl/eval/pieceEval.h"
6 #include "osl/misc/carray.h"
7
8 // YSSの評価値を真似
9 // http://www32.ocn.ne.jp/~yss/book.html#SEC3
10 //
11 // 先手の玉に対する後手の駒の相対位置による増減割合。Ｘ軸については対称である。
12 // 0 1 2 3 4 5 6 7 8 (Ｘ距離)
13 //
14 // +8 50 50 50 50 50 50 50 50 50
15 // +7 50 50 50 50 50 50 50 50 50
16 // +6 62 60 58 52 50 50 50 50 50
17 // +5 80 78 72 67 55 51 50 50 50
18 // +4 100 99 95 87 78 69 50 50 50
19 // +3 140 130 110 100 95 75 54 50 50
20 // +2 170 160 142 114 98 80 62 55 50 <--- ２段真上を最大とする。
21 // +1 170 165 150 121 94 78 58 52 50
22 // 0 170 145 137 115 91 75 57 50 50 <--- 中心。左隅(0 0)に王がいるとする
23 // -1 132 132 129 102 84 71 51 50 50
24 // -2 100 97 95 85 70 62 50 50 50
25 // -3 90 85 80 68 60 53 50 50 50
26 // -4 70 66 62 55 52 50 50 50 50
27 // -5 54 53 51 50 50 50 50 50 50
28 // -6 50 50 50 50 50 50 50 50 50
29 // -7 50 50 50 50 50 50 50 50 50
30 // -8 50 50 50 50 50 50 50 50 50
31
32 namespace osl
33 {
34 namespace
35 {
36 const CArray<int,19*9> yss_bonus = {{
37 // 桂，香は一段下げるため，+9 から -9 まで取る
38 50, 50, 50, 50, 50, 50, 0, 0, 0,
39 50, 50, 50, 50, 50, 50, 0, 0, 0,
40 50, 50, 50, 50, 50, 50, 0, 0, 0,
41 62, 60, 58, 52, 50, 50, 0, 0, 0,
42 80, 78, 72, 67, 55, 51, 0, 0, 0,
43 100, 99, 95, 87, 78, 69, 0, 0, 0,
44 140, 130, 110, 100, 95, 75, 0, 0, 0,
45 170, 160, 142, 114, 98, 80, 0, 0, 0,
46 170, 165, 150, 121, 94, 78, 0, 0, 0,
47 170, 145, 137, 115, 91, 75, 0, 0, 0,
48 132, 132, 129, 102, 84, 71, 0, 0, 0,
49 100, 97, 95, 85, 70, 62, 0, 0, 0,
50 90, 85, 80, 68, 60, 53, 0, 0, 0,
51 70, 66, 62, 55, 52, 50, 0, 0, 0,
52 54, 53, 51, 50, 50, 50, 0, 0, 0,
53 50, 50, 50, 50, 50, 50, 0, 0, 0,
54 50, 50, 50, 50, 50, 50, 0, 0, 0,
55 50, 50, 50, 50, 50, 50, 0, 0, 0,
56 50, 50, 50, 50, 50, 50, 0, 0, 0,
57 }};
58 inline int toEven(int value)
59 {
60 if (value % 2 == 0)
61 return value;
62 if (value > 0)
63 return value - 1;
64 return value + 1;
65 }
66 inline int multiply(int value, int bonus)
67 {
68 // yss では持駒の付加価値が2割程度あるため1.2で割る
69 return toEven(value * bonus / 120);
70 }
71 inline void adhoc_adjust(int& value, double scale)
72 {
73 value = toEven(static_cast<int>(value * scale));
74 }
75 } // anonymous namespace
76 } // namespace osl
77
78 void osl::eval::endgame::AttackKing::
79 Table::adhoc_edge_king_1(const Player player,
80 const Square king,
81 const Square attack)
82 {
83 for (int ptype = PPAWN; ptype <= ROOK; ptype++)
84 {
85 if (ptype != KING)
86 {
87 adhoc_adjust(valueOf(king, player, attack,
88 static_cast<osl::Ptype>(ptype)), 1.25);
89 }
90 }
91 }
92
93 void osl::eval::endgame::AttackKing::
94 Table::adhoc_edge_king_2(const Player player,
95 const Square king,
96 const Square attack)
97 {
98 adhoc_adjust(valueOf(king, player, attack,
99 GOLD), 1.25);
100 adhoc_adjust(valueOf(king, player, attack,
101 SILVER), 1.25);
102 for (int ptype = PPAWN; ptype <= PSILVER; ptype++)
103 {
104 adhoc_adjust(valueOf(king, player, attack,
105 static_cast<osl::Ptype>(ptype)), 1.25);
106 }
107 }
108
109 osl::eval::endgame::AttackKing::
110 Table::Table()
111 {
112 // WHITEのKINGに対するBLACKの価値を書き，最後に反転させる．
113 data.fill(0);
114 for (int king_x=1; king_x<=9; ++king_x)
115 {
116 for (int king_y=1; king_y<=9; ++king_y)
117 {
118 const Square king(king_x, king_y);
119 for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p)
120 {
121 const Ptype ptype = static_cast<Ptype>(p);
122 assert(isPiece(ptype));
123 const Ptype basic_type = unpromote(ptype);
124
125 const int ptype_value
126 = Ptype_Eval_Table.value(newPtypeO(BLACK,ptype));
127 // 持駒
128 const int stand_bonus
129 = (isMajorBasic(basic_type)
130 ? Ptype_Eval_Table.value(newPtypeO(BLACK,PAWN))
131 : 0);
132 valueOf(king, WHITE, Square::STAND(), ptype) = +ptype_value
133 + stand_bonus;
134 if (ptype == KNIGHT || ptype == LANCE)
135 adhoc_adjust(valueOf(king, WHITE, Square::STAND(), ptype), 0.85);
136 if (ptype == GOLD || ptype == SILVER)
137 adhoc_adjust(valueOf(king, WHITE, Square::STAND(), ptype), 1.1);
138
139 // 盤上
140 for (int attack_x=1; attack_x<=9; ++attack_x)
141 {
142 const int relative_x = abs(king_x - attack_x);
143 for (int attack_y=1; attack_y<=9; ++attack_y)
144 {
145 const Square attacker(attack_x, attack_y);
146 if (basic_type == KING)
147 {
148 // 玉はそのまま
149 valueOf(king, WHITE, attacker, ptype) = ptype_value;
150 continue;
151 }
152
153 const int relative_y_white_king
154 = (((ptype == KNIGHT)||(ptype == LANCE))
155 ? attack_y - king_y - 1 // 桂香は一段遠くから評価
156 : attack_y - king_y);
157
158 const int bonus_white_king
159 = yss_bonus[relative_x + (-relative_y_white_king+9)*9];
160
161 const int black_attack = multiply(ptype_value,bonus_white_king);
162
163 if (isMajorBasic(basic_type))
164 {
165 // 大駒は攻撃に利いていれば max を取る
166 const int relative_y = abs(king_y - attack_y);
167 const int diff1 = king_x + king_y - (attack_x + attack_y);
168 const int diff2 = king_x - king_y - (attack_x - attack_y);
169
170 if ((basic_type == ROOK &&
171 relative_y <= 1) ||
172 (basic_type == BISHOP &&
173 ((-1 <= diff1 && diff1 <= 1) ||
174 (-1 <= diff2 && diff2 <= 1))))
175 {
176 valueOf(king, WHITE, attacker, ptype)
177 = EvalTraits<BLACK>::max(ptype_value, black_attack);
178 // 玉と同じ筋の方のボーナスを高くする
179 if (relative_y == 0)
180 {
181 adhoc_adjust(valueOf(king, WHITE, attacker, ptype),
182 0.98);
183 }
184 }
185 else
186 {
187 // その他は 90 に
188 valueOf(king, WHITE, attacker, ptype)
189 = multiply(ptype_value, 90);
190 }
191 continue;
192 }
193 //成れない歩と桂は減点
194 if ((ptype == PAWN && attack_y >= 5) ||
195 (ptype == KNIGHT && attack_y >= 6))
196 {
197 int new_black_attack = black_attack;
198 adhoc_adjust(new_black_attack, 0.95);
199 valueOf(king, WHITE, attacker, ptype) = new_black_attack;
200 }
201 else
202 valueOf(king, WHITE, attacker, ptype) = black_attack;
203 }
204 }
205 }
206 }
207 }
208 for (int king_x=1; king_x<=9; ++king_x)
209 {
210 for (int king_y=1; king_y<=9; ++king_y)
211 {
212 const Square king(king_x, king_y);
213 // 1つしか動けない香は歩と同じ点数に
214 for (int x=1; x<=9; ++x)
215 {
216 const Square b(x,2);
217 valueOf(king, WHITE, b, LANCE) = valueOf(king, WHITE, b, PAWN);
218 }
219 if (king_y <= 7)
220 {
221 adhoc_adjust(valueOf(king, WHITE, Square(king_x, king_y + 2), PAWN),
222 1.25);
223 }
224 // 1段目の金類は価値を半分に
225 for (int x=1; x<=9; ++x)
226 {
227 const Square b(x,1);
228 if (x <= 2 || x >= 8)
229 {
230 adhoc_adjust(valueOf(king, WHITE, b, GOLD), 0.25);
231 adhoc_adjust(valueOf(king, WHITE, b, PSILVER), 0.25);
232 }
233 else
234 {
235 adhoc_adjust(valueOf(king, WHITE, b, GOLD), 0.5);
236 adhoc_adjust(valueOf(king, WHITE, b, PSILVER), 0.5);
237 }
238 adhoc_adjust(valueOf(king, WHITE, b, PKNIGHT), 0.5);
239 adhoc_adjust(valueOf(king, WHITE, b, PLANCE), 0.5);
240 adhoc_adjust(valueOf(king, WHITE, b, PPAWN), 0.5);
241 }
242 // 1段玉に対する3段目の駒は価値を1.25倍に
243 if (king_y == 1)
244 {
245 for (int x = 1; x <= 9; ++x) {
246 const Square three(x, 3);
247 for (int ptype = PPAWN; ptype <= ROOK; ptype++)
248 {
249 if (ptype != KING && ptype != ROOK && ptype != PROOK)
250 adhoc_adjust(valueOf(king, WHITE, three,
251 static_cast<osl::Ptype>(ptype)), 1.25);
252 }
253 }
254 }
255 if (king_y <= 2)
256 {
257 for (int x = std::max(king_x - 1, 2);
258 x <= std::min(king_x + 1, 8); x++)
259 {
260 adhoc_adjust(valueOf(king, WHITE, Square(x, 4), PAWN),
261 1.25);
262 }
263 }
264 // 端玉に対するボーナス
265 if (king_x == 1 || king_x == 9)
266 {
267 int next = king_x == 1 ? 2 : 8;
268 adhoc_edge_king_1(WHITE, king, Square(next, king_y));
269 if (king_y < 9)
270 {
271 adhoc_edge_king_1(WHITE, king, Square(next, king_y + 1));
272 }
273 if (king_y < 8)
274 {
275 // 3段目は 1.25 * 1.25 倍されるけど気にしない
276 adhoc_edge_king_1(WHITE, king, Square(next, king_y + 2));
277 }
278 }
279 if (king_x < 6)
280 {
281 valueOf(king, WHITE, Square(9, 9), LANCE) = 0;
282 valueOf(king, WHITE, Square(9, 8), LANCE) = 0;
283 valueOf(king, WHITE, Square(9, 7), LANCE) = 0;
284 valueOf(king, WHITE, Square(8, 9), KNIGHT) = 0;
285
286 valueOf(king, WHITE, Square(9, 1), GOLD) = 0;
287 valueOf(king, WHITE, Square(9, 1), SILVER) = 0;
288 valueOf(king, WHITE, Square(9, 1), PSILVER) = 0;
289 valueOf(king, WHITE, Square(8, 1), GOLD) = 0;
290 valueOf(king, WHITE, Square(8, 1), SILVER) = 0;
291 valueOf(king, WHITE, Square(8, 1), PSILVER) = 0;
292 }
293
294 if (king_x > 4)
295 {
296 valueOf(king, WHITE, Square(1, 9), LANCE) = 0;
297 valueOf(king, WHITE, Square(1, 8), LANCE) = 0;
298 valueOf(king, WHITE, Square(1, 7), LANCE) = 0;
299 valueOf(king, WHITE, Square(2, 9), KNIGHT) = 0;
300
301 valueOf(king, WHITE, Square(1, 1), GOLD) = 0;
302 valueOf(king, WHITE, Square(1, 1), PSILVER) = 0;
303 valueOf(king, WHITE, Square(1, 1), SILVER) = 0;
304 valueOf(king, WHITE, Square(2, 1), GOLD) = 0;
305 valueOf(king, WHITE, Square(2, 1), SILVER) = 0;
306 valueOf(king, WHITE, Square(2, 1), PSILVER) = 0;
307 }
308 }
309 }
310 adhoc_edge_king_2(WHITE, Square(1, 1), Square(3, 2));
311 adhoc_edge_king_2(WHITE, Square(1, 2), Square(3, 3));
312 adhoc_edge_king_2(WHITE, Square(9, 1), Square(7, 2));
313 adhoc_edge_king_2(WHITE, Square(9, 2), Square(7, 3));
314
315 for (int x = 1; x <= 9; x++)
316 {
317 for (int y = 1; y <= 9; y++)
318 {
319 adhoc_adjust(valueOf(Square(1,1), WHITE, Square(x, y), GOLD), 1.05);
320 adhoc_adjust(valueOf(Square(9,1), WHITE, Square(x, y), GOLD), 1.05);
321 adhoc_adjust(valueOf(Square(1,1), WHITE, Square(x, y), SILVER), 1.05);
322 adhoc_adjust(valueOf(Square(9,1), WHITE, Square(x, y), SILVER), 1.05);
323 adhoc_adjust(valueOf(Square(1,1), WHITE, Square(x, y), BISHOP), 0.95);
324 adhoc_adjust(valueOf(Square(1,1), WHITE, Square(x, y), PBISHOP), 0.95);
325 adhoc_adjust(valueOf(Square(9,1), WHITE, Square(x, y), BISHOP), 0.95);
326 adhoc_adjust(valueOf(Square(9,1), WHITE, Square(x, y), PBISHOP), 0.95);
327 for (int ptype = PPAWN; ptype <= PSILVER; ptype++)
328 {
329 adhoc_adjust(valueOf(Square(1, 1), WHITE, Square(x,y),
330 static_cast<osl::Ptype>(ptype)), 1.05);
331 adhoc_adjust(valueOf(Square(9, 1), WHITE, Square(x,y),
332 static_cast<osl::Ptype>(ptype)), 1.05);
333 }
334 }
335 }
336 adhoc_adjust(valueOf(Square(1,1), WHITE, Square::STAND(), BISHOP), 0.95);
337 adhoc_adjust(valueOf(Square(9,1), WHITE, Square::STAND(), BISHOP), 0.95);
338
339 // BLACK/WHITE 反転
340 for (int king_x=1; king_x<=9; ++king_x) {
341 for (int king_y=1; king_y<=9; ++king_y) {
342 const Square king_b(king_x, king_y);
343 const Square king_w = king_b.rotate180();
344
345 for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p) {
346 const Ptype ptype = static_cast<Ptype>(p);
347 assert(isPiece(ptype));
348
349 // 持駒
350 valueOf(king_b, BLACK, Square::STAND(), ptype)
351 = - valueOf(king_w, WHITE, Square::STAND(), ptype);
352
353 // 盤上
354 for (int attack_x=1; attack_x<=9; ++attack_x) {
355 for (int attack_y=1; attack_y<=9; ++attack_y) {
356 const Square attack_b(attack_x, attack_y); // white へのblackの攻撃
357 const Square attack_w = attack_b.rotate180();
358
359 valueOf(king_b, BLACK, attack_w, ptype)
360 = - valueOf(king_w, WHITE, attack_b, ptype);
361 }
362 }
363 }
364 }
365 }
366 }
367
368 void osl::eval::endgame::AttackKing::
369 saveText(const char *filename)
370 {
371 table.saveText(filename);
372 }
373
374 // ;;; Local Variables:
375 // ;;; mode:c++
376 // ;;; c-basic-offset:2
377 // ;;; End: