defenseKing.cc
Go to the documentation of this file.
00001 
00004 #include "osl/eval/endgame/defenseKing.h"
00005 #include "osl/eval/pieceEval.h"
00006 #include "osl/misc/carray.h"
00007 
00008 // YSSの評価値を真似
00009 // http://www32.ocn.ne.jp/~yss/book.html#SEC3
00010 //
00011 //         0   1   2   3   4   5   6   7   8 (X距離)
00012 //   +8   50  50  50  50  50  50  50  50  50
00013 //   +7   56  53  50  50  50  50  50  50  50
00014 //   +6   64  61  55  50  50  50  50  50  50
00015 //   +5   79  77  70  65  54  51  50  50  50
00016 //   +4  100  99  95  87  74  58  50  50  50
00017 //   +3  116 117 101  95  88  67  54  50  50
00018 //   +2  131 129 124 114  90  71  59  51  50
00019 //   +1  137 138 132 116  96  76  61  53  50
00020 //    0  142 142 136 118  98  79  64  52  50  <--- 中心
00021 //   -1  132 132 129 109  95  75  60  51  50
00022 //   -2  121 120 105  97  84  66  54  50  50
00023 //   -3   95  93  89  75  68  58  51  50  50
00024 //   -4   79  76  69  60  53  50  50  50  50
00025 //   -5   64  61  55  51  50  50  50  50  50
00026 //   -6   56  52  50  50  50  50  50  50  50
00027 //   -7   50  50  50  50  50  50  50  50  50
00028 //   -8   50  50  50  50  50  50  50  50  50
00029 
00030 namespace osl
00031 {
00032   namespace
00033   {
00034     const CArray<int,19*9> yss_bonus = {{
00035       // 桂,香は一段下げるため,+9 から -9 まで取る
00036       50,  50,  50,  50,  50,  50,  0,  0,  0,
00037       50,  50,  50,  50,  50,  50,  0,  0,  0,
00038       56,  53,  50,  50,  50,  50,  0,  0,  0,
00039       64,  61,  55,  50,  50,  50,  0,  0,  0,
00040       79,  77,  70,  65,  54,  51,  0,  0,  0,
00041      100,  99,  95,  87,  74,  58,  0,  0,  0,
00042      116, 117, 101,  95,  88,  67,  0,  0,  0,
00043      131, 129, 124, 114,  90,  71,  0,  0,  0,
00044      137, 138, 132, 116,  96,  76,  0,  0,  0,
00045      142, 142, 136, 118,  98,  79,  0,  0,  0,
00046      132, 132, 129, 109,  95,  75,  0,  0,  0,
00047      121, 120, 105,  97,  84,  66,  0,  0,  0,
00048       95,  93,  89,  75,  68,  58,  0,  0,  0,
00049       79,  76,  69,  60,  53,  50,  0,  0,  0,
00050       64,  61,  55,  51,  50,  50,  0,  0,  0,
00051       56,  52,  50,  50,  50,  50,  0,  0,  0,
00052       50,  50,  50,  50,  50,  50,  0,  0,  0,
00053       50,  50,  50,  50,  50,  50,  0,  0,  0,
00054       50,  50,  50,  50,  50,  50,  0,  0,  0,
00055     }};
00057     const CArray<int,9> yss_king_bonus = {{
00058       0, 0, 0, 150, 450, 900,1300,1550,1600
00059     }};
00060     inline int toEven(int value) 
00061     {
00062       if (value % 2 == 0)
00063         return value;
00064       if (value > 0)
00065         return value - 1;
00066       return value + 1;
00067     }
00068     inline int multiply(int value, int bonus)
00069     {
00070       // http://www32.ocn.ne.jp/~yss/book.html#SEC3
00071       // > 追記:2005年01月22日
00072       // > 自玉の近くの点数は高すぎるので、現在は+を3分の1の値まで下げています
00073       if (bonus > 100)
00074         bonus = (bonus - 100)/3 + 100;
00075       // yss では持駒の付加価値が2割程度あるため1.2で割る
00076       return toEven(value * bonus / 120);
00077     }
00078     inline void adhoc_adjust(int& value, double scale)
00079     {
00080       value = toEven(static_cast<int>(value * scale));
00081     }
00082   } // anonymous namespace
00083 } // namespace osl
00084 
00085 
00086 
00087 osl::eval::endgame::DefenseKing::
00088 Table::Table()
00089 {
00090   // BLACKのKINGに対するBLACKの価値を書き,WHITEの駒の価値は最後に反転させる.
00091   data.fill(0);
00092   for (int king_x=1; king_x<=9; ++king_x)
00093   {
00094     for (int king_y=1; king_y<=9; ++king_y)
00095     {
00096       const Square king(king_x, king_y);
00097       for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p)
00098       {
00099         const Ptype ptype = static_cast<Ptype>(p);
00100         assert(isPiece(ptype));
00101         const Ptype basic_type = unpromote(ptype);
00102 
00103         const int ptype_value
00104           = Ptype_Eval_Table.value(newPtypeO(BLACK,ptype));
00105         // 持駒
00106         const int stand_bonus
00107           = (isMajorBasic(basic_type) 
00108              ? Ptype_Eval_Table.value(newPtypeO(BLACK,PAWN)) 
00109              : 0);
00110         valueOf(king, BLACK, Square::STAND(), ptype) = ptype_value
00111           + stand_bonus;
00112         if (ptype == KNIGHT || ptype == LANCE)
00113         {
00114           adhoc_adjust(valueOf(king, BLACK, Square::STAND(), ptype), 0.85);
00115         }
00116         // 盤上
00117         if (basic_type == KING)
00118         {
00119           // 玉は入玉を考慮
00120           valueOf(king, BLACK, king, ptype) 
00121             = ptype_value + yss_king_bonus[9-king_y];
00122           continue;
00123         }
00124               
00125         for (int defense_x=1; defense_x<=9; ++defense_x)
00126         {
00127           const bool near_edge 
00128             = (((defense_x < 3) && (defense_x < king_x))
00129                || ((defense_x > 7) && (defense_x > king_x)));
00130           const int relative_x = abs(king_x - defense_x);
00131           for (int defense_y=1; defense_y<=9; ++defense_y)
00132           {
00133             const Square defender(defense_x, defense_y);
00134             // 馬以外の大駒は0.9
00135             if (isMajorBasic(basic_type) && ptype != PBISHOP)
00136             {
00137               int black_bonus;
00138               // 入玉後の大駒は大事
00139               if (king_y < 4)
00140                 black_bonus = 105;
00141               else if (king_y == 4)
00142                 black_bonus = 100;
00143               // 1段目と2段目の玉に対する2段目の飛車は 0.95 あげる
00144               else if (basic_type == ROOK && defense_y == 8 && king_y >= 8)
00145                 black_bonus = 95;
00146               else
00147                 black_bonus = 90;
00148 
00149               valueOf(king, BLACK, defender, ptype) =
00150                 multiply(ptype_value, black_bonus);
00151               continue;
00152             }
00153             int relative_y_black_king = king_y - defense_y;
00154             if (ptype == KNIGHT || ptype == LANCE)
00155             {
00156               // 桂香は一段遠くから評価
00157               relative_y_black_king++;
00158             }
00159             else if (ptype == PAWN)
00160             {
00161               // 歩は玉の真上の段とその上の段のボーナスを交換する
00162               if (relative_y_black_king == 1)
00163               {
00164                 relative_y_black_king = 2;
00165               }
00166               else if (relative_y_black_king == 2)
00167               {
00168                 relative_y_black_king = 1;
00169               }
00170             }
00171 
00172             int bonus_black_king
00173               = yss_bonus[relative_x + (-relative_y_black_king+9)*9];
00174             // 端の方にはボーナスをあげない (自玉の近くの端歩以外
00175             if (near_edge || ptype == LANCE)
00176             {
00177               if (!(ptype == PAWN &&
00178                     (defense_x == 1 || defense_x == 9) &&
00179                     defense_y < king_y))
00180                 bonus_black_king = std::min(100, bonus_black_king);
00181             }
00182             if (ptype == KNIGHT)
00183             {
00184               if ((defense_x == 2 || defense_x == 8) &&
00185                   (defense_y == 1 || defense_y == 9))
00186               {
00187               }
00188               else
00189               {
00190                 bonus_black_king = std::min(100, bonus_black_king);
00191               }
00192             }
00193 
00194             int black_defense =  multiply(ptype_value,bonus_black_king);
00195             const bool near_center 
00196               = abs(defense_x-king_x)==1 &&
00197               (((king_x < 3) && (defense_x > king_x))
00198                || ((king_x > 7) && (defense_x < king_x)));
00199             if(defense_x==king_x || near_center){
00200               if(defense_y==king_y-1){
00201                 if(king_y==9 && (king_x==1 || king_x==9))
00202                   black_defense+=600;
00203                 else if(defense_x!=king_x && king_y==8 && (king_x==2 || king_x==8))
00204                   black_defense+=200;
00205                 else
00206                   black_defense+=400;
00207               }
00208             }
00209             valueOf(king, BLACK, defender, ptype) = black_defense;
00210           }
00211         }
00212       }
00213     }
00214   }
00215   // 1つしか動けない香は歩と同じ点数に
00216   for (int king_x=1; king_x<=9; ++king_x)
00217   {
00218     for (int king_y=1; king_y<=9; ++king_y)
00219     {
00220       const Square king(king_x, king_y);
00221       for (int x=1; x<=9; ++x)
00222       {
00223         const Square b(x,2);
00224         valueOf(king, BLACK, b, LANCE) = valueOf(king, BLACK, b, PAWN);
00225         adhoc_adjust(valueOf(king, BLACK, Square(x, 1), GOLD), 0.5);
00226         adhoc_adjust(valueOf(king, BLACK, Square(x, 1), SILVER), 0.5);
00227         adhoc_adjust(valueOf(king, BLACK, Square(x, 1), PSILVER), 0.5);
00228       }
00229 
00230       if (king_x < 6)
00231       {
00232         valueOf(king, BLACK, Square(9, 9), LANCE) = 0;
00233         valueOf(king, BLACK, Square(9, 8), LANCE) = 0;
00234         valueOf(king, BLACK, Square(9, 7), LANCE) = 0;
00235         valueOf(king, BLACK, Square(8, 9), KNIGHT) = 0;
00236 
00237         valueOf(king, BLACK, Square(9, 1), GOLD) = 0;
00238         valueOf(king, BLACK, Square(9, 1), SILVER) = 0;
00239         valueOf(king, BLACK, Square(9, 1), PSILVER) = 0;
00240         valueOf(king, BLACK, Square(8, 1), GOLD) = 0;
00241         valueOf(king, BLACK, Square(8, 1), SILVER) = 0;
00242         valueOf(king, BLACK, Square(8, 1), PSILVER) = 0;
00243       }
00244 
00245       if (king_x > 4)
00246       {
00247         valueOf(king, BLACK, Square(1, 9), LANCE) = 0;
00248         valueOf(king, BLACK, Square(1, 8), LANCE) = 0;
00249         valueOf(king, BLACK, Square(1, 7), LANCE) = 0;
00250         valueOf(king, BLACK, Square(2, 9), KNIGHT) = 0;
00251 
00252         valueOf(king, BLACK, Square(1, 1), GOLD) = 0;
00253         valueOf(king, BLACK, Square(1, 1), PSILVER) = 0;
00254         valueOf(king, BLACK, Square(1, 1), SILVER) = 0;
00255         valueOf(king, BLACK, Square(2, 1), GOLD) = 0;
00256         valueOf(king, BLACK, Square(2, 1), SILVER) = 0;
00257         valueOf(king, BLACK, Square(2, 1), PSILVER) = 0;
00258       }
00259     }
00260   }
00261 
00262   adhoc_adjust(valueOf(Square(1,1), BLACK, Square::STAND(), BISHOP), 0.95);
00263   adhoc_adjust(valueOf(Square(9,1), BLACK, Square::STAND(), BISHOP), 0.95);
00264 
00265   // BLACK/WHITE 反転
00266   for (int king_x=1; king_x<=9; ++king_x) {
00267     for (int king_y=1; king_y<=9; ++king_y) {
00268       const Square king_b(king_x, king_y);
00269       const Square king_w = king_b.rotate180();
00270       
00271       for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p) {
00272         const Ptype ptype = static_cast<Ptype>(p);
00273         assert(isPiece(ptype));
00274 
00275         // 持駒
00276         valueOf(king_w, WHITE, Square::STAND(), ptype)
00277           = - valueOf(king_b, BLACK, Square::STAND(), ptype);
00278 
00279         // 盤上
00280         for (int defense_x=1; defense_x<=9; ++defense_x) {
00281           for (int defense_y=1; defense_y<=9; ++defense_y) {
00282             const Square defense_b(defense_x, defense_y); // blackへのblackの防御
00283             const Square defense_w = defense_b.rotate180();
00284 
00285             valueOf(king_w, WHITE, defense_w, ptype)
00286               = - valueOf(king_b, BLACK, defense_b, ptype);
00287           }
00288         }
00289       }
00290     }
00291   }
00292 }
00293 // ;;; Local Variables:
00294 // ;;; mode:c++
00295 // ;;; c-basic-offset:2
00296 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines