All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
defenseKing.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 // 0 1 2 3 4 5 6 7 8 (X距離)
12 // +8 50 50 50 50 50 50 50 50 50
13 // +7 56 53 50 50 50 50 50 50 50
14 // +6 64 61 55 50 50 50 50 50 50
15 // +5 79 77 70 65 54 51 50 50 50
16 // +4 100 99 95 87 74 58 50 50 50
17 // +3 116 117 101 95 88 67 54 50 50
18 // +2 131 129 124 114 90 71 59 51 50
19 // +1 137 138 132 116 96 76 61 53 50
20 // 0 142 142 136 118 98 79 64 52 50 <--- 中心
21 // -1 132 132 129 109 95 75 60 51 50
22 // -2 121 120 105 97 84 66 54 50 50
23 // -3 95 93 89 75 68 58 51 50 50
24 // -4 79 76 69 60 53 50 50 50 50
25 // -5 64 61 55 51 50 50 50 50 50
26 // -6 56 52 50 50 50 50 50 50 50
27 // -7 50 50 50 50 50 50 50 50 50
28 // -8 50 50 50 50 50 50 50 50 50
29 
30 namespace osl
31 {
32  namespace
33  {
34  const CArray<int,19*9> yss_bonus = {{
35  // 桂,香は一段下げるため,+9 から -9 まで取る
36  50, 50, 50, 50, 50, 50, 0, 0, 0,
37  50, 50, 50, 50, 50, 50, 0, 0, 0,
38  56, 53, 50, 50, 50, 50, 0, 0, 0,
39  64, 61, 55, 50, 50, 50, 0, 0, 0,
40  79, 77, 70, 65, 54, 51, 0, 0, 0,
41  100, 99, 95, 87, 74, 58, 0, 0, 0,
42  116, 117, 101, 95, 88, 67, 0, 0, 0,
43  131, 129, 124, 114, 90, 71, 0, 0, 0,
44  137, 138, 132, 116, 96, 76, 0, 0, 0,
45  142, 142, 136, 118, 98, 79, 0, 0, 0,
46  132, 132, 129, 109, 95, 75, 0, 0, 0,
47  121, 120, 105, 97, 84, 66, 0, 0, 0,
48  95, 93, 89, 75, 68, 58, 0, 0, 0,
49  79, 76, 69, 60, 53, 50, 0, 0, 0,
50  64, 61, 55, 51, 50, 50, 0, 0, 0,
51  56, 52, 50, 50, 50, 50, 0, 0, 0,
52  50, 50, 50, 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  }};
57  const CArray<int,9> yss_king_bonus = {{
58  0, 0, 0, 150, 450, 900,1300,1550,1600
59  }};
60  inline int toEven(int value)
61  {
62  if (value % 2 == 0)
63  return value;
64  if (value > 0)
65  return value - 1;
66  return value + 1;
67  }
68  inline int multiply(int value, int bonus)
69  {
70  // http://www32.ocn.ne.jp/~yss/book.html#SEC3
71  // > 追記:2005年01月22日
72  // > 自玉の近くの点数は高すぎるので、現在は+を3分の1の値まで下げています
73  if (bonus > 100)
74  bonus = (bonus - 100)/3 + 100;
75  // yss では持駒の付加価値が2割程度あるため1.2で割る
76  return toEven(value * bonus / 120);
77  }
78  inline void adhoc_adjust(int& value, double scale)
79  {
80  value = toEven(static_cast<int>(value * scale));
81  }
82  } // anonymous namespace
83 } // namespace osl
84 
85 
86 
89 {
90  // BLACKのKINGに対するBLACKの価値を書き,WHITEの駒の価値は最後に反転させる.
91  data.fill(0);
92  for (int king_x=1; king_x<=9; ++king_x)
93  {
94  for (int king_y=1; king_y<=9; ++king_y)
95  {
96  const Square king(king_x, king_y);
97  for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p)
98  {
99  const Ptype ptype = static_cast<Ptype>(p);
100  assert(isPiece(ptype));
101  const Ptype basic_type = unpromote(ptype);
102 
103  const int ptype_value
105  // 持駒
106  const int stand_bonus
107  = (isMajorBasic(basic_type)
109  : 0);
110  valueOf(king, BLACK, Square::STAND(), ptype) = ptype_value
111  + stand_bonus;
112  if (ptype == KNIGHT || ptype == LANCE)
113  {
114  adhoc_adjust(valueOf(king, BLACK, Square::STAND(), ptype), 0.85);
115  }
116  // 盤上
117  if (basic_type == KING)
118  {
119  // 玉は入玉を考慮
120  valueOf(king, BLACK, king, ptype)
121  = ptype_value + yss_king_bonus[9-king_y];
122  continue;
123  }
124 
125  for (int defense_x=1; defense_x<=9; ++defense_x)
126  {
127  const bool near_edge
128  = (((defense_x < 3) && (defense_x < king_x))
129  || ((defense_x > 7) && (defense_x > king_x)));
130  const int relative_x = abs(king_x - defense_x);
131  for (int defense_y=1; defense_y<=9; ++defense_y)
132  {
133  const Square defender(defense_x, defense_y);
134  // 馬以外の大駒は0.9
135  if (isMajorBasic(basic_type) && ptype != PBISHOP)
136  {
137  int black_bonus;
138  // 入玉後の大駒は大事
139  if (king_y < 4)
140  black_bonus = 105;
141  else if (king_y == 4)
142  black_bonus = 100;
143  // 1段目と2段目の玉に対する2段目の飛車は 0.95 あげる
144  else if (basic_type == ROOK && defense_y == 8 && king_y >= 8)
145  black_bonus = 95;
146  else
147  black_bonus = 90;
148 
149  valueOf(king, BLACK, defender, ptype) =
150  multiply(ptype_value, black_bonus);
151  continue;
152  }
153  int relative_y_black_king = king_y - defense_y;
154  if (ptype == KNIGHT || ptype == LANCE)
155  {
156  // 桂香は一段遠くから評価
157  relative_y_black_king++;
158  }
159  else if (ptype == PAWN)
160  {
161  // 歩は玉の真上の段とその上の段のボーナスを交換する
162  if (relative_y_black_king == 1)
163  {
164  relative_y_black_king = 2;
165  }
166  else if (relative_y_black_king == 2)
167  {
168  relative_y_black_king = 1;
169  }
170  }
171 
172  int bonus_black_king
173  = yss_bonus[relative_x + (-relative_y_black_king+9)*9];
174  // 端の方にはボーナスをあげない (自玉の近くの端歩以外
175  if (near_edge || ptype == LANCE)
176  {
177  if (!(ptype == PAWN &&
178  (defense_x == 1 || defense_x == 9) &&
179  defense_y < king_y))
180  bonus_black_king = std::min(100, bonus_black_king);
181  }
182  if (ptype == KNIGHT)
183  {
184  if ((defense_x == 2 || defense_x == 8) &&
185  (defense_y == 1 || defense_y == 9))
186  {
187  }
188  else
189  {
190  bonus_black_king = std::min(100, bonus_black_king);
191  }
192  }
193 
194  int black_defense = multiply(ptype_value,bonus_black_king);
195  const bool near_center
196  = abs(defense_x-king_x)==1 &&
197  (((king_x < 3) && (defense_x > king_x))
198  || ((king_x > 7) && (defense_x < king_x)));
199  if(defense_x==king_x || near_center){
200  if(defense_y==king_y-1){
201  if(king_y==9 && (king_x==1 || king_x==9))
202  black_defense+=600;
203  else if(defense_x!=king_x && king_y==8 && (king_x==2 || king_x==8))
204  black_defense+=200;
205  else
206  black_defense+=400;
207  }
208  }
209  valueOf(king, BLACK, defender, ptype) = black_defense;
210  }
211  }
212  }
213  }
214  }
215  // 1つしか動けない香は歩と同じ点数に
216  for (int king_x=1; king_x<=9; ++king_x)
217  {
218  for (int king_y=1; king_y<=9; ++king_y)
219  {
220  const Square king(king_x, king_y);
221  for (int x=1; x<=9; ++x)
222  {
223  const Square b(x,2);
224  valueOf(king, BLACK, b, LANCE) = valueOf(king, BLACK, b, PAWN);
225  adhoc_adjust(valueOf(king, BLACK, Square(x, 1), GOLD), 0.5);
226  adhoc_adjust(valueOf(king, BLACK, Square(x, 1), SILVER), 0.5);
227  adhoc_adjust(valueOf(king, BLACK, Square(x, 1), PSILVER), 0.5);
228  }
229 
230  if (king_x < 6)
231  {
232  valueOf(king, BLACK, Square(9, 9), LANCE) = 0;
233  valueOf(king, BLACK, Square(9, 8), LANCE) = 0;
234  valueOf(king, BLACK, Square(9, 7), LANCE) = 0;
235  valueOf(king, BLACK, Square(8, 9), KNIGHT) = 0;
236 
237  valueOf(king, BLACK, Square(9, 1), GOLD) = 0;
238  valueOf(king, BLACK, Square(9, 1), SILVER) = 0;
239  valueOf(king, BLACK, Square(9, 1), PSILVER) = 0;
240  valueOf(king, BLACK, Square(8, 1), GOLD) = 0;
241  valueOf(king, BLACK, Square(8, 1), SILVER) = 0;
242  valueOf(king, BLACK, Square(8, 1), PSILVER) = 0;
243  }
244 
245  if (king_x > 4)
246  {
247  valueOf(king, BLACK, Square(1, 9), LANCE) = 0;
248  valueOf(king, BLACK, Square(1, 8), LANCE) = 0;
249  valueOf(king, BLACK, Square(1, 7), LANCE) = 0;
250  valueOf(king, BLACK, Square(2, 9), KNIGHT) = 0;
251 
252  valueOf(king, BLACK, Square(1, 1), GOLD) = 0;
253  valueOf(king, BLACK, Square(1, 1), PSILVER) = 0;
254  valueOf(king, BLACK, Square(1, 1), SILVER) = 0;
255  valueOf(king, BLACK, Square(2, 1), GOLD) = 0;
256  valueOf(king, BLACK, Square(2, 1), SILVER) = 0;
257  valueOf(king, BLACK, Square(2, 1), PSILVER) = 0;
258  }
259  }
260  }
261 
262  adhoc_adjust(valueOf(Square(1,1), BLACK, Square::STAND(), BISHOP), 0.95);
263  adhoc_adjust(valueOf(Square(9,1), BLACK, Square::STAND(), BISHOP), 0.95);
264 
265  // BLACK/WHITE 反転
266  for (int king_x=1; king_x<=9; ++king_x) {
267  for (int king_y=1; king_y<=9; ++king_y) {
268  const Square king_b(king_x, king_y);
269  const Square king_w = king_b.rotate180();
270 
271  for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p) {
272  const Ptype ptype = static_cast<Ptype>(p);
273  assert(isPiece(ptype));
274 
275  // 持駒
276  valueOf(king_w, WHITE, Square::STAND(), ptype)
277  = - valueOf(king_b, BLACK, Square::STAND(), ptype);
278 
279  // 盤上
280  for (int defense_x=1; defense_x<=9; ++defense_x) {
281  for (int defense_y=1; defense_y<=9; ++defense_y) {
282  const Square defense_b(defense_x, defense_y); // blackへのblackの防御
283  const Square defense_w = defense_b.rotate180();
284 
285  valueOf(king_w, WHITE, defense_w, ptype)
286  = - valueOf(king_b, BLACK, defense_b, ptype);
287  }
288  }
289  }
290  }
291  }
292 }
293 // ;;; Local Variables:
294 // ;;; mode:c++
295 // ;;; c-basic-offset:2
296 // ;;; End: