pairedit.cc
Go to the documentation of this file.
00001 /* pairedit.cc
00002  */
00003 
00004 #include "osl/eval/ppair/piecePairRawEval.h"
00005 #include <boost/scoped_ptr.hpp>
00006 #include <iostream>
00007 #include <cstdlib>
00008 #include <cstdio>
00009 #include <unistd.h>
00010 
00024 using namespace osl;
00025 using namespace osl::eval;
00026 
00027 void usage(const char *prog)
00028 {
00029   using namespace std;
00030   cerr << "Usage: " << prog << " [-f read-pair-file-name] [-o write-pair-file-name] "
00031        << endl;
00032   exit(1);
00033 }
00034 
00035 bool verbose = false;
00036 
00037 void adjust(PiecePairRawTable& table, 
00038             Square pos1, PtypeO ptypeo1,
00039             Square pos2, PtypeO ptypeo2,
00040             int value)
00041 {
00042   assert(pos1.isOnBoard());
00043   assert(pos2.isOnBoard());
00044   const unsigned int index1 = table.indexOf(pos1, ptypeo1);
00045   const unsigned int index2 = table.indexOf(pos2, ptypeo2);
00046   
00047   int val = table.valueOf(index1, index2);
00048   assert(val == table.valueOf(index2, index1));
00049   if (verbose)
00050     std::cerr << pos1 << ptypeo1 << " " << pos2 << ptypeo2
00051               << " " << val << " => ";
00052   val += value;
00053   val = std::min(127, val);
00054   val = std::max(-127, val);
00055   if (verbose)
00056     std::cerr << val << "\n";
00057   table.valueOf(index1, index2) = val;
00058   table.valueOf(index2, index1) = val;
00059 }
00060 
00061 void adjustKingBonus(PiecePairRawTable& table, 
00062                      Square pos1, PtypeO ptypeo1, // king
00063                      Square pos2, PtypeO ptypeo2, // attacker
00064                      int bonus)
00065 {
00066   assert(getPtype(ptypeo1) == KING);
00067   assert(getPtype(ptypeo2) != KING);
00068   assert(getOwner(ptypeo1) != getOwner(ptypeo2));
00069   assert((bonus > 0) ^ (getOwner(ptypeo1) == BLACK));
00070 
00071   adjust(table, pos1, ptypeo1, pos2, ptypeo2, bonus);
00072 }
00073 
00075 void adjustDual(PiecePairRawTable& table, 
00076                 Square king, Square attacker, Ptype attackerType,
00077                 int blackAttackBonus, int whiteAttackBonus)
00078 {
00079   adjustKingBonus(table, king.rotate180(), newPtypeO(BLACK, KING),
00080          attacker.rotate180(), newPtypeO(WHITE, attackerType),
00081          whiteAttackBonus);
00082   adjustKingBonus(table, king, newPtypeO(WHITE, KING),
00083          attacker, newPtypeO(BLACK, attackerType),
00084          blackAttackBonus);
00085 }
00086 
00087 void adjustDual(PiecePairRawTable& table, 
00088                 Square black, Ptype black_ptype,
00089                 Square white, Ptype white_ptype,
00090                 int value)
00091 {
00092   adjust(table, black, newPtypeO(BLACK, black_ptype),
00093          white, newPtypeO(WHITE, white_ptype), value);
00094   adjust(table, black.rotate180(), newPtypeO(WHITE, black_ptype),
00095          white.rotate180(), newPtypeO(BLACK, white_ptype), -value);
00096 }
00097 
00098 void addValue(Player player, PiecePairRawTable& table,
00099               Square pos1, Ptype ptype1,
00100               Square pos2, Ptype ptype2,
00101               int bonus)
00102 {
00103   const PtypeO ptypeo1 = newPtypeO(player, ptype1);
00104   const PtypeO ptypeo2 = newPtypeO(player, ptype2);
00105   adjust(table, pos1, ptypeo1, pos2, ptypeo2, bonus);
00106 }
00107 
00108 void addPenalty(Player player, PiecePairRawTable& table,
00109                 Square pos1, Ptype ptype1,
00110                 Square pos2, Ptype ptype2,
00111                 int bonus)
00112 {
00113   assert(eval::betterThan(player, 0, bonus));
00114   addValue(player, table, pos1, ptype1, pos2, ptype2, bonus);
00115 }
00116 
00117 void addBonus(Player player, PiecePairRawTable& table,
00118               Square pos1, Ptype ptype1,
00119               Square pos2, Ptype ptype2,
00120               int bonus)
00121 {
00122   assert(eval::betterThan(player, bonus, 0));
00123   addValue(player, table, pos1, ptype1, pos2, ptype2, bonus);
00124 }
00125 
00126 void addPenaltyDual(PiecePairRawTable& table, 
00127                     Square pos1, Ptype ptype1,
00128                     Square pos2, Ptype ptype2,
00129                     int black_bonus)
00130 {
00131   assert(black_bonus < 0);
00132   addPenalty(BLACK, table, pos1, ptype1, pos2, ptype2,  black_bonus);
00133   addPenalty(WHITE, table, pos1, ptype1, pos2, ptype2, -black_bonus);
00134 }
00135 
00136 void addSelfPenaltyDual(PiecePairRawTable& table, 
00137                         Square pos, Ptype ptype,
00138                         int black_bonus)
00139 {
00140   addPenaltyDual(table, pos, ptype, pos, ptype, black_bonus);
00141 }
00142 
00143 
00144 int main(int argc, char **argv)
00145 {
00146   const char *program_name = argv[0];
00147   bool error_flag = false;
00148   const char *read_pairfilename = 0;
00149   const char *write_pairfilename = 0;
00150   
00151   extern char *optarg;
00152   extern int optind;
00153   char c;
00154   while ((c = getopt(argc, argv, "f:o:vh")) != EOF)
00155   {
00156     switch(c)
00157     {
00158     case 'f':   read_pairfilename = optarg;
00159       break;
00160     case 'o':   write_pairfilename = optarg;
00161       break;
00162     case 'v':   verbose = true;
00163       break;
00164     default:    error_flag = true;
00165     }
00166   }
00167   argc -= optind;
00168   argv += optind;
00169 
00170   if (error_flag || (! read_pairfilename) || (! write_pairfilename))
00171     usage(program_name);
00172 
00173   boost::scoped_ptr<PiecePairRawTable> table(new PiecePairRawTable);
00174   table->loadFromBinaryFile(read_pairfilename);
00175 
00176   // 通常の5x5の範囲
00177   CArray2d<bool,Square::SIZE,Square::SIZE> adjusted;
00178   adjusted.fill(false);
00179   for (int king_x=1; king_x<=9; ++king_x)
00180   {
00181     for (int king_y=1; king_y<=9; ++king_y)
00182     {
00183       const Square king(king_x,king_y);
00184       for (int attacker_x = ((king_x==9) ? king_x-3 : king_x-2); 
00185            attacker_x <= ((king_x==1) ? king_x+3 : king_x+2); ++attacker_x)
00186       {
00187         if ((attacker_x < 1) || (attacker_x > 9))
00188           continue;
00189         for (int attacker_y = ((king_y==9) ? king_y-3 : king_y-2); 
00190              attacker_y <= ((king_y==1) ? king_y+3 : king_y+2); ++attacker_y)
00191         {
00192           if ((attacker_y < 1) || (attacker_y > 9))
00193             continue;
00194           const Square attacker(attacker_x,attacker_y);
00195           if (king == attacker)
00196             continue;
00197           adjusted[king.index()][attacker.index()] = true;
00198           adjustDual(*table, king, attacker, PPAWN,   100, -100);
00199           adjustDual(*table, king, attacker, PLANCE,  100, -100);
00200           adjustDual(*table, king, attacker, PKNIGHT, 100, -100);
00201           adjustDual(*table, king, attacker, PBISHOP, 100, -100);
00202           adjustDual(*table, king, attacker, PROOK,   100, -100);
00203           adjustDual(*table, king, attacker, SILVER,  100, -100);
00204           adjustDual(*table, king, attacker, BISHOP,  100, -100);
00205           adjustDual(*table, king, attacker, ROOK,    100, -100);
00206 
00207           // 金と成銀は1段目以外
00208           if (attacker_y != 1)
00209           {
00210             const int bonus = 
00211               (attacker_y >= king_y) ? 100 : 50;
00212             adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
00213                             attacker, newPtypeO(BLACK, PSILVER),
00214                             bonus);
00215             adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
00216                             attacker, newPtypeO(BLACK, GOLD),
00217                             bonus);
00218           }
00219           if (attacker_y != 9)
00220           {
00221             const int bonus = 
00222               (attacker_y <= king_y) ? -100 : -50;
00223             adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
00224                             attacker, newPtypeO(WHITE, PSILVER),
00225                             bonus);
00226             adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
00227                             attacker, newPtypeO(WHITE, GOLD),
00228                             bonus);
00229           }
00230           // 歩は王と同列かより手前
00231           if (attacker_y >= king_y)
00232           {
00233             adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
00234                             attacker, newPtypeO(BLACK, PAWN),
00235                             100);
00236           }
00237           if (attacker_y <= king_y)
00238           {
00239             adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
00240                             attacker, newPtypeO(WHITE, PAWN),
00241                             -100);
00242           }
00243         } // attacker_y
00244         // 桂香は長目にとる
00245         for (int attacker_y = ((king_y==9) ? king_y-4 : king_y-3);
00246              attacker_y <= ((king_y==1) ? king_y+4 : king_y+3); ++attacker_y)
00247         {
00248           if ((attacker_y < 1) || (attacker_y > 9))
00249             continue;
00250           const Square attacker(attacker_x,attacker_y);
00251           if (king == attacker)
00252             continue;
00253 
00254           // 王より手前, 25,45,65,85 は弊害が大きいので除く
00255           if (! ((attacker_y == 5)
00256                  && ((attacker_x == 2)
00257                      || (attacker_x == 4)
00258                      || (attacker_x == 6)
00259                      || (attacker_x == 8))))
00260           {
00261             if ((attacker_y > king_y) && (attacker_y > 2))
00262             {
00263               adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
00264                               attacker, newPtypeO(BLACK, LANCE),
00265                               100);
00266               adjustKingBonus(*table, king, newPtypeO(WHITE, KING),
00267                               attacker, newPtypeO(BLACK, KNIGHT),
00268                               100);
00269             }
00270             if ((attacker_y < king_y) && (attacker_y < 8))
00271             {
00272               adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
00273                               attacker, newPtypeO(WHITE, LANCE),
00274                               -100);
00275               adjustKingBonus(*table, king, newPtypeO(BLACK, KING),
00276                               attacker, newPtypeO(WHITE, KNIGHT),
00277                               -100);
00278             }
00279           }
00280         } // attacker_y, knight, lance
00281       } // attacker_x
00282     } // king_y
00283   } // king_x
00284   // 5x5の範囲外の補正 x+1
00285   for (int king_x=1; king_x<=9; ++king_x)
00286   {
00287     for (int king_y=1; king_y<=3; ++king_y)
00288     {
00289       const Square king(king_x,king_y);
00290       for (int rook_x=1; rook_x<=9; ++rook_x)
00291       {
00292         for (int rook_y=king_y-1; rook_y<=king_y+1; ++rook_y)
00293         {
00294           if ((rook_y < 1) || (rook_y > 9))
00295             continue;
00296           const Square rook(rook_x, rook_y);
00297           if (king == rook)
00298             continue;
00299           if (! adjusted[king.index()][rook.index()])
00300           {
00301             adjustDual(*table, king, rook, ROOK,   30, -30);
00302             adjustDual(*table, king, rook, PROOK,  30, -30);
00303           }
00304         }
00305       }
00306       for (int attacker_x = ((king_x==9) ? king_x-4 : king_x-3); 
00307            attacker_x <= ((king_x==1) ? king_x+4 : king_x+3); ++attacker_x)
00308       {
00309         if ((attacker_x < 1) || (attacker_x > 9))
00310           continue;
00311         for (int attacker_y = king_y; attacker_y <= ((king_y==1) ? king_y+3 : king_y+2); ++attacker_y)
00312         {
00313           if ((attacker_y < 1) || (attacker_y > 9))
00314             continue;
00315           const Square attacker(attacker_x,attacker_y);
00316           if (king == attacker)
00317             continue;
00318           if (adjusted[king.index()][attacker.index()])
00319             continue;
00320           adjusted[king.index()][attacker.index()] = true;
00321           adjustDual(*table, king, attacker, PPAWN,   40, -40);
00322           adjustDual(*table, king, attacker, PLANCE,  40, -40);   
00323           adjustDual(*table, king, attacker, PKNIGHT, 40, -40);   
00324           adjustDual(*table, king, attacker, SILVER,  40, -40);   
00325         }
00326       }
00327     }
00328   }
00329   // x+2
00330   for (int king_x=1; king_x<=9; ++king_x)
00331   {
00332     for (int king_y=1; king_y<=3; ++king_y)
00333     {
00334       const Square king(king_x,king_y);
00335       for (int attacker_x = ((king_x==9) ? king_x-5 : king_x-4); 
00336            attacker_x <= ((king_x==1) ? king_x+5 : king_x+4); ++attacker_x)
00337       {
00338         if ((attacker_x < 1) || (attacker_x > 9))
00339           continue;
00340         for (int attacker_y = king_y+1; attacker_y <= ((king_y==1) ? king_y+3 : king_y+2); ++attacker_y)
00341         {
00342           if ((attacker_y < 1) || (attacker_y > 9))
00343             continue;
00344           const Square attacker(attacker_x,attacker_y);
00345           if (king == attacker)
00346             continue;
00347           if (adjusted[king.index()][attacker.index()])
00348             continue;
00349           adjustDual(*table, king, attacker, PPAWN,   10, -10);
00350           adjustDual(*table, king, attacker, PLANCE,  10, -10);   
00351           adjustDual(*table, king, attacker, PKNIGHT, 10, -10);   
00352           adjustDual(*table, king, attacker, SILVER,  10, -10);   
00353         }
00354       }
00355     }
00356   }
00357   for (int attacker_x=1; attacker_x<=9; ++attacker_x)
00358   {
00359     for (int attacker_y=1; attacker_y<=9; ++attacker_y)
00360     {
00361       const Square attacker(attacker_x,attacker_y);
00362       // 端の駒は色々減点
00363       if ((attacker_x == 1) || (attacker_x == 9))
00364       {
00365         addSelfPenaltyDual(*table, attacker, KNIGHT,  -100);
00366         addSelfPenaltyDual(*table, attacker, SILVER,  -100);
00367         addSelfPenaltyDual(*table, attacker, GOLD  ,  -100);
00368         addSelfPenaltyDual(*table, attacker, PPAWN ,  -100);
00369         addSelfPenaltyDual(*table, attacker, PLANCE,  -100);
00370         addSelfPenaltyDual(*table, attacker, PKNIGHT, -100);
00371         addSelfPenaltyDual(*table, attacker, PSILVER, -100);
00372       }
00373     }
00374   }
00375   // 捌きにくい銀
00376   addPenalty(BLACK, *table, Square(2,6), SILVER, Square(3,7), KNIGHT, -80);
00377   addPenalty(WHITE, *table, Square(8,4), SILVER, Square(7,3), KNIGHT, +80);
00378 
00379   addPenalty(BLACK, *table, Square(2,6), SILVER, Square(1,5), PAWN, -80);
00380   addPenalty(WHITE, *table, Square(8,4), SILVER, Square(9,5), PAWN, +80);
00381 
00382   addPenalty(BLACK, *table, Square(9,7), SILVER, Square(8,8), BISHOP, -80);
00383   addPenalty(BLACK, *table, Square(1,7), SILVER, Square(2,8), BISHOP, -80);
00384   addPenalty(WHITE, *table, Square(9,3), SILVER, Square(8,2), BISHOP, +80);
00385   addPenalty(WHITE, *table, Square(1,3), SILVER, Square(2,2), BISHOP, +80);
00386   
00387   // 穴熊関係
00388   addPenalty(BLACK, *table, Square(9,9), KING, Square(7,7), KNIGHT, -120);
00389   addPenalty(BLACK, *table, Square(9,9), KING, Square(9,7), KNIGHT, -120);
00390   addPenalty(BLACK, *table, Square(1,9), KING, Square(3,7), KNIGHT, -120);
00391   addPenalty(BLACK, *table, Square(1,9), KING, Square(1,7), KNIGHT, -120);
00392   addPenalty(WHITE, *table, Square(9,1), KING, Square(7,3), KNIGHT, +120);
00393   addPenalty(WHITE, *table, Square(9,1), KING, Square(9,3), KNIGHT, +120);
00394   addPenalty(WHITE, *table, Square(1,1), KING, Square(3,3), KNIGHT, +120);
00395   addPenalty(WHITE, *table, Square(1,1), KING, Square(1,3), KNIGHT, +120);
00396 
00397   // 玉の点数を引いておき,桂香があれば復活させる
00398   addPenalty(BLACK, *table, Square(9,9), KING, Square(9,9), KING, -120);
00399   addBonus(BLACK, *table, Square(9,9), KING, Square(9,8), LANCE, 40);
00400   addBonus(BLACK, *table, Square(9,9), KING, Square(8,9), KNIGHT, 80);
00401 
00402   addPenalty(BLACK, *table, Square(1,9), KING, Square(1,9), KING, -120);
00403   addBonus(BLACK, *table, Square(1,9), KING, Square(1,8), LANCE, 40);
00404   addBonus(BLACK, *table, Square(1,9), KING, Square(2,9), KNIGHT, 80);
00405 
00406   addPenalty(WHITE, *table, Square(9,1), KING, Square(9,1), KING, +120);
00407   addBonus(WHITE, *table, Square(9,1), KING, Square(9,2), LANCE, -40);
00408   addBonus(WHITE, *table, Square(9,1), KING, Square(8,1), KNIGHT, -80);
00409 
00410   addPenalty(WHITE, *table, Square(1,1), KING, Square(1,1), KING, +120);
00411   addBonus(WHITE, *table, Square(1,1), KING, Square(1,2), LANCE, -40);
00412   addBonus(WHITE, *table, Square(1,1), KING, Square(2,1), KNIGHT, -80);
00413 
00414   // 5段目の桂馬 (取られそう)
00415   for (int x=2; x<=8; ++x)      // 1,9はペナルティ済
00416   {
00417     // 
00418     const Square attacker(x,5);
00419     addSelfPenaltyDual(*table, attacker, KNIGHT, -100);
00420 
00421     // 相手の歩が遠ければ大丈夫かも.
00422     adjust(*table, Square(x,1), newPtypeO(WHITE,PAWN), attacker, newPtypeO(BLACK,KNIGHT), 100);
00423     adjust(*table, Square(x,2), newPtypeO(WHITE,PAWN), attacker, newPtypeO(BLACK,KNIGHT), 100);
00424     adjust(*table, Square(x,9), newPtypeO(BLACK,PAWN), attacker, newPtypeO(WHITE,KNIGHT), -100);
00425     adjust(*table, Square(x,8), newPtypeO(BLACK,PAWN), attacker, newPtypeO(WHITE,KNIGHT), -100);
00426   }
00427 
00428   // 敵の大駒の成駒と自陣の生の駒
00429   for (int promoted_x=1; promoted_x<=9; ++promoted_x)
00430   {
00431     for (int x=1; x<=9; ++x)
00432     {
00433       for (int promoted_y=1; promoted_y<=3; ++promoted_y)
00434       {
00435         const Square promoted(promoted_x, promoted_y);
00436         for (int y=1; y<=3; ++y)
00437         {
00438           const Square unpromoted(x, y);
00439           if (promoted == unpromoted)
00440             continue;
00441           adjust(*table, promoted, newPtypeO(BLACK,PROOK), 
00442                  unpromoted, newPtypeO(WHITE,ROOK), 100);
00443           adjust(*table, promoted, newPtypeO(BLACK,PROOK), 
00444                  unpromoted, newPtypeO(WHITE,BISHOP), 100);
00445           adjust(*table, promoted, newPtypeO(BLACK,PBISHOP), 
00446                  unpromoted, newPtypeO(WHITE,ROOK), 100);
00447           adjust(*table, promoted, newPtypeO(BLACK,PBISHOP), 
00448                  unpromoted, newPtypeO(WHITE,BISHOP), 100);
00449         }
00450       }
00451       for (int promoted_y=7; promoted_y<=9; ++promoted_y)
00452       {
00453         const Square promoted(promoted_x, promoted_y);
00454         for (int y=7; y<=9; ++y)
00455         {
00456           const Square unpromoted(x, y);
00457           if (promoted == unpromoted)
00458             continue;
00459           adjust(*table, promoted, newPtypeO(WHITE,PROOK), 
00460                  unpromoted, newPtypeO(BLACK,ROOK), -100);
00461           adjust(*table, promoted, newPtypeO(WHITE,PROOK), 
00462                  unpromoted, newPtypeO(BLACK,BISHOP), -100);
00463           adjust(*table, promoted, newPtypeO(WHITE,PBISHOP), 
00464                  unpromoted, newPtypeO(BLACK,ROOK), -100);
00465           adjust(*table, promoted, newPtypeO(WHITE,PBISHOP), 
00466                  unpromoted, newPtypeO(BLACK,BISHOP), -100);
00467         }
00468       }
00469     } // x
00470   }
00471   // 4,6段目の歩に抑え込みボーナス
00472   for (int x=1; x<=9; ++x)
00473   {
00474     // 
00475     const Square black_position(x,4);
00476     const Square white_position(x,6);
00477     addBonus(BLACK, *table, black_position, PAWN, black_position, PAWN, 100);
00478     addBonus(WHITE, *table, white_position, PAWN, white_position, PAWN,-100);
00479   }
00480 
00481   for (int x=1; x<=9; ++x)
00482   {
00483     // 危ない飛車
00484     addPenalty(BLACK, *table, Square(x,6), ROOK, Square(x,7), PAWN, -95);
00485     addPenalty(WHITE, *table, Square(x,4), ROOK, Square(x,3), PAWN, +95);
00486     // 捌きにくい銀
00487     if (x == 1 || x == 3 || x == 7 || x == 9) 
00488     {
00489       addPenalty(BLACK, *table, Square(x,6), SILVER, Square(x,7), PAWN, -80);
00490       addPenalty(WHITE, *table, Square(x,4), SILVER, Square(x,3), PAWN, +80);
00491     }
00492     // 捻り飛車失敗?
00493     for (int i=x-1; i<=x+1; ++i)
00494     {
00495       if (i<1 || i > 9)
00496         continue;
00497       addPenalty(BLACK, *table, Square(x,6), ROOK, Square(i,8), KING, -100);
00498       addPenalty(BLACK, *table, Square(x,6), ROOK, Square(i,9), KING,  -90);
00499       addPenalty(WHITE, *table, Square(x,4), ROOK, Square(i,2), KING, +100);
00500       addPenalty(WHITE, *table, Square(x,4), ROOK, Square(i,1), KING,  +90);
00501     }
00502     // 玉飛接近
00503     for (int y=7; y<=9; ++y)
00504     {
00505       const int wy = 10-y;
00506       addPenalty(BLACK, *table, Square(x,y), KING, Square(x,y-1), ROOK, -70);
00507       addPenalty(BLACK, *table, Square(x,y-1), KING, Square(x,y), ROOK, -70);
00508       addPenalty(WHITE, *table, Square(x,wy), KING, Square(x,wy+1), ROOK, +70);
00509       addPenalty(WHITE, *table, Square(x,wy+1), KING, Square(x,wy), ROOK, +70);
00510       if (x > 1)
00511       {
00512         addPenalty(BLACK, *table, Square(x,y), KING, Square(x-1,y), ROOK, -70);
00513         addPenalty(WHITE, *table, Square(x,wy), KING, Square(x-1,wy), ROOK, +70);
00514       }
00515       if (x > 2) 
00516       {
00517         addPenalty(BLACK, *table, Square(x,y), KING, Square(x-2,y), ROOK, -50);
00518         addPenalty(WHITE, *table, Square(x,wy), KING, Square(x-2,wy), ROOK, +50);
00519       }
00520       if (x < 9)
00521       {
00522         addPenalty(BLACK, *table, Square(x,y), KING, Square(x+1,y), ROOK, -70);
00523         addPenalty(WHITE, *table, Square(x,wy), KING, Square(x+1,wy), ROOK, +70);
00524       }
00525       if (x < 8)
00526       {
00527         addPenalty(BLACK, *table, Square(x,y), KING, Square(x+2,y), ROOK, -50);
00528         addPenalty(WHITE, *table, Square(x,wy), KING, Square(x+2,wy), ROOK, +50);
00529       }
00530     } // for y
00531   } // for x
00532 
00533   // 桂馬と飛車
00534   addPenalty(BLACK, *table, Square(1,7), ROOK, Square(2,9), KNIGHT, -70);
00535   addPenalty(BLACK, *table, Square(3,7), ROOK, Square(2,9), KNIGHT, -70);
00536   addPenalty(BLACK, *table, Square(7,7), ROOK, Square(8,9), KNIGHT, -70);
00537   addPenalty(BLACK, *table, Square(9,7), ROOK, Square(8,9), KNIGHT, -70);
00538   addPenalty(WHITE, *table, Square(1,3), ROOK, Square(2,1), KNIGHT, +70);
00539   addPenalty(WHITE, *table, Square(3,3), ROOK, Square(2,1), KNIGHT, +70);
00540   addPenalty(WHITE, *table, Square(7,3), ROOK, Square(8,1), KNIGHT, +70);
00541   addPenalty(WHITE, *table, Square(9,3), ROOK, Square(8,1), KNIGHT, +70);
00542   // 角道を防ぐ金
00543   for (int x=1; x<=9; ++x)
00544   {
00545     for (int y=8; y<=9; ++y) 
00546     {
00547       const Square bishop(x, y);
00548       if (x < 9)
00549       {
00550         const Square ul(x+1, y-1);
00551         addPenalty(BLACK, *table, bishop, BISHOP, ul, GOLD, -65);
00552         addPenalty(WHITE, *table, bishop.rotate180(), BISHOP, 
00553                    ul.rotate180(), GOLD, 65);
00554       }
00555       if (x > 1) 
00556       {
00557         const Square ur(x-1, y-1);
00558         addPenalty(BLACK, *table, bishop, BISHOP, ur, GOLD, -65);
00559         addPenalty(WHITE, *table, bishop.rotate180(), BISHOP, 
00560                    ur.rotate180(), GOLD, 65);
00561       }
00562     }
00563   }
00564 
00565   // 隣接する成駒
00566   const CArray<Ptype, 6> types = 
00567     {{ LANCE, KNIGHT, PPAWN, PLANCE, PKNIGHT, PSILVER }};
00568   for (int x1=1; x1<=9; ++x1)
00569   {
00570     for (int x2=x1; x2<=9; ++x2)
00571     {
00572       const int xdiff = abs(x1 - x2);
00573       if (xdiff > 2)
00574         continue;
00575       for (int y1=1; y1<=3; ++y1) 
00576       {
00577         const Square p1(x1,y1);
00578         for (int y2=y1; y2<=3; ++y2) 
00579         {
00580           if (x1 == x2 && y1 == y2)
00581             continue;
00582           const Square p2(x2,y2);
00583           const int py = (3-std::min(y1, y2))*10; // 3段目のほうがマシに
00584           const int center = std::min(abs(5-x1), abs(5-x2)); // 端を減点
00585           const int p = 0-py-center*15; // y=1:0,-80
00586           if (p == 0)
00587             continue;
00588           for (int t1=0; t1<(int)types.size(); ++t1)
00589           {
00590             assert(isPiece(types[t1]));
00591             if (y1 < 3 && types[t1] == KNIGHT)
00592               continue;
00593             if (y1 == 1 && (types[t1] == LANCE || types[t1] == PAWN))
00594               continue;
00595             for (int t2=0; t2<(int)types.size(); ++t2)
00596             {
00597               if (y2 < 3 && types[t2] == KNIGHT)
00598                 continue;
00599               if (y2 == 1 && (types[t2] == LANCE || types[t2] == PAWN))
00600                 continue;
00601               addPenalty(BLACK, *table, p1, types[t1], p2, types[t2], p);
00602               addPenalty(WHITE, *table, p1.rotate180(), types[t1], 
00603                          p2.rotate180(), types[t2], -p);
00604             }
00605           }
00606         }
00607       }
00608     }
00609   }
00610 
00611   // 飛車先の歩を切る
00612   for (int x=1; x<=9; ++x)
00613   {
00614     for (int y=5; y<=7; ++y)
00615     {
00616       const Square pawn(x,y);
00617       for (int ry=6; ry<=9; ++ry)
00618       {
00619         if (y == ry)
00620           continue;
00621         const Square rook(x,ry);
00622         const int p = -y*10-25;
00623         addPenalty(BLACK, *table, rook, ROOK, pawn, PAWN, p);
00624         addPenalty(WHITE, *table, rook.rotate180(), ROOK, 
00625                    pawn.rotate180(), PAWN, -p);
00626       }
00627     }
00628   }
00629 
00630   // 相手の飛車/香車を受ける
00631   for (int x=1; x<=9; ++x)
00632   {
00633     for (int y=3; y<=7; ++y)
00634     {
00635       const Square pawn(x,y);
00636       for (int ry=1; ry<y; ++ry)
00637       {
00638         const Square rook(x,ry);
00639         adjustDual(*table, pawn, PAWN, rook, ROOK, 90);
00640         adjustDual(*table, pawn, PAWN, rook, LANCE, 90);
00641       }
00642     }
00643   }
00644 
00645   // 自陣の歩
00646   for (int x=1; x<=9; ++x)
00647   {
00648     for (int y=8; y<=9; ++y)
00649     {
00650       const Square pawn(x,y);
00651       const Square pawn_white = pawn.rotate180();
00652 #if 0
00653       addPenalty(BLACK, *table, pawn, PAWN, pawn, PAWN, -60);
00654       addPenalty(WHITE, *table, pawn_white, PAWN, pawn_white, PAWN, 60);
00655 #endif
00656       // 玉に近いとさらに減点
00657       for (int kx=1; kx<=9; ++kx)
00658       {
00659         for (int ky=7; ky<=9; ++ky)
00660         {
00661           const Square king(kx,ky);
00662           const Square king_white = king.rotate180();
00663           if (king == pawn)
00664             continue;
00665           const int penalty = -(8-abs(kx-x))*10;        // 0-80
00666           if (penalty == 0)
00667             continue;
00668           addPenalty(BLACK, *table, pawn, PAWN, king, KING, penalty);
00669           addPenalty(WHITE, *table, pawn_white, PAWN, king_white, KING, -penalty);
00670 
00671           // 敵玉の居る筋に対するペナルティ
00672           adjust(*table, pawn, newPtypeO(BLACK,PAWN), 
00673                  Square(kx,10-ky), newPtypeO(WHITE,KING), penalty);
00674           adjust(*table, Square(x,10-y), newPtypeO(WHITE,PAWN), 
00675                  king, newPtypeO(BLACK,KING), -penalty);
00676         }
00677       }
00678     }
00679   }
00680   
00681   table->writeInBinaryFile(write_pairfilename);
00682 }
00683 
00684 
00685 /* ------------------------------------------------------------------------- */
00686 // ;;; Local Variables:
00687 // ;;; mode:c++
00688 // ;;; c-basic-offset:2
00689 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines