All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pairedit.cc
Go to the documentation of this file.
1 /* pairedit.cc
2  */
3 
5 #include <boost/scoped_ptr.hpp>
6 #include <iostream>
7 #include <cstdlib>
8 #include <cstdio>
9 #include <unistd.h>
10 
24 using namespace osl;
25 using namespace osl::eval;
26 
27 void usage(const char *prog)
28 {
29  using namespace std;
30  cerr << "Usage: " << prog << " [-f read-pair-file-name] [-o write-pair-file-name] "
31  << endl;
32  exit(1);
33 }
34 
35 bool verbose = false;
36 
37 void adjust(PiecePairRawTable& table,
38  Square pos1, PtypeO ptypeo1,
39  Square pos2, PtypeO ptypeo2,
40  int value)
41 {
42  assert(pos1.isOnBoard());
43  assert(pos2.isOnBoard());
44  const unsigned int index1 = table.indexOf(pos1, ptypeo1);
45  const unsigned int index2 = table.indexOf(pos2, ptypeo2);
46 
47  int val = table.valueOf(index1, index2);
48  assert(val == table.valueOf(index2, index1));
49  if (verbose)
50  std::cerr << pos1 << ptypeo1 << " " << pos2 << ptypeo2
51  << " " << val << " => ";
52  val += value;
53  val = std::min(127, val);
54  val = std::max(-127, val);
55  if (verbose)
56  std::cerr << val << "\n";
57  table.valueOf(index1, index2) = val;
58  table.valueOf(index2, index1) = val;
59 }
60 
61 void adjustKingBonus(PiecePairRawTable& table,
62  Square pos1, PtypeO ptypeo1, // king
63  Square pos2, PtypeO ptypeo2, // attacker
64  int bonus)
65 {
66  assert(getPtype(ptypeo1) == KING);
67  assert(getPtype(ptypeo2) != KING);
68  assert(getOwner(ptypeo1) != getOwner(ptypeo2));
69  assert((bonus > 0) ^ (getOwner(ptypeo1) == BLACK));
70 
71  adjust(table, pos1, ptypeo1, pos2, ptypeo2, bonus);
72 }
73 
75 void adjustDual(PiecePairRawTable& table,
76  Square king, Square attacker, Ptype attackerType,
77  int blackAttackBonus, int whiteAttackBonus)
78 {
79  adjustKingBonus(table, king.rotate180(), newPtypeO(BLACK, KING),
80  attacker.rotate180(), newPtypeO(WHITE, attackerType),
81  whiteAttackBonus);
82  adjustKingBonus(table, king, newPtypeO(WHITE, KING),
83  attacker, newPtypeO(BLACK, attackerType),
84  blackAttackBonus);
85 }
86 
87 void adjustDual(PiecePairRawTable& table,
88  Square black, Ptype black_ptype,
89  Square white, Ptype white_ptype,
90  int value)
91 {
92  adjust(table, black, newPtypeO(BLACK, black_ptype),
93  white, newPtypeO(WHITE, white_ptype), value);
94  adjust(table, black.rotate180(), newPtypeO(WHITE, black_ptype),
95  white.rotate180(), newPtypeO(BLACK, white_ptype), -value);
96 }
97 
98 void addValue(Player player, PiecePairRawTable& table,
99  Square pos1, Ptype ptype1,
100  Square pos2, Ptype ptype2,
101  int bonus)
102 {
103  const PtypeO ptypeo1 = newPtypeO(player, ptype1);
104  const PtypeO ptypeo2 = newPtypeO(player, ptype2);
105  adjust(table, pos1, ptypeo1, pos2, ptypeo2, bonus);
106 }
107 
108 void addPenalty(Player player, PiecePairRawTable& table,
109  Square pos1, Ptype ptype1,
110  Square pos2, Ptype ptype2,
111  int bonus)
112 {
113  assert(eval::betterThan(player, 0, bonus));
114  addValue(player, table, pos1, ptype1, pos2, ptype2, bonus);
115 }
116 
117 void addBonus(Player player, PiecePairRawTable& table,
118  Square pos1, Ptype ptype1,
119  Square pos2, Ptype ptype2,
120  int bonus)
121 {
122  assert(eval::betterThan(player, bonus, 0));
123  addValue(player, table, pos1, ptype1, pos2, ptype2, bonus);
124 }
125 
126 void addPenaltyDual(PiecePairRawTable& table,
127  Square pos1, Ptype ptype1,
128  Square pos2, Ptype ptype2,
129  int black_bonus)
130 {
131  assert(black_bonus < 0);
132  addPenalty(BLACK, table, pos1, ptype1, pos2, ptype2, black_bonus);
133  addPenalty(WHITE, table, pos1, ptype1, pos2, ptype2, -black_bonus);
134 }
135 
136 void addSelfPenaltyDual(PiecePairRawTable& table,
137  Square pos, Ptype ptype,
138  int black_bonus)
139 {
140  addPenaltyDual(table, pos, ptype, pos, ptype, black_bonus);
141 }
142 
143 
144 int main(int argc, char **argv)
145 {
146  const char *program_name = argv[0];
147  bool error_flag = false;
148  const char *read_pairfilename = 0;
149  const char *write_pairfilename = 0;
150 
151  extern char *optarg;
152  extern int optind;
153  char c;
154  while ((c = getopt(argc, argv, "f:o:vh")) != EOF)
155  {
156  switch(c)
157  {
158  case 'f': read_pairfilename = optarg;
159  break;
160  case 'o': write_pairfilename = optarg;
161  break;
162  case 'v': verbose = true;
163  break;
164  default: error_flag = true;
165  }
166  }
167  argc -= optind;
168  argv += optind;
169 
170  if (error_flag || (! read_pairfilename) || (! write_pairfilename))
171  usage(program_name);
172 
173  boost::scoped_ptr<PiecePairRawTable> table(new PiecePairRawTable);
174  table->loadFromBinaryFile(read_pairfilename);
175 
176  // 通常の5x5の範囲
177  CArray2d<bool,Square::SIZE,Square::SIZE> adjusted;
178  adjusted.fill(false);
179  for (int king_x=1; king_x<=9; ++king_x)
180  {
181  for (int king_y=1; king_y<=9; ++king_y)
182  {
183  const Square king(king_x,king_y);
184  for (int attacker_x = ((king_x==9) ? king_x-3 : king_x-2);
185  attacker_x <= ((king_x==1) ? king_x+3 : king_x+2); ++attacker_x)
186  {
187  if ((attacker_x < 1) || (attacker_x > 9))
188  continue;
189  for (int attacker_y = ((king_y==9) ? king_y-3 : king_y-2);
190  attacker_y <= ((king_y==1) ? king_y+3 : king_y+2); ++attacker_y)
191  {
192  if ((attacker_y < 1) || (attacker_y > 9))
193  continue;
194  const Square attacker(attacker_x,attacker_y);
195  if (king == attacker)
196  continue;
197  adjusted[king.index()][attacker.index()] = true;
198  adjustDual(*table, king, attacker, PPAWN, 100, -100);
199  adjustDual(*table, king, attacker, PLANCE, 100, -100);
200  adjustDual(*table, king, attacker, PKNIGHT, 100, -100);
201  adjustDual(*table, king, attacker, PBISHOP, 100, -100);
202  adjustDual(*table, king, attacker, PROOK, 100, -100);
203  adjustDual(*table, king, attacker, SILVER, 100, -100);
204  adjustDual(*table, king, attacker, BISHOP, 100, -100);
205  adjustDual(*table, king, attacker, ROOK, 100, -100);
206 
207  // 金と成銀は1段目以外
208  if (attacker_y != 1)
209  {
210  const int bonus =
211  (attacker_y >= king_y) ? 100 : 50;
212  adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
213  attacker, newPtypeO(BLACK, PSILVER),
214  bonus);
215  adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
216  attacker, newPtypeO(BLACK, GOLD),
217  bonus);
218  }
219  if (attacker_y != 9)
220  {
221  const int bonus =
222  (attacker_y <= king_y) ? -100 : -50;
223  adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
224  attacker, newPtypeO(WHITE, PSILVER),
225  bonus);
226  adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
227  attacker, newPtypeO(WHITE, GOLD),
228  bonus);
229  }
230  // 歩は王と同列かより手前
231  if (attacker_y >= king_y)
232  {
233  adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
234  attacker, newPtypeO(BLACK, PAWN),
235  100);
236  }
237  if (attacker_y <= king_y)
238  {
239  adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
240  attacker, newPtypeO(WHITE, PAWN),
241  -100);
242  }
243  } // attacker_y
244  // 桂香は長目にとる
245  for (int attacker_y = ((king_y==9) ? king_y-4 : king_y-3);
246  attacker_y <= ((king_y==1) ? king_y+4 : king_y+3); ++attacker_y)
247  {
248  if ((attacker_y < 1) || (attacker_y > 9))
249  continue;
250  const Square attacker(attacker_x,attacker_y);
251  if (king == attacker)
252  continue;
253 
254  // 王より手前, 25,45,65,85 は弊害が大きいので除く
255  if (! ((attacker_y == 5)
256  && ((attacker_x == 2)
257  || (attacker_x == 4)
258  || (attacker_x == 6)
259  || (attacker_x == 8))))
260  {
261  if ((attacker_y > king_y) && (attacker_y > 2))
262  {
263  adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
264  attacker, newPtypeO(BLACK, LANCE),
265  100);
266  adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
267  attacker, newPtypeO(BLACK, KNIGHT),
268  100);
269  }
270  if ((attacker_y < king_y) && (attacker_y < 8))
271  {
272  adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
273  attacker, newPtypeO(WHITE, LANCE),
274  -100);
275  adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
276  attacker, newPtypeO(WHITE, KNIGHT),
277  -100);
278  }
279  }
280  } // attacker_y, knight, lance
281  } // attacker_x
282  } // king_y
283  } // king_x
284  // 5x5の範囲外の補正 x+1
285  for (int king_x=1; king_x<=9; ++king_x)
286  {
287  for (int king_y=1; king_y<=3; ++king_y)
288  {
289  const Square king(king_x,king_y);
290  for (int rook_x=1; rook_x<=9; ++rook_x)
291  {
292  for (int rook_y=king_y-1; rook_y<=king_y+1; ++rook_y)
293  {
294  if ((rook_y < 1) || (rook_y > 9))
295  continue;
296  const Square rook(rook_x, rook_y);
297  if (king == rook)
298  continue;
299  if (! adjusted[king.index()][rook.index()])
300  {
301  adjustDual(*table, king, rook, ROOK, 30, -30);
302  adjustDual(*table, king, rook, PROOK, 30, -30);
303  }
304  }
305  }
306  for (int attacker_x = ((king_x==9) ? king_x-4 : king_x-3);
307  attacker_x <= ((king_x==1) ? king_x+4 : king_x+3); ++attacker_x)
308  {
309  if ((attacker_x < 1) || (attacker_x > 9))
310  continue;
311  for (int attacker_y = king_y; attacker_y <= ((king_y==1) ? king_y+3 : king_y+2); ++attacker_y)
312  {
313  if ((attacker_y < 1) || (attacker_y > 9))
314  continue;
315  const Square attacker(attacker_x,attacker_y);
316  if (king == attacker)
317  continue;
318  if (adjusted[king.index()][attacker.index()])
319  continue;
320  adjusted[king.index()][attacker.index()] = true;
321  adjustDual(*table, king, attacker, PPAWN, 40, -40);
322  adjustDual(*table, king, attacker, PLANCE, 40, -40);
323  adjustDual(*table, king, attacker, PKNIGHT, 40, -40);
324  adjustDual(*table, king, attacker, SILVER, 40, -40);
325  }
326  }
327  }
328  }
329  // x+2
330  for (int king_x=1; king_x<=9; ++king_x)
331  {
332  for (int king_y=1; king_y<=3; ++king_y)
333  {
334  const Square king(king_x,king_y);
335  for (int attacker_x = ((king_x==9) ? king_x-5 : king_x-4);
336  attacker_x <= ((king_x==1) ? king_x+5 : king_x+4); ++attacker_x)
337  {
338  if ((attacker_x < 1) || (attacker_x > 9))
339  continue;
340  for (int attacker_y = king_y+1; attacker_y <= ((king_y==1) ? king_y+3 : king_y+2); ++attacker_y)
341  {
342  if ((attacker_y < 1) || (attacker_y > 9))
343  continue;
344  const Square attacker(attacker_x,attacker_y);
345  if (king == attacker)
346  continue;
347  if (adjusted[king.index()][attacker.index()])
348  continue;
349  adjustDual(*table, king, attacker, PPAWN, 10, -10);
350  adjustDual(*table, king, attacker, PLANCE, 10, -10);
351  adjustDual(*table, king, attacker, PKNIGHT, 10, -10);
352  adjustDual(*table, king, attacker, SILVER, 10, -10);
353  }
354  }
355  }
356  }
357  for (int attacker_x=1; attacker_x<=9; ++attacker_x)
358  {
359  for (int attacker_y=1; attacker_y<=9; ++attacker_y)
360  {
361  const Square attacker(attacker_x,attacker_y);
362  // 端の駒は色々減点
363  if ((attacker_x == 1) || (attacker_x == 9))
364  {
365  addSelfPenaltyDual(*table, attacker, KNIGHT, -100);
366  addSelfPenaltyDual(*table, attacker, SILVER, -100);
367  addSelfPenaltyDual(*table, attacker, GOLD , -100);
368  addSelfPenaltyDual(*table, attacker, PPAWN , -100);
369  addSelfPenaltyDual(*table, attacker, PLANCE, -100);
370  addSelfPenaltyDual(*table, attacker, PKNIGHT, -100);
371  addSelfPenaltyDual(*table, attacker, PSILVER, -100);
372  }
373  }
374  }
375  // 捌きにくい銀
376  addPenalty(BLACK, *table, Square(2,6), SILVER, Square(3,7), KNIGHT, -80);
377  addPenalty(WHITE, *table, Square(8,4), SILVER, Square(7,3), KNIGHT, +80);
378 
379  addPenalty(BLACK, *table, Square(2,6), SILVER, Square(1,5), PAWN, -80);
380  addPenalty(WHITE, *table, Square(8,4), SILVER, Square(9,5), PAWN, +80);
381 
382  addPenalty(BLACK, *table, Square(9,7), SILVER, Square(8,8), BISHOP, -80);
383  addPenalty(BLACK, *table, Square(1,7), SILVER, Square(2,8), BISHOP, -80);
384  addPenalty(WHITE, *table, Square(9,3), SILVER, Square(8,2), BISHOP, +80);
385  addPenalty(WHITE, *table, Square(1,3), SILVER, Square(2,2), BISHOP, +80);
386 
387  // 穴熊関係
388  addPenalty(BLACK, *table, Square(9,9), KING, Square(7,7), KNIGHT, -120);
389  addPenalty(BLACK, *table, Square(9,9), KING, Square(9,7), KNIGHT, -120);
390  addPenalty(BLACK, *table, Square(1,9), KING, Square(3,7), KNIGHT, -120);
391  addPenalty(BLACK, *table, Square(1,9), KING, Square(1,7), KNIGHT, -120);
392  addPenalty(WHITE, *table, Square(9,1), KING, Square(7,3), KNIGHT, +120);
393  addPenalty(WHITE, *table, Square(9,1), KING, Square(9,3), KNIGHT, +120);
394  addPenalty(WHITE, *table, Square(1,1), KING, Square(3,3), KNIGHT, +120);
395  addPenalty(WHITE, *table, Square(1,1), KING, Square(1,3), KNIGHT, +120);
396 
397  // 玉の点数を引いておき,桂香があれば復活させる
398  addPenalty(BLACK, *table, Square(9,9), KING, Square(9,9), KING, -120);
399  addBonus(BLACK, *table, Square(9,9), KING, Square(9,8), LANCE, 40);
400  addBonus(BLACK, *table, Square(9,9), KING, Square(8,9), KNIGHT, 80);
401 
402  addPenalty(BLACK, *table, Square(1,9), KING, Square(1,9), KING, -120);
403  addBonus(BLACK, *table, Square(1,9), KING, Square(1,8), LANCE, 40);
404  addBonus(BLACK, *table, Square(1,9), KING, Square(2,9), KNIGHT, 80);
405 
406  addPenalty(WHITE, *table, Square(9,1), KING, Square(9,1), KING, +120);
407  addBonus(WHITE, *table, Square(9,1), KING, Square(9,2), LANCE, -40);
408  addBonus(WHITE, *table, Square(9,1), KING, Square(8,1), KNIGHT, -80);
409 
410  addPenalty(WHITE, *table, Square(1,1), KING, Square(1,1), KING, +120);
411  addBonus(WHITE, *table, Square(1,1), KING, Square(1,2), LANCE, -40);
412  addBonus(WHITE, *table, Square(1,1), KING, Square(2,1), KNIGHT, -80);
413 
414  // 5段目の桂馬 (取られそう)
415  for (int x=2; x<=8; ++x) // 1,9はペナルティ済
416  {
417  //
418  const Square attacker(x,5);
419  addSelfPenaltyDual(*table, attacker, KNIGHT, -100);
420 
421  // 相手の歩が遠ければ大丈夫かも.
422  adjust(*table, Square(x,1), newPtypeO(WHITE,PAWN), attacker, newPtypeO(BLACK,KNIGHT), 100);
423  adjust(*table, Square(x,2), newPtypeO(WHITE,PAWN), attacker, newPtypeO(BLACK,KNIGHT), 100);
424  adjust(*table, Square(x,9), newPtypeO(BLACK,PAWN), attacker, newPtypeO(WHITE,KNIGHT), -100);
425  adjust(*table, Square(x,8), newPtypeO(BLACK,PAWN), attacker, newPtypeO(WHITE,KNIGHT), -100);
426  }
427 
428  // 敵の大駒の成駒と自陣の生の駒
429  for (int promoted_x=1; promoted_x<=9; ++promoted_x)
430  {
431  for (int x=1; x<=9; ++x)
432  {
433  for (int promoted_y=1; promoted_y<=3; ++promoted_y)
434  {
435  const Square promoted(promoted_x, promoted_y);
436  for (int y=1; y<=3; ++y)
437  {
438  const Square unpromoted(x, y);
439  if (promoted == unpromoted)
440  continue;
441  adjust(*table, promoted, newPtypeO(BLACK,PROOK),
442  unpromoted, newPtypeO(WHITE,ROOK), 100);
443  adjust(*table, promoted, newPtypeO(BLACK,PROOK),
444  unpromoted, newPtypeO(WHITE,BISHOP), 100);
445  adjust(*table, promoted, newPtypeO(BLACK,PBISHOP),
446  unpromoted, newPtypeO(WHITE,ROOK), 100);
447  adjust(*table, promoted, newPtypeO(BLACK,PBISHOP),
448  unpromoted, newPtypeO(WHITE,BISHOP), 100);
449  }
450  }
451  for (int promoted_y=7; promoted_y<=9; ++promoted_y)
452  {
453  const Square promoted(promoted_x, promoted_y);
454  for (int y=7; y<=9; ++y)
455  {
456  const Square unpromoted(x, y);
457  if (promoted == unpromoted)
458  continue;
459  adjust(*table, promoted, newPtypeO(WHITE,PROOK),
460  unpromoted, newPtypeO(BLACK,ROOK), -100);
461  adjust(*table, promoted, newPtypeO(WHITE,PROOK),
462  unpromoted, newPtypeO(BLACK,BISHOP), -100);
463  adjust(*table, promoted, newPtypeO(WHITE,PBISHOP),
464  unpromoted, newPtypeO(BLACK,ROOK), -100);
465  adjust(*table, promoted, newPtypeO(WHITE,PBISHOP),
466  unpromoted, newPtypeO(BLACK,BISHOP), -100);
467  }
468  }
469  } // x
470  }
471  // 4,6段目の歩に抑え込みボーナス
472  for (int x=1; x<=9; ++x)
473  {
474  //
475  const Square black_position(x,4);
476  const Square white_position(x,6);
477  addBonus(BLACK, *table, black_position, PAWN, black_position, PAWN, 100);
478  addBonus(WHITE, *table, white_position, PAWN, white_position, PAWN,-100);
479  }
480 
481  for (int x=1; x<=9; ++x)
482  {
483  // 危ない飛車
484  addPenalty(BLACK, *table, Square(x,6), ROOK, Square(x,7), PAWN, -95);
485  addPenalty(WHITE, *table, Square(x,4), ROOK, Square(x,3), PAWN, +95);
486  // 捌きにくい銀
487  if (x == 1 || x == 3 || x == 7 || x == 9)
488  {
489  addPenalty(BLACK, *table, Square(x,6), SILVER, Square(x,7), PAWN, -80);
490  addPenalty(WHITE, *table, Square(x,4), SILVER, Square(x,3), PAWN, +80);
491  }
492  // 捻り飛車失敗?
493  for (int i=x-1; i<=x+1; ++i)
494  {
495  if (i<1 || i > 9)
496  continue;
497  addPenalty(BLACK, *table, Square(x,6), ROOK, Square(i,8), KING, -100);
498  addPenalty(BLACK, *table, Square(x,6), ROOK, Square(i,9), KING, -90);
499  addPenalty(WHITE, *table, Square(x,4), ROOK, Square(i,2), KING, +100);
500  addPenalty(WHITE, *table, Square(x,4), ROOK, Square(i,1), KING, +90);
501  }
502  // 玉飛接近
503  for (int y=7; y<=9; ++y)
504  {
505  const int wy = 10-y;
506  addPenalty(BLACK, *table, Square(x,y), KING, Square(x,y-1), ROOK, -70);
507  addPenalty(BLACK, *table, Square(x,y-1), KING, Square(x,y), ROOK, -70);
508  addPenalty(WHITE, *table, Square(x,wy), KING, Square(x,wy+1), ROOK, +70);
509  addPenalty(WHITE, *table, Square(x,wy+1), KING, Square(x,wy), ROOK, +70);
510  if (x > 1)
511  {
512  addPenalty(BLACK, *table, Square(x,y), KING, Square(x-1,y), ROOK, -70);
513  addPenalty(WHITE, *table, Square(x,wy), KING, Square(x-1,wy), ROOK, +70);
514  }
515  if (x > 2)
516  {
517  addPenalty(BLACK, *table, Square(x,y), KING, Square(x-2,y), ROOK, -50);
518  addPenalty(WHITE, *table, Square(x,wy), KING, Square(x-2,wy), ROOK, +50);
519  }
520  if (x < 9)
521  {
522  addPenalty(BLACK, *table, Square(x,y), KING, Square(x+1,y), ROOK, -70);
523  addPenalty(WHITE, *table, Square(x,wy), KING, Square(x+1,wy), ROOK, +70);
524  }
525  if (x < 8)
526  {
527  addPenalty(BLACK, *table, Square(x,y), KING, Square(x+2,y), ROOK, -50);
528  addPenalty(WHITE, *table, Square(x,wy), KING, Square(x+2,wy), ROOK, +50);
529  }
530  } // for y
531  } // for x
532 
533  // 桂馬と飛車
534  addPenalty(BLACK, *table, Square(1,7), ROOK, Square(2,9), KNIGHT, -70);
535  addPenalty(BLACK, *table, Square(3,7), ROOK, Square(2,9), KNIGHT, -70);
536  addPenalty(BLACK, *table, Square(7,7), ROOK, Square(8,9), KNIGHT, -70);
537  addPenalty(BLACK, *table, Square(9,7), ROOK, Square(8,9), KNIGHT, -70);
538  addPenalty(WHITE, *table, Square(1,3), ROOK, Square(2,1), KNIGHT, +70);
539  addPenalty(WHITE, *table, Square(3,3), ROOK, Square(2,1), KNIGHT, +70);
540  addPenalty(WHITE, *table, Square(7,3), ROOK, Square(8,1), KNIGHT, +70);
541  addPenalty(WHITE, *table, Square(9,3), ROOK, Square(8,1), KNIGHT, +70);
542  // 角道を防ぐ金
543  for (int x=1; x<=9; ++x)
544  {
545  for (int y=8; y<=9; ++y)
546  {
547  const Square bishop(x, y);
548  if (x < 9)
549  {
550  const Square ul(x+1, y-1);
551  addPenalty(BLACK, *table, bishop, BISHOP, ul, GOLD, -65);
552  addPenalty(WHITE, *table, bishop.rotate180(), BISHOP,
553  ul.rotate180(), GOLD, 65);
554  }
555  if (x > 1)
556  {
557  const Square ur(x-1, y-1);
558  addPenalty(BLACK, *table, bishop, BISHOP, ur, GOLD, -65);
559  addPenalty(WHITE, *table, bishop.rotate180(), BISHOP,
560  ur.rotate180(), GOLD, 65);
561  }
562  }
563  }
564 
565  // 隣接する成駒
566  const CArray<Ptype, 6> types =
567  {{ LANCE, KNIGHT, PPAWN, PLANCE, PKNIGHT, PSILVER }};
568  for (int x1=1; x1<=9; ++x1)
569  {
570  for (int x2=x1; x2<=9; ++x2)
571  {
572  const int xdiff = abs(x1 - x2);
573  if (xdiff > 2)
574  continue;
575  for (int y1=1; y1<=3; ++y1)
576  {
577  const Square p1(x1,y1);
578  for (int y2=y1; y2<=3; ++y2)
579  {
580  if (x1 == x2 && y1 == y2)
581  continue;
582  const Square p2(x2,y2);
583  const int py = (3-std::min(y1, y2))*10; // 3段目のほうがマシに
584  const int center = std::min(abs(5-x1), abs(5-x2)); // 端を減点
585  const int p = 0-py-center*15; // y=1:0,-80
586  if (p == 0)
587  continue;
588  for (int t1=0; t1<(int)types.size(); ++t1)
589  {
590  assert(isPiece(types[t1]));
591  if (y1 < 3 && types[t1] == KNIGHT)
592  continue;
593  if (y1 == 1 && (types[t1] == LANCE || types[t1] == PAWN))
594  continue;
595  for (int t2=0; t2<(int)types.size(); ++t2)
596  {
597  if (y2 < 3 && types[t2] == KNIGHT)
598  continue;
599  if (y2 == 1 && (types[t2] == LANCE || types[t2] == PAWN))
600  continue;
601  addPenalty(BLACK, *table, p1, types[t1], p2, types[t2], p);
602  addPenalty(WHITE, *table, p1.rotate180(), types[t1],
603  p2.rotate180(), types[t2], -p);
604  }
605  }
606  }
607  }
608  }
609  }
610 
611  // 飛車先の歩を切る
612  for (int x=1; x<=9; ++x)
613  {
614  for (int y=5; y<=7; ++y)
615  {
616  const Square pawn(x,y);
617  for (int ry=6; ry<=9; ++ry)
618  {
619  if (y == ry)
620  continue;
621  const Square rook(x,ry);
622  const int p = -y*10-25;
623  addPenalty(BLACK, *table, rook, ROOK, pawn, PAWN, p);
624  addPenalty(WHITE, *table, rook.rotate180(), ROOK,
625  pawn.rotate180(), PAWN, -p);
626  }
627  }
628  }
629 
630  // 相手の飛車/香車を受ける
631  for (int x=1; x<=9; ++x)
632  {
633  for (int y=3; y<=7; ++y)
634  {
635  const Square pawn(x,y);
636  for (int ry=1; ry<y; ++ry)
637  {
638  const Square rook(x,ry);
639  adjustDual(*table, pawn, PAWN, rook, ROOK, 90);
640  adjustDual(*table, pawn, PAWN, rook, LANCE, 90);
641  }
642  }
643  }
644 
645  // 自陣の歩
646  for (int x=1; x<=9; ++x)
647  {
648  for (int y=8; y<=9; ++y)
649  {
650  const Square pawn(x,y);
651  const Square pawn_white = pawn.rotate180();
652 #if 0
653  addPenalty(BLACK, *table, pawn, PAWN, pawn, PAWN, -60);
654  addPenalty(WHITE, *table, pawn_white, PAWN, pawn_white, PAWN, 60);
655 #endif
656  // 玉に近いとさらに減点
657  for (int kx=1; kx<=9; ++kx)
658  {
659  for (int ky=7; ky<=9; ++ky)
660  {
661  const Square king(kx,ky);
662  const Square king_white = king.rotate180();
663  if (king == pawn)
664  continue;
665  const int penalty = -(8-abs(kx-x))*10; // 0-80
666  if (penalty == 0)
667  continue;
668  addPenalty(BLACK, *table, pawn, PAWN, king, KING, penalty);
669  addPenalty(WHITE, *table, pawn_white, PAWN, king_white, KING, -penalty);
670 
671  // 敵玉の居る筋に対するペナルティ
672  adjust(*table, pawn, newPtypeO(BLACK,PAWN),
673  Square(kx,10-ky), newPtypeO(WHITE,KING), penalty);
674  adjust(*table, Square(x,10-y), newPtypeO(WHITE,PAWN),
675  king, newPtypeO(BLACK,KING), -penalty);
676  }
677  }
678  }
679  }
680 
681  table->writeInBinaryFile(write_pairfilename);
682 }
683 
684 
685 /* ------------------------------------------------------------------------- */
686 // ;;; Local Variables:
687 // ;;; mode:c++
688 // ;;; c-basic-offset:2
689 // ;;; End: