00001
00004 #include "osl/eval/endgame/defenseKing.h"
00005 #include "osl/eval/pieceEval.h"
00006 #include "osl/misc/carray.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 namespace osl
00031 {
00032 namespace
00033 {
00034 const CArray<int,19*9> yss_bonus = {{
00035
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
00071
00072
00073 if (bonus > 100)
00074 bonus = (bonus - 100)/3 + 100;
00075
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 }
00083 }
00084
00085
00086
00087 osl::eval::endgame::DefenseKing::
00088 Table::Table()
00089 {
00090
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 Position 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, Position::STAND(), ptype) = ptype_value
00111 + stand_bonus;
00112 if (ptype == KNIGHT || ptype == LANCE)
00113 {
00114 adhoc_adjust(valueOf(king, BLACK, Position::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 Position defender(defense_x, defense_y);
00134
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
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
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 Position king(king_x, king_y);
00221 for (int x=1; x<=9; ++x)
00222 {
00223 const Position b(x,2);
00224 valueOf(king, BLACK, b, LANCE) = valueOf(king, BLACK, b, PAWN);
00225 adhoc_adjust(valueOf(king, BLACK, Position(x, 1), GOLD), 0.5);
00226 adhoc_adjust(valueOf(king, BLACK, Position(x, 1), SILVER), 0.5);
00227 adhoc_adjust(valueOf(king, BLACK, Position(x, 1), PSILVER), 0.5);
00228 }
00229
00230 if (king_x < 6)
00231 {
00232 valueOf(king, BLACK, Position(9, 9), LANCE) = 0;
00233 valueOf(king, BLACK, Position(9, 8), LANCE) = 0;
00234 valueOf(king, BLACK, Position(9, 7), LANCE) = 0;
00235 valueOf(king, BLACK, Position(8, 9), KNIGHT) = 0;
00236
00237 valueOf(king, BLACK, Position(9, 1), GOLD) = 0;
00238 valueOf(king, BLACK, Position(9, 1), SILVER) = 0;
00239 valueOf(king, BLACK, Position(9, 1), PSILVER) = 0;
00240 valueOf(king, BLACK, Position(8, 1), GOLD) = 0;
00241 valueOf(king, BLACK, Position(8, 1), SILVER) = 0;
00242 valueOf(king, BLACK, Position(8, 1), PSILVER) = 0;
00243 }
00244
00245 if (king_x > 4)
00246 {
00247 valueOf(king, BLACK, Position(1, 9), LANCE) = 0;
00248 valueOf(king, BLACK, Position(1, 8), LANCE) = 0;
00249 valueOf(king, BLACK, Position(1, 7), LANCE) = 0;
00250 valueOf(king, BLACK, Position(2, 9), KNIGHT) = 0;
00251
00252 valueOf(king, BLACK, Position(1, 1), GOLD) = 0;
00253 valueOf(king, BLACK, Position(1, 1), PSILVER) = 0;
00254 valueOf(king, BLACK, Position(1, 1), SILVER) = 0;
00255 valueOf(king, BLACK, Position(2, 1), GOLD) = 0;
00256 valueOf(king, BLACK, Position(2, 1), SILVER) = 0;
00257 valueOf(king, BLACK, Position(2, 1), PSILVER) = 0;
00258 }
00259 }
00260 }
00261
00262 adhoc_adjust(valueOf(Position(1,1), BLACK, Position::STAND(), BISHOP), 0.95);
00263 adhoc_adjust(valueOf(Position(9,1), BLACK, Position::STAND(), BISHOP), 0.95);
00264
00265
00266 for (int king_x=1; king_x<=9; ++king_x) {
00267 for (int king_y=1; king_y<=9; ++king_y) {
00268 const Position king_b(king_x, king_y);
00269 const Position 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, Position::STAND(), ptype)
00277 = - valueOf(king_b, BLACK, Position::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 Position defense_b(defense_x, defense_y);
00283 const Position 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
00294
00295
00296