All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
attackKing.cc
Go to the documentation of this file.
1 
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 // 先手の玉に対する後手の駒の相対位置による増減割合。X軸については対称である。
12 // 0 1 2 3 4 5 6 7 8 (X距離)
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 <--- 2段真上を最大とする。
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 
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 
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 
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
127  // 持駒
128  const int stand_bonus
129  = (isMajorBasic(basic_type)
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 
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: