pairedit.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
4 #include "osl/eval/ppair/piecePairRawEval.h"
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: