00001
00004 #include "osl/eval/endgame/attackKing.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
00031
00032 namespace osl
00033 {
00034 namespace
00035 {
00036 const CArray<int,19*9> yss_bonus = {{
00037
00038 50, 50, 50, 50, 50, 50, 0, 0, 0,
00039 50, 50, 50, 50, 50, 50, 0, 0, 0,
00040 50, 50, 50, 50, 50, 50, 0, 0, 0,
00041 62, 60, 58, 52, 50, 50, 0, 0, 0,
00042 80, 78, 72, 67, 55, 51, 0, 0, 0,
00043 100, 99, 95, 87, 78, 69, 0, 0, 0,
00044 140, 130, 110, 100, 95, 75, 0, 0, 0,
00045 170, 160, 142, 114, 98, 80, 0, 0, 0,
00046 170, 165, 150, 121, 94, 78, 0, 0, 0,
00047 170, 145, 137, 115, 91, 75, 0, 0, 0,
00048 132, 132, 129, 102, 84, 71, 0, 0, 0,
00049 100, 97, 95, 85, 70, 62, 0, 0, 0,
00050 90, 85, 80, 68, 60, 53, 0, 0, 0,
00051 70, 66, 62, 55, 52, 50, 0, 0, 0,
00052 54, 53, 51, 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 50, 50, 50, 50, 50, 50, 0, 0, 0,
00056 50, 50, 50, 50, 50, 50, 0, 0, 0,
00057 }};
00058 inline int toEven(int value)
00059 {
00060 if (value % 2 == 0)
00061 return value;
00062 if (value > 0)
00063 return value - 1;
00064 return value + 1;
00065 }
00066 inline int multiply(int value, int bonus)
00067 {
00068
00069 return toEven(value * bonus / 120);
00070 }
00071 inline void adhoc_adjust(int& value, double scale)
00072 {
00073 value = toEven(static_cast<int>(value * scale));
00074 }
00075 }
00076 }
00077
00078 void osl::eval::endgame::AttackKing::
00079 Table::adhoc_edge_king_1(const Player player,
00080 const Position king,
00081 const Position attack)
00082 {
00083 for (int ptype = PPAWN; ptype <= ROOK; ptype++)
00084 {
00085 if (ptype != KING)
00086 {
00087 adhoc_adjust(valueOf(king, player, attack,
00088 static_cast<osl::Ptype>(ptype)), 1.25);
00089 }
00090 }
00091 }
00092
00093 void osl::eval::endgame::AttackKing::
00094 Table::adhoc_edge_king_2(const Player player,
00095 const Position king,
00096 const Position attack)
00097 {
00098 adhoc_adjust(valueOf(king, player, attack,
00099 GOLD), 1.25);
00100 adhoc_adjust(valueOf(king, player, attack,
00101 SILVER), 1.25);
00102 for (int ptype = PPAWN; ptype <= PSILVER; ptype++)
00103 {
00104 adhoc_adjust(valueOf(king, player, attack,
00105 static_cast<osl::Ptype>(ptype)), 1.25);
00106 }
00107 }
00108
00109 osl::eval::endgame::AttackKing::
00110 Table::Table()
00111 {
00112
00113 data.fill(0);
00114 for (int king_x=1; king_x<=9; ++king_x)
00115 {
00116 for (int king_y=1; king_y<=9; ++king_y)
00117 {
00118 const Position king(king_x, king_y);
00119 for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p)
00120 {
00121 const Ptype ptype = static_cast<Ptype>(p);
00122 assert(isPiece(ptype));
00123 const Ptype basic_type = unpromote(ptype);
00124
00125 const int ptype_value
00126 = Ptype_Eval_Table.value(newPtypeO(BLACK,ptype));
00127
00128 const int stand_bonus
00129 = (isMajorBasic(basic_type)
00130 ? Ptype_Eval_Table.value(newPtypeO(BLACK,PAWN))
00131 : 0);
00132 valueOf(king, WHITE, Position::STAND(), ptype) = +ptype_value
00133 + stand_bonus;
00134 if (ptype == KNIGHT || ptype == LANCE)
00135 adhoc_adjust(valueOf(king, WHITE, Position::STAND(), ptype), 0.85);
00136 if (ptype == GOLD || ptype == SILVER)
00137 adhoc_adjust(valueOf(king, WHITE, Position::STAND(), ptype), 1.1);
00138
00139
00140 for (int attack_x=1; attack_x<=9; ++attack_x)
00141 {
00142 const int relative_x = abs(king_x - attack_x);
00143 for (int attack_y=1; attack_y<=9; ++attack_y)
00144 {
00145 const Position attacker(attack_x, attack_y);
00146 if (basic_type == KING)
00147 {
00148
00149 valueOf(king, WHITE, attacker, ptype) = ptype_value;
00150 continue;
00151 }
00152
00153 const int relative_y_white_king
00154 = (((ptype == KNIGHT)||(ptype == LANCE))
00155 ? attack_y - king_y - 1
00156 : attack_y - king_y);
00157
00158 const int bonus_white_king
00159 = yss_bonus[relative_x + (-relative_y_white_king+9)*9];
00160
00161 const int black_attack = multiply(ptype_value,bonus_white_king);
00162
00163 if (isMajorBasic(basic_type))
00164 {
00165
00166 const int relative_y = abs(king_y - attack_y);
00167 const int diff1 = king_x + king_y - (attack_x + attack_y);
00168 const int diff2 = king_x - king_y - (attack_x - attack_y);
00169
00170 if ((basic_type == ROOK &&
00171 relative_y <= 1) ||
00172 (basic_type == BISHOP &&
00173 ((-1 <= diff1 && diff1 <= 1) ||
00174 (-1 <= diff2 && diff2 <= 1))))
00175 {
00176 valueOf(king, WHITE, attacker, ptype)
00177 = EvalTraits<BLACK>::max(ptype_value, black_attack);
00178
00179 if (relative_y == 0)
00180 {
00181 adhoc_adjust(valueOf(king, WHITE, attacker, ptype),
00182 0.98);
00183 }
00184 }
00185 else
00186 {
00187
00188 valueOf(king, WHITE, attacker, ptype)
00189 = multiply(ptype_value, 90);
00190 }
00191 continue;
00192 }
00193
00194 if ((ptype == PAWN && attack_y >= 5) ||
00195 (ptype == KNIGHT && attack_y >= 6))
00196 {
00197 int new_black_attack = black_attack;
00198 adhoc_adjust(new_black_attack, 0.95);
00199 valueOf(king, WHITE, attacker, ptype) = new_black_attack;
00200 }
00201 else
00202 valueOf(king, WHITE, attacker, ptype) = black_attack;
00203 }
00204 }
00205 }
00206 }
00207 }
00208 for (int king_x=1; king_x<=9; ++king_x)
00209 {
00210 for (int king_y=1; king_y<=9; ++king_y)
00211 {
00212 const Position king(king_x, king_y);
00213
00214 for (int x=1; x<=9; ++x)
00215 {
00216 const Position b(x,2);
00217 valueOf(king, WHITE, b, LANCE) = valueOf(king, WHITE, b, PAWN);
00218 }
00219 if (king_y <= 7)
00220 {
00221 adhoc_adjust(valueOf(king, WHITE, Position(king_x, king_y + 2), PAWN),
00222 1.25);
00223 }
00224
00225 for (int x=1; x<=9; ++x)
00226 {
00227 const Position b(x,1);
00228 if (x <= 2 || x >= 8)
00229 {
00230 adhoc_adjust(valueOf(king, WHITE, b, GOLD), 0.25);
00231 adhoc_adjust(valueOf(king, WHITE, b, PSILVER), 0.25);
00232 }
00233 else
00234 {
00235 adhoc_adjust(valueOf(king, WHITE, b, GOLD), 0.5);
00236 adhoc_adjust(valueOf(king, WHITE, b, PSILVER), 0.5);
00237 }
00238 adhoc_adjust(valueOf(king, WHITE, b, PKNIGHT), 0.5);
00239 adhoc_adjust(valueOf(king, WHITE, b, PLANCE), 0.5);
00240 adhoc_adjust(valueOf(king, WHITE, b, PPAWN), 0.5);
00241 }
00242
00243 if (king_y == 1)
00244 {
00245 for (int x = 1; x <= 9; ++x) {
00246 const Position three(x, 3);
00247 for (int ptype = PPAWN; ptype <= ROOK; ptype++)
00248 {
00249 if (ptype != KING && ptype != ROOK && ptype != PROOK)
00250 adhoc_adjust(valueOf(king, WHITE, three,
00251 static_cast<osl::Ptype>(ptype)), 1.25);
00252 }
00253 }
00254 }
00255 if (king_y <= 2)
00256 {
00257 for (int x = std::max(king_x - 1, 2);
00258 x <= std::min(king_x + 1, 8); x++)
00259 {
00260 adhoc_adjust(valueOf(king, WHITE, Position(x, 4), PAWN),
00261 1.25);
00262 }
00263 }
00264
00265 if (king_x == 1 || king_x == 9)
00266 {
00267 int next = king_x == 1 ? 2 : 8;
00268 adhoc_edge_king_1(WHITE, king, Position(next, king_y));
00269 if (king_y < 9)
00270 {
00271 adhoc_edge_king_1(WHITE, king, Position(next, king_y + 1));
00272 }
00273 if (king_y < 8)
00274 {
00275
00276 adhoc_edge_king_1(WHITE, king, Position(next, king_y + 2));
00277 }
00278 }
00279 if (king_x < 6)
00280 {
00281 valueOf(king, WHITE, Position(9, 9), LANCE) = 0;
00282 valueOf(king, WHITE, Position(9, 8), LANCE) = 0;
00283 valueOf(king, WHITE, Position(9, 7), LANCE) = 0;
00284 valueOf(king, WHITE, Position(8, 9), KNIGHT) = 0;
00285
00286 valueOf(king, WHITE, Position(9, 1), GOLD) = 0;
00287 valueOf(king, WHITE, Position(9, 1), SILVER) = 0;
00288 valueOf(king, WHITE, Position(9, 1), PSILVER) = 0;
00289 valueOf(king, WHITE, Position(8, 1), GOLD) = 0;
00290 valueOf(king, WHITE, Position(8, 1), SILVER) = 0;
00291 valueOf(king, WHITE, Position(8, 1), PSILVER) = 0;
00292 }
00293
00294 if (king_x > 4)
00295 {
00296 valueOf(king, WHITE, Position(1, 9), LANCE) = 0;
00297 valueOf(king, WHITE, Position(1, 8), LANCE) = 0;
00298 valueOf(king, WHITE, Position(1, 7), LANCE) = 0;
00299 valueOf(king, WHITE, Position(2, 9), KNIGHT) = 0;
00300
00301 valueOf(king, WHITE, Position(1, 1), GOLD) = 0;
00302 valueOf(king, WHITE, Position(1, 1), PSILVER) = 0;
00303 valueOf(king, WHITE, Position(1, 1), SILVER) = 0;
00304 valueOf(king, WHITE, Position(2, 1), GOLD) = 0;
00305 valueOf(king, WHITE, Position(2, 1), SILVER) = 0;
00306 valueOf(king, WHITE, Position(2, 1), PSILVER) = 0;
00307 }
00308 }
00309 }
00310 adhoc_edge_king_2(WHITE, Position(1, 1), Position(3, 2));
00311 adhoc_edge_king_2(WHITE, Position(1, 2), Position(3, 3));
00312 adhoc_edge_king_2(WHITE, Position(9, 1), Position(7, 2));
00313 adhoc_edge_king_2(WHITE, Position(9, 2), Position(7, 3));
00314
00315 for (int x = 1; x <= 9; x++)
00316 {
00317 for (int y = 1; y <= 9; y++)
00318 {
00319 adhoc_adjust(valueOf(Position(1,1), WHITE, Position(x, y), GOLD), 1.05);
00320 adhoc_adjust(valueOf(Position(9,1), WHITE, Position(x, y), GOLD), 1.05);
00321 adhoc_adjust(valueOf(Position(1,1), WHITE, Position(x, y), SILVER), 1.05);
00322 adhoc_adjust(valueOf(Position(9,1), WHITE, Position(x, y), SILVER), 1.05);
00323 adhoc_adjust(valueOf(Position(1,1), WHITE, Position(x, y), BISHOP), 0.95);
00324 adhoc_adjust(valueOf(Position(1,1), WHITE, Position(x, y), PBISHOP), 0.95);
00325 adhoc_adjust(valueOf(Position(9,1), WHITE, Position(x, y), BISHOP), 0.95);
00326 adhoc_adjust(valueOf(Position(9,1), WHITE, Position(x, y), PBISHOP), 0.95);
00327 for (int ptype = PPAWN; ptype <= PSILVER; ptype++)
00328 {
00329 adhoc_adjust(valueOf(Position(1, 1), WHITE, Position(x,y),
00330 static_cast<osl::Ptype>(ptype)), 1.05);
00331 adhoc_adjust(valueOf(Position(9, 1), WHITE, Position(x,y),
00332 static_cast<osl::Ptype>(ptype)), 1.05);
00333 }
00334 }
00335 }
00336 adhoc_adjust(valueOf(Position(1,1), WHITE, Position::STAND(), BISHOP), 0.95);
00337 adhoc_adjust(valueOf(Position(9,1), WHITE, Position::STAND(), BISHOP), 0.95);
00338
00339
00340 for (int king_x=1; king_x<=9; ++king_x) {
00341 for (int king_y=1; king_y<=9; ++king_y) {
00342 const Position king_b(king_x, king_y);
00343 const Position king_w = king_b.rotate180();
00344
00345 for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p) {
00346 const Ptype ptype = static_cast<Ptype>(p);
00347 assert(isPiece(ptype));
00348
00349
00350 valueOf(king_b, BLACK, Position::STAND(), ptype)
00351 = - valueOf(king_w, WHITE, Position::STAND(), ptype);
00352
00353
00354 for (int attack_x=1; attack_x<=9; ++attack_x) {
00355 for (int attack_y=1; attack_y<=9; ++attack_y) {
00356 const Position attack_b(attack_x, attack_y);
00357 const Position attack_w = attack_b.rotate180();
00358
00359 valueOf(king_b, BLACK, attack_w, ptype)
00360 = - valueOf(king_w, WHITE, attack_b, ptype);
00361 }
00362 }
00363 }
00364 }
00365 }
00366 }
00367
00368
00369
00370
00371