00001 #include "osl/eval/kingTable.h"
00002 using osl::MultiInt;
00003
00004 osl::CArray2d<MultiInt, osl::PTYPE_SIZE, 17 * 9> osl::eval::ml::KingPieceRelative::attack_table;
00005 osl::CArray2d<MultiInt, osl::PTYPE_SIZE, 17 * 9> osl::eval::ml::KingPieceRelative::defense_table;
00006
00007 void osl::eval::ml::
00008 KingPieceRelative::setUp(const Weights &weights, int stage)
00009 {
00010 for (int i = PTYPE_PIECE_MIN; i <= PTYPE_MAX; ++i)
00011 {
00012 for (int y = 0; y <= 16; ++y)
00013 {
00014 for (int x = 0; x <= 8; ++x)
00015 {
00016 const int distance = x * 17 + y;
00017 attack_table[i][distance][stage] =
00018 weights.value((i - PTYPE_PIECE_MIN) * 17 * 9 + distance);
00019 defense_table[i][distance][stage] =
00020 weights.value((i - PTYPE_PIECE_MIN) * 17 * 9 + distance + TABLE_DIM);
00021 }
00022 }
00023 }
00024 }
00025
00026 MultiInt osl::eval::ml::
00027 KingPieceRelative::eval(const NumEffectState &state)
00028 {
00029 MultiInt value;
00030 const Square b_king = state.kingSquare(BLACK);
00031 const Square w_king = state.kingSquare(WHITE);
00032 for (int i = 0; i < osl::Piece::SIZE; ++i)
00033 {
00034 const osl::Piece piece = state.pieceOf(i);
00035 if (!piece.isOnBoard())
00036 continue;
00037 const Ptype ptype = piece.ptype();
00038 const Square position = piece.square();
00039 if (piece.owner() == BLACK)
00040 {
00041 const int attack_index = index(state, BLACK,position, w_king);
00042 const int defense_index = index(state, BLACK,position, b_king);
00043 value += attack_table[ptype][attack_index];
00044 value += defense_table[ptype][defense_index];
00045 }
00046 else
00047 {
00048 const int attack_index = index(state, WHITE,position, b_king);
00049 const int defense_index = index(state, WHITE,position, w_king);
00050 value -= attack_table[ptype][attack_index];
00051 value -= defense_table[ptype][defense_index];
00052 }
00053 }
00054 return value;
00055 }
00056
00057 template<osl::Player P>
00058 MultiInt osl::eval::ml::
00059 KingPieceRelative::evalWithUpdate(const NumEffectState &state,
00060 Move moved, MultiInt const& last_value)
00061 {
00062 if (moved.isPass())
00063 return last_value;
00064
00065 if (moved.ptype() == osl::KING)
00066 {
00067 return eval(state);
00068 }
00069
00070 MultiInt value(last_value);
00071 if (!moved.isDrop())
00072 {
00073 const PtypeO ptypeO = moved.oldPtypeO();
00074 const int attack_index = index(state, ptypeO, moved.from(), false);
00075 const int defense_index = index(state,ptypeO, moved.from(), true);
00076 if (P == BLACK)
00077 {
00078 value -= attack_table[moved.oldPtype()][attack_index];
00079 value -= defense_table[moved.oldPtype()][defense_index];
00080 }
00081 else
00082 {
00083 value += attack_table[moved.oldPtype()][attack_index];
00084 value += defense_table[moved.oldPtype()][defense_index];
00085 }
00086 }
00087 {
00088 const int attack_index = index(state, moved.ptypeO(), moved.to(), false);
00089 const int defense_index = index(state, moved.ptypeO(), moved.to(), true);
00090 if (P == BLACK)
00091 {
00092 value += attack_table[moved.ptype()][attack_index];
00093 value += defense_table[moved.ptype()][defense_index];
00094 }
00095 else
00096 {
00097 value -= attack_table[moved.ptype()][attack_index];
00098 value -= defense_table[moved.ptype()][defense_index];
00099 }
00100 }
00101 const Ptype captured = moved.capturePtype();
00102 if (captured != PTYPE_EMPTY)
00103 {
00104 const PtypeO ptypeO = moved.capturePtypeO();
00105 const int attack_index = index(state, ptypeO, moved.to(), false);
00106 const int defense_index = index(state,ptypeO, moved.to(), true);
00107 if (P == BLACK)
00108 {
00109 value += attack_table[captured][attack_index];
00110 value += defense_table[captured][defense_index];
00111 }
00112 else
00113 {
00114 value -= attack_table[captured][attack_index];
00115 value -= defense_table[captured][defense_index];
00116 }
00117 }
00118 return value;
00119 }
00120
00121
00122 osl::CArray<MultiInt, osl::eval::ml::KingPieceRelativeNoSupport::ONE_DIM>
00123 osl::eval::ml::KingPieceRelativeNoSupport::table;
00124
00125 void osl::eval::ml::
00126 KingPieceRelativeNoSupport::setUp(const Weights &weights)
00127 {
00128 for (int i = 0; i < ONE_DIM; ++i)
00129 {
00130 for (int s=0; s<NStages; ++s)
00131 table[i][s] = weights.value(i + ONE_DIM*s);
00132 }
00133 }
00134
00135 template <int Sign> inline
00136 void osl::eval::ml::
00137 KingPieceRelativeNoSupport::adjust(int attack, int defense, MultiInt& out)
00138 {
00139 if(Sign>0)
00140 out += table[attack] + table[defense];
00141 else
00142 out -= table[attack] + table[defense];
00143 }
00144
00145 MultiInt osl::eval::ml::
00146 KingPieceRelativeNoSupport::eval(const NumEffectState &state)
00147 {
00148 MultiInt result;
00149 const CArray<Square, 2> kings = {
00150 state.kingSquare(BLACK),
00151 state.kingSquare(WHITE),
00152 };
00153 PieceMask black = (~state.effectedMask(BLACK)) & state.piecesOnBoard(BLACK);
00154 black.reset(KingTraits<BLACK>::index);
00155 while (black.any())
00156 {
00157 const Piece piece = state.pieceOf(black.takeOneBit());
00158 const int index_attack = index(BLACK, kings[WHITE],
00159 piece);
00160 const int index_defense = index(BLACK, kings[BLACK],
00161 piece) + ONE_DIM / 2;
00162 adjust<1>(index_attack, index_defense, result);
00163 }
00164 PieceMask white = (~state.effectedMask(WHITE)) & state.piecesOnBoard(WHITE);
00165 white.reset(KingTraits<WHITE>::index);
00166 while (white.any())
00167 {
00168 const Piece piece = state.pieceOf(white.takeOneBit());
00169 const int index_attack = index(WHITE, kings[BLACK],
00170 piece);
00171 const int index_defense = index(WHITE, kings[WHITE],
00172 piece) + ONE_DIM / 2;
00173 adjust<-1>(index_attack, index_defense, result);
00174 }
00175 return result;
00176 }
00177
00178 MultiInt osl::eval::ml::
00179 KingPieceRelativeNoSupport::evalWithUpdate(
00180 const NumEffectState &state,
00181 Move moved,
00182 const CArray<PieceMask, 2> &effected_mask,
00183 const MultiInt &last_values)
00184 {
00185 if (moved.ptype() == KING)
00186 return eval(state);
00187
00188
00189 const CArray<PieceMask, 2> new_mask = {{
00190 state.effectedMask(BLACK),
00191 state.effectedMask(WHITE)
00192 }};
00193 const CArray<Square, 2> kings = {{
00194 state.kingSquare<BLACK>(),
00195 state.kingSquare<WHITE>(),
00196 }};
00197
00198 MultiInt result(last_values);
00199 const Piece p = state.pieceAt(moved.to());
00200 if (!moved.isDrop())
00201 {
00202 if (!effected_mask[p.owner()].test(p.number()))
00203 {
00204 const int index_attack =
00205 index(p.owner(), kings[alt(p.owner())],
00206 moved.oldPtype(), moved.from());
00207 const int index_defense =
00208 index(p.owner(), kings[p.owner()], moved.oldPtype(),
00209 moved.from()) + ONE_DIM / 2;
00210 if (p.owner() == BLACK)
00211 adjust<-1>(index_attack, index_defense, result);
00212 else
00213 adjust<1>(index_attack, index_defense, result);
00214 }
00215 }
00216 const Ptype captured = moved.capturePtype();
00217 if (captured != PTYPE_EMPTY)
00218 {
00219 PieceMask captured_mask =
00220 effected_mask[moved.player()] & (~state.piecesOnBoard(BLACK)) &
00221 (~state.piecesOnBoard(WHITE));
00222
00223 if (!effected_mask[alt(moved.player())].test(captured_mask.takeOneBit()))
00224 {
00225 const int index_attack =
00226 index(alt(p.owner()), kings[p.owner()],
00227 captured, moved.to());
00228 const int index_defense =
00229 index(alt(p.owner()), kings[alt(p.owner())], captured,
00230 moved.to()) + ONE_DIM / 2;
00231 if (p.owner() == BLACK)
00232 adjust<1>(index_attack, index_defense, result);
00233 else
00234 adjust<-1>(index_attack, index_defense, result);
00235 }
00236 }
00237 if (!new_mask[p.owner()].test(p.number()))
00238 {
00239 const int index_attack =
00240 index(p.owner(), kings[alt(p.owner())],
00241 moved.ptype(), moved.to());
00242 const int index_defense =
00243 index(p.owner(), kings[p.owner()], moved.ptype(),
00244 moved.to()) + ONE_DIM / 2;
00245 if (p.owner() == BLACK)
00246 adjust<1>(index_attack, index_defense, result);
00247 else
00248 adjust<-1>(index_attack, index_defense, result);
00249 }
00250 PieceMask onboard_black = state.piecesOnBoard(BLACK);
00251 onboard_black.reset(KingTraits<BLACK>::index);
00252
00253 PieceMask black_old = (~effected_mask[0]) & new_mask[0] & onboard_black;
00254 black_old.reset(p.number());
00255 while (black_old.any())
00256 {
00257 const Piece piece = state.pieceOf(black_old.takeOneBit());
00258 const int index_attack =
00259 index(BLACK, kings[WHITE], piece);
00260 const int index_defense =
00261 index(BLACK, kings[BLACK], piece) + ONE_DIM / 2;
00262 adjust<-1>(index_attack, index_defense, result);
00263 }
00264
00265 PieceMask black_new = effected_mask[0] & (~new_mask[0]) & onboard_black;
00266 black_new.reset(p.number());
00267 while (black_new.any())
00268 {
00269 const Piece piece = state.pieceOf(black_new.takeOneBit());
00270 const int index_attack =
00271 index(BLACK, kings[WHITE], piece);
00272 const int index_defense =
00273 index(BLACK, kings[BLACK], piece) + ONE_DIM / 2;
00274 adjust<1>(index_attack, index_defense, result);
00275 }
00276
00277
00278 PieceMask onboard_white = state.piecesOnBoard(WHITE);
00279 onboard_white.reset(KingTraits<WHITE>::index);
00280 PieceMask white_old = (~effected_mask[1]) & new_mask[1] & onboard_white;
00281 white_old.reset(p.number());
00282 while (white_old.any())
00283 {
00284 const Piece piece = state.pieceOf(white_old.takeOneBit());
00285 const int index_attack =
00286 index(WHITE, kings[BLACK], piece);
00287 const int index_defense =
00288 index(WHITE, kings[WHITE], piece) + ONE_DIM / 2;
00289 adjust<1>(index_attack, index_defense, result);
00290 }
00291
00292 PieceMask white_new = effected_mask[1] & (~new_mask[1]) & onboard_white;
00293 white_new.reset(p.number());
00294 while (white_new.any())
00295 {
00296 const Piece piece = state.pieceOf(white_new.takeOneBit());
00297 const int index_attack =
00298 index(WHITE, kings[BLACK], piece);
00299 const int index_defense =
00300 index(WHITE, kings[WHITE], piece) + ONE_DIM / 2;
00301 adjust<-1>(index_attack, index_defense, result);
00302 }
00303
00304 return result;
00305 }
00306
00307
00308 osl::CArray<MultiInt, 2592> osl::eval::ml::PtypeYY::table;
00309
00310 void osl::eval::ml::PtypeYY::setUp(const Weights &weights)
00311 {
00312 for (int i = 0; i < ONE_DIM; ++i)
00313 {
00314 for (int s=0; s<NStages; ++s)
00315 table[i][s] = weights.value(i + ONE_DIM*s);
00316 }
00317 }
00318
00319 template <int Sign>
00320 inline
00321 void osl::eval::ml::
00322 PtypeYY::adjust(int black, int white, MultiInt &out)
00323 {
00324 if(Sign>0)
00325 out += table[black] - table[white];
00326 else
00327 out -= table[black] - table[white];
00328 }
00329
00330 MultiInt osl::eval::ml::
00331 PtypeYY::eval(const NumEffectState &state)
00332 {
00333 MultiInt result;
00334 const CArray<Square,2> kings = {{
00335 state.kingSquare(BLACK),
00336 state.kingSquare(WHITE),
00337 }};
00338 for (int i = 0; i < Piece::SIZE; ++i)
00339 {
00340 const Piece p = state.pieceOf(i);
00341 if (!p.isOnBoard())
00342 continue;
00343 const int black_index = index<BLACK>(p, kings[BLACK]);
00344 const int white_index = index<WHITE>(p, kings[WHITE]);
00345 adjust<1>(black_index, white_index, result);
00346 }
00347
00348 return result;
00349 }
00350
00351 MultiInt osl::eval::ml::PtypeYY::evalWithUpdate(
00352 const NumEffectState& state,
00353 Move moved,
00354 const MultiInt &last_values)
00355 {
00356 if (moved.ptype() == KING && moved.to().y() != moved.from().y())
00357 {
00358 return eval(state);
00359 }
00360 MultiInt result(last_values);
00361 if (!moved.isDrop())
00362 {
00363 const int index_black = index<BLACK>(moved.oldPtypeO(), moved.from(),
00364 state.kingSquare<BLACK>());
00365 const int index_white = index<WHITE>(moved.oldPtypeO(), moved.from(),
00366 state.kingSquare<WHITE>());
00367 adjust<-1>(index_black, index_white, result);
00368 }
00369 Ptype captured = moved.capturePtype();
00370 if (captured != PTYPE_EMPTY)
00371 {
00372 const PtypeO ptypeO = newPtypeO(alt(moved.player()), captured);
00373 const int index_black = index<BLACK>(ptypeO, moved.to(),
00374 state.kingSquare<BLACK>());
00375 const int index_white = index<WHITE>(ptypeO, moved.to(),
00376 state.kingSquare<WHITE>());
00377 adjust<-1>(index_black, index_white, result);
00378 }
00379
00380 {
00381 const int index_black = index<BLACK>(moved.ptypeO(), moved.to(),
00382 state.kingSquare<BLACK>());
00383 const int index_white = index<WHITE>(moved.ptypeO(), moved.to(),
00384 state.kingSquare<WHITE>());
00385 adjust<1>(index_black, index_white, result);
00386 }
00387 return result;
00388 }
00389
00390
00391 osl::CArray<int, osl::eval::ml::King25Effect::DIM>
00392 osl::eval::ml::King25Effect::table;
00393
00394 void osl::eval::ml::
00395 King25Effect::setUp(const Weights &weights)
00396 {
00397 table.fill(0);
00398 for (size_t i = 0; i < weights.dimension(); ++i)
00399 {
00400 table[i] = weights.value(i);
00401 }
00402 }
00403
00404 void osl::eval::ml::King25Effect::countEffectAndPieces(
00405 const NumEffectState &state,
00406 const osl::Player attack,
00407 int &effect,
00408 int &piece)
00409 {
00410 const Square king = state.kingSquare(alt(attack));
00411 const int min_x = std::max(1, king.x() - 2);
00412 const int max_x = std::min(9, king.x() + 2);
00413 const int min_y = std::max(1, king.y() - 2);
00414 const int max_y = std::min(9, king.y() + 2);
00415
00416 PieceMask mask;
00417 int count = 0;
00418 for (int y = min_y; y <= max_y; ++y)
00419 {
00420 for (int x = min_x; x <= max_x; ++x)
00421 {
00422 const Square target(x, y);
00423 count += state.countEffect(attack, target);
00424 mask |= state.effectSetAt(target);
00425 }
00426 }
00427 effect = std::min(255, count);
00428 mask = mask & state.piecesOnBoard(attack);
00429 piece = std::min(16, mask.countBit());
00430 }
00431
00432 int osl::eval::ml::King25Effect::index(int effect, int piece_count)
00433 {
00434 return effect + 128 * piece_count;
00435 }
00436
00437 int osl::eval::ml::King25Effect::eval(
00438 const NumEffectState &state)
00439 {
00440 int black_effect, black_piece, white_effect, white_piece;
00441 countEffectAndPieces(state, osl::BLACK, black_effect, black_piece);
00442 countEffectAndPieces(state, osl::WHITE, white_effect, white_piece);
00443 return table[index(black_effect, black_piece)] - table[index(white_effect, white_piece)];
00444 }
00445
00446
00447 osl::CArray<MultiInt, osl::eval::ml::King25Effect2::ONE_DIM>
00448 osl::eval::ml::King25Effect2::table;
00449 osl::CArray<MultiInt, osl::eval::ml::King25EffectY2::ONE_DIM>
00450 osl::eval::ml::King25EffectY2::table;
00451
00452 void osl::eval::ml::King25Effect2::setUp(const Weights &weights)
00453 {
00454 for (int i = 0; i < ONE_DIM; ++i)
00455 {
00456 for (int s=0; s<NStages; ++s)
00457 table[i][s] = weights.value(i + ONE_DIM*s);
00458 }
00459 }
00460
00461 void osl::eval::ml::King25EffectY2::setUp(const Weights &weights)
00462 {
00463 for (int i = 0; i < ONE_DIM; ++i)
00464 {
00465 for (int s=0; s<NStages; ++s)
00466 table[i][s] = weights.value(i + ONE_DIM*s);
00467 }
00468 }
00469
00470
00471 osl::CArray<MultiInt, osl::eval::ml::King25EffectSupported::ONE_DIM>
00472 osl::eval::ml::King25EffectSupported::table;
00473 osl::CArray<MultiInt, osl::eval::ml::King25EffectSupportedY::ONE_DIM>
00474 osl::eval::ml::King25EffectSupportedY::table;
00475
00476 void osl::eval::ml::King25EffectSupported::setUp(const Weights &weights)
00477 {
00478 for (int i = 0; i < ONE_DIM; ++i)
00479 {
00480 for (int s=0; s<NStages; ++s)
00481 table[i][s] = weights.value(i + ONE_DIM*s);
00482 }
00483 }
00484
00485 void osl::eval::ml::King25EffectSupportedY::setUp(const Weights &weights)
00486 {
00487 for (int i = 0; i < ONE_DIM; ++i)
00488 {
00489 for (int s=0; s<NStages; ++s)
00490 table[i][s] = weights.value(i + ONE_DIM*s);
00491 }
00492 }
00493
00494
00495 osl::CArray<int, osl::eval::ml::King25EffectBoth::DIM/2>
00496 osl::eval::ml::King25EffectBoth::attack_table;
00497 osl::CArray<int, osl::eval::ml::King25EffectBoth::DIM/2>
00498 osl::eval::ml::King25EffectBoth::defense_table;
00499
00500 void osl::eval::ml::
00501 King25EffectBoth::setUp(const Weights &weights)
00502 {
00503 attack_table.fill(0);
00504 defense_table.fill(0);
00505 for (size_t i = 0; i < DIM/2; ++i)
00506 {
00507 attack_table[i] = weights.value(i);
00508 defense_table[i] = weights.value(i+DIM/2);
00509 }
00510 }
00511
00512 template <osl::Player Attack>
00513 void
00514 osl::eval::ml::King25EffectBoth::countEffectAndPiecesBoth(
00515 const NumEffectState &state,
00516 PieceMask& mask,
00517 PieceMask& supported_mask,
00518 int &attack_effect,
00519 int &attack_piece,
00520 int &defense_effect,
00521 int &defense_piece,
00522 int &attack_piece_supported,
00523 CArray<int, 5> &verticals,
00524 CArray<int, 5> &king_verticals)
00525 {
00526 king_verticals.fill(0);
00527 const Player Defense = alt(Attack);
00528 const Square king = state.kingSquare(Defense);
00529 const int min_x = std::max(1, king.x() - 2);
00530 const int max_x = std::min(9, king.x() + 2);
00531 const int min_y = std::max(1, king.y() - 2);
00532 const int max_y = std::min(9, king.y() + 2);
00533 int mask_all=(1<<5)-1;
00534 verticals.fill(mask_all);
00535 const int y_mask_base=(1 << (Defense == BLACK ? (min_y-king.y()) + 2 : -(max_y-king.y()) + 2));
00536 if(Defense==BLACK)
00537 mask_all ^= ((1<<(max_y-king.y()+3))-y_mask_base);
00538 else
00539 mask_all ^= ((1<<(king.y()-min_y+3))-y_mask_base);
00540 mask.resetAll();
00541 int attack_count = 0;
00542 int defense_count = 0;
00543 for (int x = min_x; x <= max_x; ++x)
00544 {
00545 int vertical_x=mask_all;
00546 int king_vertical_x = 0;
00547 if(Defense==BLACK){
00548 int y_mask=y_mask_base;
00549 for (int y = min_y; y <= max_y; ++y, y_mask+=y_mask)
00550 {
00551 const Square target(x, y);
00552 const int count = state.countEffect(Attack, target);
00553 defense_count += state.countEffect(alt(Attack), target);
00554 mask |= state.effectSetAt(target);
00555 if(count>0){
00556 attack_count += count;
00557 vertical_x |= y_mask;
00558 }
00559 const Piece piece = state.pieceAt(target);
00560 if (count == 0 &&
00561 (piece.isEmpty() || piece.owner() == Attack))
00562 {
00563 king_vertical_x |= y_mask;
00564 }
00565 }
00566 }
00567 else{
00568 int y_mask=y_mask_base;
00569 for (int y = max_y; y >= min_y; --y, y_mask+=y_mask)
00570 {
00571 const Square target(x, y);
00572 const int count = state.countEffect(Attack, target);
00573 defense_count += state.countEffect(alt(Attack), target);
00574 mask |= state.effectSetAt(target);
00575 if(count>0){
00576 attack_count += count;
00577 vertical_x |= y_mask;
00578 }
00579 const Piece piece = state.pieceAt(target);
00580 if (count == 0 &&
00581 (piece.isEmpty() || piece.owner() == Attack))
00582 {
00583 king_vertical_x |= y_mask;
00584 }
00585 }
00586 }
00587 const int x_diff = king.x() - x;
00588 verticals[(Defense == BLACK ? 2 - x_diff : 2 + x_diff)] = vertical_x;
00589 king_verticals[(Defense == BLACK ? 2 - x_diff : 2 + x_diff)] =
00590 king_vertical_x;
00591 }
00592 attack_effect = std::min(127, attack_count);
00593 defense_effect = std::min(127, defense_count);
00594 PieceMask attack_mask = mask & state.piecesOnBoard(Attack);
00595 attack_piece = std::min(16, attack_mask.countBit());
00596 PieceMask defense_mask = mask & state.piecesOnBoard(alt(Attack));
00597 defense_piece = std::min(16, defense_mask.countBit());
00598 supported_mask = attack_mask & state.effectedMask(Attack);
00599 attack_piece_supported = std::min(16, supported_mask.countBit());
00600 }
00601
00602
00603 osl::CArray<int, osl::eval::ml::King25EffectY::DIM/2>
00604 osl::eval::ml::King25EffectY::attack_table;
00605 osl::CArray<int, osl::eval::ml::King25EffectY::DIM/2>
00606 osl::eval::ml::King25EffectY::defense_table;
00607
00608 void osl::eval::ml::
00609 King25EffectY::setUp(const Weights &weights)
00610 {
00611 attack_table.fill(0);
00612 defense_table.fill(0);
00613 for (size_t i = 0; i < DIM/2; ++i)
00614 {
00615 attack_table[i] = weights.value(i);
00616 defense_table[i] = weights.value(i+DIM/2);
00617 }
00618 }
00619
00620
00621
00622 void osl::eval::ml::
00623 King25EmptySquareNoEffect::setUpBase(const Weights &weights, CArray<int, 15>& table)
00624 {
00625 table.fill(0);
00626 for (size_t i = 0; i < weights.dimension(); ++i)
00627 {
00628 table[i] = weights.value(i);
00629 }
00630 }
00631
00632 template <osl::Player defense>
00633 int osl::eval::ml::
00634 King25EmptySquareNoEffect::evalOne(const NumEffectState &state, const CArray<int, 15>& table)
00635 {
00636 int result = 0;
00637 const Piece king_piece = state.kingPiece<defense>();
00638 const Square king = king_piece.square();
00639 const int min_x = std::max(1, king.x() - 2);
00640 const int max_x = std::min(9, king.x() + 2);
00641 const int min_y = std::max(1, king.y() - 2);
00642 const int max_y = std::min(9, king.y() + 2);
00643
00644 PieceMask pieces=state.piecesOnBoard(defense);
00645 pieces.reset(KingTraits<defense>::index);
00646
00647 for (int x = min_x; x <= max_x; ++x)
00648 {
00649 for (int y = min_y; y <= max_y; ++y)
00650 {
00651 Square target(x, y);
00652 if (state.pieceAt(target).isEmpty()
00653 && !
00654 (pieces & state.effectSetAt(target)).any())
00655 {
00656 if (defense == BLACK)
00657 result += table[index(x - king.x(), y - king.y())];
00658 else
00659 result -= table[index(king.x() - x, king.y() - y)];
00660 }
00661 }
00662 }
00663 return result;
00664 }
00665
00666 template <osl::Player defense>
00667 std::pair<int,int> osl::eval::ml::
00668 King25EmptySquareNoEffect::evalOne(const NumEffectState &state,
00669 const CArray<int, 15>& opening, const CArray<int, 15>& ending)
00670 {
00671 int result_o = 0, result_e = 0;
00672 const Piece king_piece = state.kingPiece<defense>();
00673 const Square king = king_piece.square();
00674 const int min_x = std::max(1, king.x() - 2);
00675 const int max_x = std::min(9, king.x() + 2);
00676 const int min_y = std::max(1, king.y() - 2);
00677 const int max_y = std::min(9, king.y() + 2);
00678
00679 PieceMask pieces=state.piecesOnBoard(defense);
00680 pieces.reset(KingTraits<defense>::index);
00681
00682 for (int x = min_x; x <= max_x; ++x)
00683 {
00684 for (int y = min_y; y <= max_y; ++y)
00685 {
00686 Square target(x, y);
00687 if (state.pieceAt(target).isEmpty()
00688 && !
00689 (pieces & state.effectSetAt(target)).any())
00690 {
00691 if (defense == BLACK)
00692 {
00693 result_o += opening[index(x - king.x(), y - king.y())];
00694 result_e += ending[index(x - king.x(), y - king.y())];
00695 }
00696 else
00697 {
00698 result_o -= opening[index(king.x() - x, king.y() - y)];
00699 result_e -= ending[index(king.x() - x, king.y() - y)];
00700 }
00701 }
00702 }
00703 }
00704 return std::make_pair(result_o, result_e);
00705 }
00706
00707 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
00708 King25EmptySquareNoEffect::eval(const NumEffectState &state,
00709 const CArray<int, 15>& opening, const CArray<int, 15>& ending)
00710 {
00711 std::pair<int,int> b = evalOne<BLACK>(state, opening, ending);
00712 std::pair<int,int> w = evalOne<WHITE>(state, opening, ending);
00713 CArray<int,2> result_o = {{ b.first, w.first }};
00714 CArray<int,2> result_e = {{ b.second, w.second }};
00715 return std::make_pair(result_o, result_e);
00716 }
00717
00718 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
00719 King25EmptySquareNoEffect::evalWithUpdate(const NumEffectState &state, Move last_move,
00720 const CArray<int, 15>& opening, const CArray<int, 15>& ending,
00721 const CArray<int, 2>& last_opening_value,
00722 const CArray<int, 2>& last_ending_value)
00723 {
00724 BoardMask mb = state.changedEffects(BLACK), mw = state.changedEffects(WHITE);
00725 mb.set(Square(last_move.to())); mb.set(Square(last_move.from()));
00726 mw.set(Square(last_move.to())); mw.set(Square(last_move.from()));
00727 const Square kb = state.kingSquare<BLACK>(), kw = state.kingSquare<WHITE>();
00728 const bool update_black = mb.anyInRange(Board_Mask_Table5x5.mask(kb));
00729 const bool update_white = mw.anyInRange(Board_Mask_Table5x5.mask(kw));
00730 std::pair<int,int> b = update_black
00731 ? evalOne<BLACK>(state, opening, ending)
00732 : std::make_pair(last_opening_value[0], last_ending_value[0]);
00733 std::pair<int,int> w = update_white
00734 ? evalOne<WHITE>(state, opening, ending)
00735 : std::make_pair(last_opening_value[1], last_ending_value[1]);
00736 CArray<int,2> result_o = {{ b.first, w.first }};
00737 CArray<int,2> result_e = {{ b.second, w.second }};
00738 return std::make_pair(result_o, result_e);
00739 }
00740
00741
00742 osl::CArray<int, 15>
00743 osl::eval::ml::King25EmptySquareNoEffectOpening::table;
00744 osl::CArray<int, 15>
00745 osl::eval::ml::King25EmptySquareNoEffectEnding::table;
00746
00747 const osl::CArray<int,2> osl::eval::ml::
00748 King25EmptySquareNoEffectOpening::eval(const NumEffectState &state)
00749 {
00750 CArray<int, 2> result = {{ evalOne<BLACK>(state, table), evalOne<WHITE>(state, table) }};
00751 return result;
00752 }
00753
00754 const osl::CArray<int,2> osl::eval::ml::
00755 King25EmptySquareNoEffectEnding::eval(const NumEffectState &state)
00756 {
00757 CArray<int, 2> result = {{ evalOne<BLACK>(state, table), evalOne<WHITE>(state, table) }};
00758 return result;
00759 }
00760
00761
00762
00763 template <int Stage>
00764 osl::CArray<int, 5 * 3 * 8 * 3>
00765 osl::eval::ml::King25EffectEach<Stage>::table;
00766
00767 template <int Stage>
00768 void osl::eval::ml::
00769 King25EffectEach<Stage>::setUp(const Weights &weights)
00770 {
00771 for (size_t i = 0; i < weights.dimension(); ++i)
00772 {
00773 table[i] = weights.value(i);
00774 }
00775 }
00776
00777 template <int Stage>
00778 template <osl::Player Defense>
00779 osl::eval::ml::EffectState
00780 osl::eval::ml::King25EffectEach<Stage>::effectState(
00781 const NumEffectState &state,
00782 Square target)
00783 {
00784 if (!state.hasEffectAt(alt(Defense), target))
00785 {
00786 return static_cast<EffectState>(std::min(2, state.countEffect(Defense, target)));
00787 }
00788 const int diff = state.countEffect(Defense, target) -
00789 state.countEffect(alt(Defense), target);
00790 return static_cast<EffectState>(std::max(-2, std::min(2, diff)) + ATTACK_DIFF_0);
00791 }
00792
00793 template <int Stage>
00794 template <osl::Player Defense>
00795 int osl::eval::ml::King25EffectEach<Stage>::index(
00796 const NumEffectState &state, Square king,
00797 Square target)
00798 {
00799 const Piece piece = state.pieceAt(target);
00800
00801 const int rel_x = std::abs(king.x() - target.x());
00802
00803 const int rel_y = (target.y() - king.y()) * (Defense == BLACK ? 1 : -1);
00804 int piece_owner;
00805 if (piece.isEmpty())
00806 piece_owner = 0;
00807 else if (piece.owner() == Defense)
00808 piece_owner = 1;
00809 else
00810 piece_owner = 2;
00811
00812 int val = rel_y + 2 + rel_x * 5 +
00813 effectState<Defense>(state, target) * 5 * 3 +
00814 piece_owner * 5 * 3 * 8;
00815 return val;
00816 }
00817
00818 template <int Stage>
00819 template <osl::Player Defense>
00820 int osl::eval::ml::King25EffectEach<Stage>::evalOne(
00821 const NumEffectState &state)
00822 {
00823 int result = 0;
00824 const Square king = state.kingSquare<Defense>();
00825 const int min_x = std::max(1, king.x() - 2);
00826 const int max_x = std::min(9, king.x() + 2);
00827 const int min_y = std::max(1, king.y() - 2);
00828 const int max_y = std::min(9, king.y() + 2);
00829 for (int x = min_x; x <= max_x; ++x)
00830 {
00831 for (int y = min_y; y <= max_y; ++y)
00832 {
00833 Square target(x, y);
00834 result += table[index<Defense>(state, king, target)];
00835 }
00836 }
00837 if (Defense == BLACK)
00838 return result;
00839 else
00840 return -result;
00841 }
00842
00843 template <int Stage>
00844 int osl::eval::ml::
00845 King25EffectEach<Stage>::eval(const NumEffectState &state)
00846 {
00847 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
00848 }
00849
00850 osl::CArray<MultiInt, 5 * 3 * 8 * 3>
00851 osl::eval::ml::King25EffectEachBoth::table;
00852 osl::CArray<MultiInt, 3000>
00853 osl::eval::ml::King25EffectEachBoth::x_table;
00854 osl::CArray<MultiInt, 3240>
00855 osl::eval::ml::King25EffectEachBoth::y_table;
00856 osl::CArray<MultiInt, 27000>
00857 osl::eval::ml::King25EffectEachBoth::xy_table;
00858 osl::CArray<int, 256>
00859 osl::eval::ml::King25EffectEachBoth::effect_state_table;
00860
00861 void osl::eval::ml::
00862 King25EffectEachBothOpening::setUp(const Weights &weights)
00863 {
00864 for (size_t i = 0; i < weights.dimension(); ++i)
00865 {
00866 King25EffectEachBoth::table[i][0] = weights.value(i);
00867 }
00868 }
00869
00870 void osl::eval::ml::
00871 King25EffectEachBothMidgame::setUp(const Weights &weights)
00872 {
00873 for (size_t i = 0; i < weights.dimension(); ++i)
00874 {
00875 King25EffectEachBoth::table[i][1] = weights.value(i);
00876 }
00877 }
00878
00879 void osl::eval::ml::
00880 King25EffectEachBothMidgame2::setUp(const Weights &weights)
00881 {
00882 for (size_t i = 0; i < weights.dimension(); ++i)
00883 {
00884 King25EffectEachBoth::table[i][2] = weights.value(i);
00885 }
00886 }
00887
00888 void osl::eval::ml::
00889 King25EffectEachBothEnding::setUp(const Weights &weights)
00890 {
00891 for (size_t i = 0; i < weights.dimension(); ++i)
00892 {
00893 King25EffectEachBoth::table[i][EndgameIndex] = weights.value(i);
00894 }
00895 }
00896 void osl::eval::ml::
00897 King25EffectEachXY::setUp(const Weights &weights)
00898 {
00899 for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
00900 for(int x_diff_2=0;x_diff_2<5;x_diff_2++)
00901 for(int es=0;es<8;es++)
00902 for(int po=0;po<3;po++)
00903 for(int king_x_1=0;king_x_1<5;king_x_1++){
00904 int oldIndex=(rel_y_2+x_diff_2*5+es*5*5+po*5*5*8)*5+king_x_1;
00905 int newIndex=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*king_x_1)));
00906 for (int s=0; s<NStages; ++s)
00907 King25EffectEachBoth::x_table[newIndex][s] = weights.value(oldIndex + X_DIM*s);
00908 }
00909 for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
00910 for(int rel_x=0;rel_x<3;rel_x++)
00911 for(int es=0;es<8;es++)
00912 for(int po=0;po<3;po++)
00913 for(int king_y_1=0;king_y_1<9;king_y_1++){
00914 int oldIndex=(rel_y_2+rel_x*5+es*5*3+po*5*3*8)*9+king_y_1;
00915 int newIndex=po+3*(es+8*(rel_y_2+5*(rel_x+3*king_y_1)));
00916 for (int s=0; s<NStages; ++s)
00917 King25EffectEachBoth::y_table[newIndex][s] = weights.value(oldIndex+ X_DIM * EvalStages + Y_DIM*s)+King25EffectEachBoth::table[oldIndex/9][s];
00918 }
00919 for(int d_effect=0;d_effect<16;d_effect++){
00920 for(int a_effect=0;a_effect<16;a_effect++){
00921 if(a_effect==0){
00922 King25EffectEachBoth::effect_state_table[a_effect*16+d_effect]=3*(std::min(2, d_effect));
00923 }
00924 else{
00925 int diff=d_effect-a_effect;
00926 King25EffectEachBoth::effect_state_table[a_effect*16+d_effect]=
00927 3*(std::max(-2, std::min(2, diff)) + ATTACK_DIFF_0);
00928 }
00929 }
00930 }
00931 }
00932
00933 void osl::eval::ml::
00934 King25EffectEachKXY::setUp(const Weights &weights)
00935 {
00936 for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
00937 for(int x_diff_2=0;x_diff_2<5;x_diff_2++){
00938 int rel_x=std::abs(x_diff_2-2);
00939 for(int es=0;es<8;es++)
00940 for(int po=0;po<3;po++)
00941 for(int king_x_1=0;king_x_1<5;king_x_1++)
00942 for (int king_y_1=0;king_y_1<9;king_y_1++) {
00943 int oldIndex=((rel_y_2+x_diff_2*5+es*5*5+po*5*5*8)*9+king_y_1)*5 + king_x_1;
00944 int newIndexX=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*king_x_1)));
00945 int newIndexY=po+3*(es+8*(rel_y_2+5*(rel_x+3*king_y_1)));
00946 int newIndex=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*(king_x_1+5*king_y_1))));
00947 for (int s=0; s<NStages; ++s)
00948 King25EffectEachBoth::xy_table[newIndex][s] = weights.value(oldIndex + ONE_DIM*s)+King25EffectEachBoth::x_table[newIndexX][s]+King25EffectEachBoth::y_table[newIndexY][s];
00949 }
00950 }
00951 }
00952
00953 template <osl::Player Defense>
00954 int
00955 osl::eval::ml::King25EffectEachBoth::effectStateIndex3(
00956 const NumEffectState &state, Square target)
00957 {
00958 NumBitmapEffect effect=state.effectSetAt(target);
00959 const int d_effect=effect.countEffect(Defense);
00960 const int a_effect=effect.countEffect(alt(Defense));
00961 return effect_state_table[a_effect*16+d_effect];
00962 }
00963
00964 template <osl::Player Defense>
00965 void osl::eval::ml::King25EffectEachBoth::index(
00966 const NumEffectState &state,
00967 Square target, int &index_xy,
00968 int rel_y, int king_x, int king_y, int x_diff)
00969 {
00970 const Piece piece = state.pieceAt(target);
00971
00972 int piece_owner;
00973 PtypeO ptypeO=piece.ptypeO();
00974 if(Defense==BLACK){
00975 #ifdef __INTEL_COMPILER
00976 piece_owner = (unsigned int)((int)(ptypeO)>>30);
00977 piece_owner &= 0x2;
00978 piece_owner |= (ptypeO+14)>>4;
00979 #else
00980 piece_owner=((ptypeO+14)>>4)|(((unsigned int)ptypeO>>30)&0x2);
00981 #endif
00982 }
00983 else{
00984 piece_owner=(((ptypeO+14)>>3)&0x2)|((unsigned int)ptypeO>>31);
00985 }
00986 assert(piece_owner >= 0 && piece_owner < 3);
00987 int effect_state_index = effectStateIndex3<Defense>(state, target);
00988
00989 index_xy=piece_owner+effect_state_index+3*(8*((rel_y+2)+5*((x_diff+2)+5*(king_x-1+5*(king_y-1)))));
00990 }
00991
00992 template <osl::Player Defense>
00993 void osl::eval::ml::King25EffectEachBoth::evalOne(
00994 const NumEffectState &state, MultiInt &out)
00995 {
00996 out.clear();
00997 const Square king = state.kingSquare<Defense>();
00998 const int min_dx = std::max(1, king.x() - 2)-king.x();
00999 const int max_dx = std::min(9, king.x() + 2)-king.x();
01000 const int min_dy = std::max(1, king.y() - 2)-king.y();
01001 const int max_dy = std::min(9, king.y() + 2)-king.y();
01002 const int king_x = (king.x() > 5 ? 10 - king.x() : king.x());
01003 const int king_y = (Defense == BLACK ? king.y() : 10 - king.y());
01004 if ((Defense == BLACK && king.x() >= 6) ||
01005 (Defense == WHITE && king.x() >= 5)){
01006 for (int dx = min_dx; dx <= max_dx; ++dx)
01007 {
01008
01009
01010
01011 int x_diff = dx;
01012 for (int dy = min_dy; dy <= max_dy; ++dy)
01013 {
01014 const Square target(king.x()+dx, king.y()+dy);
01015
01016 const int rel_y = dy * (Defense == BLACK ? 1 : -1);
01017 int index_xy;
01018 index<Defense>(state, target, index_xy,
01019 rel_y,king_x,king_y,x_diff);
01020 out += xy_table[index_xy];
01021 }
01022 }
01023 }
01024 else {
01025 for (int dx = min_dx; dx <= max_dx; ++dx)
01026 {
01027
01028
01029
01030 int x_diff = -dx;
01031 for (int dy = min_dy; dy <= max_dy; ++dy)
01032 {
01033 const Square target(king.x()+dx, king.y()+dy);
01034
01035 const int rel_y = dy * (Defense == BLACK ? 1 : -1);
01036 int index_xy;
01037 index<Defense>(state, target, index_xy,
01038 rel_y,king_x,king_y,x_diff);
01039 out += xy_table[index_xy];
01040 }
01041 }
01042 }
01043 if (Defense != BLACK)
01044 {
01045 out = -out;
01046 }
01047 }
01048
01049 void osl::eval::ml::
01050 King25EffectEachBoth::eval(const NumEffectState &state,
01051 MultiIntPair &out)
01052 {
01053 evalOne<BLACK>(state, out[BLACK]);
01054 evalOne<WHITE>(state, out[WHITE]);
01055 }
01056
01057 void
01058 osl::eval::ml::King25EffectEachBoth::evalWithUpdate(
01059 const NumEffectState &state, Move last_move,
01060 MultiIntPair &values)
01061 {
01062 BoardMask mb = state.changedEffects(BLACK), mw = state.changedEffects(WHITE);
01063 mb.set(Square(last_move.to())); mb.set(Square(last_move.from()));
01064 mw.set(Square(last_move.to())); mw.set(Square(last_move.from()));
01065 const Square kb = state.kingSquare<BLACK>(), kw = state.kingSquare<WHITE>();
01066 const bool update_black = mb.anyInRange(Board_Mask_Table5x5.mask(kb)) ||
01067 mw.anyInRange(Board_Mask_Table5x5.mask(kb));
01068 const bool update_white = mw.anyInRange(Board_Mask_Table5x5.mask(kw)) ||
01069 mb.anyInRange(Board_Mask_Table5x5.mask(kw));
01070 if (update_black)
01071 {
01072 evalOne<BLACK>(state, values[BLACK]);
01073 }
01074 if (update_white)
01075 {
01076 evalOne<WHITE>(state, values[WHITE]);
01077 }
01078 }
01079
01080
01081 template <bool Opening>
01082 osl::CArray<int, 1125> osl::eval::ml::King25EmptyAbs<Opening>::table;
01083
01084 template <bool Opening>
01085 void osl::eval::ml::
01086 King25EmptyAbs<Opening>::setUp(const Weights &weights)
01087 {
01088 for (size_t i = 0; i < weights.dimension(); ++i)
01089 {
01090 table[i] = weights.value(i);
01091 }
01092 }
01093
01094 template <bool Opening>
01095 template <osl::Player player>
01096 int osl::eval::ml::King25EmptyAbs<Opening>::index(Square king,
01097 Square target)
01098 {
01099 int x, target_x;
01100 if ((player == BLACK && king.x() >= 6) ||
01101 (player == WHITE && king.x() >= 5))
01102 {
01103 x = 10 - king.x();
01104 target_x = 10 - target.x();
01105 }
01106 else
01107 {
01108 x = king.x();
01109 target_x = target.x();
01110 }
01111 const int y = (player == BLACK ? king.y() : 10 - king.y());
01112 const int target_y = (player == BLACK ? target.y() : 10 - target.y());
01113
01114 return target_y - y + 2 + (target_x - x + 2 ) * 5 + (y - 1) * 5 * 5
01115 + (x - 1) * 5 * 5 * 9;
01116 }
01117
01118 template <bool Opening>
01119 template <osl::Player Defense>
01120 int osl::eval::ml::King25EmptyAbs<Opening>::evalOne(
01121 const NumEffectState &state)
01122 {
01123 int result = 0;
01124 const Square king = state.kingSquare<Defense>();
01125 const int min_x = std::max(1, king.x() - 2);
01126 const int max_x = std::min(9, king.x() + 2);
01127 const int min_y = std::max(1, king.y() - 2);
01128 const int max_y = std::min(9, king.y() + 2);
01129 for (int x = min_x; x <= max_x; ++x)
01130 {
01131 for (int y = min_y; y <= max_y; ++y)
01132 {
01133 Square target(x, y);
01134 if (target.isOnBoard() && state.pieceAt(target).isEmpty())
01135 {
01136 result += table[index<Defense>(king, target)];
01137 }
01138 }
01139 }
01140 if (Defense == BLACK)
01141 return result;
01142 else
01143 return -result;
01144 }
01145
01146 template <bool Opening>
01147 int osl::eval::ml::King25EmptyAbs<Opening>::eval(
01148 const NumEffectState &state)
01149 {
01150 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
01151 }
01152
01153 template <bool Opening>
01154 int osl::eval::ml::King25EmptyAbs<Opening>::evalWithUpdate(
01155 const NumEffectState &state, osl::Move moved,
01156 int last_value)
01157 {
01158 if (moved.ptype() == osl::KING)
01159 {
01160 return eval(state);
01161 }
01162 const osl::Square self_king = state.kingSquare(moved.player());
01163 const osl::Square opp_king = state.kingSquare(alt(moved.player()));
01164 int result = last_value;
01165
01166 if (!moved.isDrop())
01167 {
01168 const Square from = moved.from();
01169 if (std::abs(self_king.x() - from.x()) <= 2 &&
01170 std::abs(self_king.y() - from.y()) <= 2)
01171 {
01172 result += table[index(self_king, moved.from(), moved.player())] *
01173 (moved.player() == BLACK ? 1 : -1);
01174 }
01175
01176 if (std::abs(opp_king.x() - from.x()) <= 2 &&
01177 std::abs(opp_king.y() - from.y()) <= 2)
01178 {
01179 result -= table[index(opp_king, from, alt(moved.player()))] *
01180 (moved.player() == BLACK ? 1 : -1);
01181 }
01182 }
01183
01184 Ptype captured = moved.capturePtype();
01185 if (captured == PTYPE_EMPTY)
01186 {
01187 const Square to = moved.to();
01188 if (std::abs(self_king.x() - to.x()) <= 2 &&
01189 std::abs(self_king.y() - to.y()) <= 2)
01190 {
01191 result -= table[index(self_king, to, moved.player())] *
01192 (moved.player() == BLACK ? 1 : -1);
01193 }
01194 if (std::abs(opp_king.x() - to.x()) <= 2 &&
01195 std::abs(opp_king.y() - to.y()) <= 2)
01196 {
01197 result += table[index(opp_king, to, alt(moved.player()))] *
01198 (moved.player() == BLACK ? 1 : -1);
01199 }
01200 }
01201 return result;
01202
01203 }
01204
01205 osl::CArray<MultiInt, 3072> osl::eval::ml::King3Pieces::table;
01206 osl::CArray<MultiInt, 15360> osl::eval::ml::King3Pieces::x_table;
01207 osl::CArray<MultiInt, 27648> osl::eval::ml::King3Pieces::y_table;
01208
01209 void osl::eval::ml::King3Pieces::setUp(const Weights &weights)
01210 {
01211 for (int i = 0; i < ONE_DIM; ++i)
01212 {
01213 for (int s=0; s<NStages; ++s)
01214 table[i][s] = weights.value(i + ONE_DIM*s);
01215 }
01216 }
01217
01218 void osl::eval::ml::King3PiecesXY::setUp(const Weights &weights)
01219 {
01220 for (int i = 0; i < X_DIM; ++i)
01221 {
01222 for (int s=0; s<NStages; ++s)
01223 King3Pieces::x_table[i][s] = weights.value(i + ONE_DIM*s);
01224 }
01225 for (int i = 0; i < Y_DIM; ++i)
01226 {
01227 for (int s=0; s<NStages; ++s)
01228 King3Pieces::y_table[i][s] = weights.value(i + ONE_DIM*s + X_DIM);
01229 }
01230 }
01231
01232 template <osl::Player King>
01233 void osl::eval::ml::King3Pieces::evalOne(const NumEffectState &state,
01234 MultiInt &result)
01235 {
01236 const Square king = state.kingSquare<King>();
01237 const int vertical_index =
01238 index<King, VERTICAL>(
01239 state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
01240 state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
01241 const int vertical_index_x =
01242 indexX<King, VERTICAL>(
01243 king,
01244 state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
01245 state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
01246 const int vertical_index_y =
01247 indexY<King, VERTICAL>(
01248 king,
01249 state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
01250 state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
01251 const int horizontal_index =
01252 index<King, HORIZONTAL>(
01253 state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
01254 state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
01255 const int horizontal_index_x =
01256 indexX<King, HORIZONTAL>(
01257 king,
01258 state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
01259 state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
01260 const int horizontal_index_y =
01261 indexY<King, HORIZONTAL>(
01262 king,
01263 state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
01264 state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
01265 const int diagonal_index1 =
01266 index<King, DIAGONAL>(
01267 state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
01268 state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
01269 const int diagonal_index2 =
01270 index<King, DIAGONAL>(
01271 state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
01272 state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
01273 const int diagonal_index1_x =
01274 indexX<King, DIAGONAL>(
01275 king,
01276 state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
01277 state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
01278 const int diagonal_index2_x=
01279 indexX<King, DIAGONAL>(
01280 king,
01281 state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
01282 state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
01283 const int diagonal_index1_y =
01284 indexY<King, DIAGONAL>(
01285 king,
01286 state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
01287 state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
01288 const int diagonal_index2_y =
01289 indexY<King, DIAGONAL>(
01290 king,
01291 state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
01292 state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
01293 const MultiInt v = value(vertical_index, horizontal_index,
01294 diagonal_index1, diagonal_index2,
01295 vertical_index_x, horizontal_index_x,
01296 diagonal_index1_x, diagonal_index2_x,
01297 vertical_index_y , horizontal_index_y,
01298 diagonal_index1_y, diagonal_index2_y);
01299 if (King == BLACK)
01300 {
01301 result += v;
01302 }
01303 else
01304 {
01305 result -= v;
01306 }
01307 }
01308
01309 MultiInt
01310 osl::eval::ml::King3Pieces::eval(const NumEffectState &state)
01311 {
01312 MultiInt result;
01313 evalOne<BLACK>(state, result);
01314 evalOne<WHITE>(state, result);
01315 return result;
01316 }
01317
01318 MultiInt
01319 osl::eval::ml::King3Pieces::evalWithUpdate(
01320 const NumEffectState &state,
01321 Move last_move,
01322 MultiInt &last_value)
01323 {
01324 const CArray<Square,2> kings = {{
01325 state.kingSquare(BLACK),
01326 state.kingSquare(WHITE),
01327 }};
01328 if ((std::abs(last_move.to().x() - kings[0].x()) <= 1 &&
01329 std::abs(last_move.to().y() - kings[0].y()) <= 1) ||
01330 (std::abs(last_move.to().x() - kings[1].x()) <= 1 &&
01331 std::abs(last_move.to().y() - kings[1].y()) <= 1))
01332 return eval(state);
01333 if (!last_move.isDrop())
01334 {
01335 if ((std::abs(last_move.from().x() - kings[0].x()) <= 1 &&
01336 std::abs(last_move.from().y() - kings[0].y()) <= 1) ||
01337 (std::abs(last_move.from().x() - kings[1].x()) <= 1 &&
01338 std::abs(last_move.from().y() - kings[1].y()) <= 1))
01339 return eval(state);
01340 }
01341 return last_value;
01342 }
01343
01344
01345
01346 osl::CArray<int, 17 * 128> osl::eval::ml::King25EffectAttack::table;
01347 osl::CArray<MultiInt, 17 * 128> osl::eval::ml::King25EffectDefense::table;
01348
01349 osl::CArray<int, 17 * 128 * 9> osl::eval::ml::King25EffectYAttack::table;
01350 osl::CArray<MultiInt, 17 * 128 * 9> osl::eval::ml::King25EffectYDefense::table;
01351
01352
01353 osl::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::table;
01354 osl::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::rook_table;
01355 osl::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::bishop_table;
01356 osl::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::rook_bishop_table;
01357
01358 void osl::eval::ml::KingMobility::setUp(const Weights &weights)
01359 {
01360 static CArray<MultiInt, 3240> old_table;
01361 for (int i = 0; i < ONE_DIM; ++i)
01362 {
01363 for (int s=0; s<NStages; ++s)
01364 old_table[i][s] = weights.value(i + ONE_DIM*s);
01365 }
01366 for(int king_x=0;king_x<5;king_x++)
01367 for(int king_y=0;king_y<9;king_y++)
01368 for(int dir=0;dir<8;dir++)
01369 for(int mobility=0;mobility<9;mobility++){
01370 int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
01371 int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
01372 for (int s=0; s<NStages; ++s)
01373 table[newIndex][s]=old_table[oldIndex][s];
01374 }
01375 }
01376
01377 void osl::eval::ml::
01378 KingMobilityWithRook::setUp(const Weights &weights)
01379 {
01380 static CArray<MultiInt, 3240> old_table;
01381 for (int i = 0; i < ONE_DIM; ++i)
01382 {
01383 for (int s=0; s<NStages; ++s)
01384 old_table[i][s] = weights.value(i + ONE_DIM*s);
01385 }
01386 for(int king_x=0;king_x<5;king_x++)
01387 for(int king_y=0;king_y<9;king_y++)
01388 for(int dir=0;dir<8;dir++)
01389 for(int mobility=0;mobility<9;mobility++){
01390 int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
01391 int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
01392 for (int s=0; s<NStages; ++s)
01393 KingMobility::rook_table[newIndex][s]=old_table[oldIndex][s];
01394 }
01395 }
01396
01397 void osl::eval::ml::
01398 KingMobilityWithBishop::setUp(const Weights &weights)
01399 {
01400 static CArray<MultiInt, 3240> old_table;
01401 for (int i = 0; i < ONE_DIM; ++i)
01402 {
01403 for (int s=0; s<NStages; ++s)
01404 old_table[i][s] = weights.value(i + ONE_DIM*s);
01405 }
01406 for(int king_x=0;king_x<5;king_x++)
01407 for(int king_y=0;king_y<9;king_y++)
01408 for(int dir=0;dir<8;dir++)
01409 for(int mobility=0;mobility<9;mobility++){
01410 int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
01411 int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
01412 for (int s=0; s<NStages; ++s)
01413 KingMobility::bishop_table[newIndex][s]=old_table[oldIndex][s];
01414 }
01415 for(int i=0;i<3240;i++){
01416 KingMobility::rook_bishop_table[i]=
01417 KingMobility::table[i]+KingMobility::rook_table[i]+KingMobility::bishop_table[i];
01418 KingMobility::rook_table[i]+=KingMobility::table[i];
01419 KingMobility::bishop_table[i]+=KingMobility::table[i];
01420 }
01421 }
01422
01423 template <osl::Player P>
01424 osl::MultiInt osl::eval::ml::
01425 KingMobility::evalOne(const NumEffectState &state)
01426 {
01427 MultiInt result;
01428 const Square king = state.kingSquare<P>();
01429 const int king_x = (king.x() > 5 ? 10 - king.x() : king.x()) - 1;
01430 const int king_y = (P == BLACK ? king.y() : 10 - king.y()) - 1;
01431 int indexBase=9*8*(king_y+9*king_x);
01432 if(P==BLACK){
01433 if (state.hasPieceOnStand<ROOK>(alt(P)))
01434 {
01435 if(state.hasPieceOnStand<BISHOP>(alt(P))){
01436 result =
01437 rook_bishop_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01438 rook_bishop_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01439 rook_bishop_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01440 rook_bishop_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01441 rook_bishop_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01442 rook_bishop_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01443 rook_bishop_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01444 rook_bishop_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01445 }
01446 else{
01447 result =
01448 rook_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01449 rook_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01450 rook_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01451 rook_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01452 rook_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01453 rook_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01454 rook_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01455 rook_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01456 }
01457 }
01458 else if(state.hasPieceOnStand<BISHOP>(alt(P))){
01459 result =
01460 bishop_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01461 bishop_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01462 bishop_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01463 bishop_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01464 bishop_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01465 bishop_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01466 bishop_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01467 bishop_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01468 }
01469 else{
01470 result =
01471 table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01472 table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01473 table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01474 table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01475 table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01476 table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01477 table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01478 table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01479 }
01480 }
01481 else{
01482 if (state.hasPieceOnStand<ROOK>(alt(P)))
01483 {
01484 if(state.hasPieceOnStand<BISHOP>(alt(P))){
01485 result = -(
01486 rook_bishop_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01487 rook_bishop_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01488 rook_bishop_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01489 rook_bishop_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01490 rook_bishop_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01491 rook_bishop_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01492 rook_bishop_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01493 rook_bishop_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01494 }
01495 else{
01496 result = -(
01497 rook_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01498 rook_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01499 rook_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01500 rook_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01501 rook_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01502 rook_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01503 rook_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01504 rook_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01505 }
01506 }
01507 else if(state.hasPieceOnStand<BISHOP>(alt(P))){
01508 result = -(
01509 bishop_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01510 bishop_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01511 bishop_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01512 bishop_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01513 bishop_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01514 bishop_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01515 bishop_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01516 bishop_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01517 }
01518 else{
01519 result = -(
01520 table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01521 table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01522 table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01523 table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01524 table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01525 table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01526 table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01527 table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01528 }
01529 }
01530 return result;
01531 }
01532
01533 osl::MultiInt osl::eval::ml::
01534 KingMobility::eval(const NumEffectState &state)
01535 {
01536 MultiInt result = evalOne<BLACK>(state) + evalOne<WHITE>(state);
01537 return result;
01538 }
01539
01540
01541 osl::CArray<MultiInt, 45*33> osl::eval::ml::KingMobilitySum::table;
01542
01543 void osl::eval::ml::KingMobilitySum::setUp(const Weights &weights)
01544 {
01545 CArray<MultiInt, 2925> old_table;
01546 for (int i = 0; i < ONE_DIM; ++i)
01547 {
01548 for (int s=0; s<NStages; ++s)
01549 old_table[i][s] = weights.value(i + ONE_DIM*s);
01550 }
01551 for(int king_x=0;king_x<5;king_x++)
01552 for(int king_y=0;king_y<9;king_y++)
01553 for(int mobility=0;mobility<=32;mobility++){
01554 int oldIndex=king_x+5*(king_y+9*(mobility+8));
01555 int newIndex=mobility+33*(king_y+9*king_x);
01556 for (int s=0; s<NStages; ++s)
01557 table[newIndex]=old_table[oldIndex];
01558 }
01559 }
01560
01561 template <osl::Player P>
01562 osl::MultiInt osl::eval::ml::
01563 KingMobilitySum::evalOne(const NumEffectState &state)
01564 {
01565 MultiInt result;
01566 const Square king = state.kingSquare<P>();
01567 int sum=state.kingMobilityAbs(P, UL).y()+state.kingMobilityAbs(P, U).y()+
01568 state.kingMobilityAbs(P, UR).y()+state.kingMobilityAbs(P, R).x()-
01569 state.kingMobilityAbs(P, DL).y()-state.kingMobilityAbs(P, D).y()-
01570 state.kingMobilityAbs(P, DR).y()-state.kingMobilityAbs(P, L).x();
01571 const int king_x = (king.x() > 5 ? 10 - king.x() : king.x()) - 1;
01572 const int king_y = (P == BLACK ? king.y() : 10 - king.y()) - 1;
01573 int mobility=sum-8;
01574 result = table[mobility+33*(king_y+9*king_x)];
01575 if (P == BLACK)
01576 {
01577 return result;
01578 }
01579 else
01580 {
01581 return -result;
01582 }
01583 }
01584
01585 osl::MultiInt osl::eval::ml::
01586 KingMobilitySum::eval(const NumEffectState &state)
01587 {
01588 MultiInt result = evalOne<BLACK>(state) + evalOne<WHITE>(state);
01589 return result;
01590 }
01591
01592
01593 osl::CArray<MultiInt, 8192>
01594 osl::eval::ml::King25BothSide::table;
01595 osl::CArray<MultiInt, 40960>
01596 osl::eval::ml::King25BothSide::x_table;
01597 osl::CArray<MultiInt, 73728>
01598 osl::eval::ml::King25BothSide::y_table;
01599
01600 void osl::eval::ml::King25BothSide::setUp(const Weights &weights)
01601 {
01602 for (int i = 0; i < ONE_DIM; ++i)
01603 {
01604 for (int s=0; s<NStages; ++s)
01605 table[i][s] = weights.value(i + ONE_DIM*s);
01606 }
01607 }
01608
01609 void osl::eval::ml::King25BothSideX::setUp(const Weights &weights)
01610 {
01611 for (int i = 0; i < ONE_DIM; ++i)
01612 {
01613 for (int s=0; s<NStages; ++s)
01614 King25BothSide::x_table[i][s] = weights.value(i + ONE_DIM*s);
01615 }
01616 }
01617
01618 void osl::eval::ml::King25BothSideY::setUp(const Weights &weights)
01619 {
01620 for (int i = 0; i < ONE_DIM; ++i)
01621 {
01622 for (int s=0; s<NStages; ++s)
01623 King25BothSide::y_table[i][s] = weights.value(i + ONE_DIM*s);
01624 }
01625 for(int king_y=1;king_y<=9;king_y++)
01626 for(int effect1=0;effect1<32;effect1++)
01627 for(int effect2=0;effect2<32;effect2++)
01628 for(int i=0;i<8;i++){
01629 int index0=effect1 + 32 * (effect2 + 32 * i);
01630 int index1=king_y - 1 + 9 *(effect1 + 32 * (effect2 + 32 * i));
01631 King25BothSide::y_table[index1] += King25BothSide::table[index0];
01632 }
01633 }
01634
01635 template<osl::Player P>
01636 osl::MultiInt osl::eval::ml::
01637 King25BothSide::evalOne(const NumEffectState &state,
01638 const CArray<int, 5> &effects)
01639 {
01640 const Square king=state.kingSquare<P>();
01641 const int king_y = (P==BLACK ? king.y() : 10 - king.y());
01642 const int king_x = (king.x() >= 6 ? 10 - king.x() : king.x());
01643 if ((P== BLACK && king.x() > 5) || (P==WHITE && king.x() < 5)){
01644 return
01645 x_table[indexX(king_x,effects[2],effects[0],(2*3)+1)]+
01646 y_table[indexY(king_y,effects[0],effects[2],(0*3)+0)]+
01647 x_table[indexX(king_x,effects[3],effects[0],(1*3)+2)]+
01648 y_table[indexY(king_y,effects[0],effects[3],(0*3)+1)]+
01649 x_table[indexX(king_x,effects[4],effects[0],(0*3)+2)]+
01650 y_table[indexY(king_y,effects[0],effects[4],(0*3)+2)]+
01651 x_table[indexX(king_x,effects[2],effects[1],(2*3)+0)]+
01652 y_table[indexY(king_y,effects[1],effects[2],(1*3)+0)]+
01653 x_table[indexX(king_x,effects[3],effects[1],(1*3)+1)]+
01654 y_table[indexY(king_y,effects[1],effects[3],(1*3)+1)]+
01655 x_table[indexX(king_x,effects[4],effects[1],(0*3)+1)]+
01656 y_table[indexY(king_y,effects[1],effects[4],(1*3)+2)]+
01657 x_table[indexX(king_x,effects[3],effects[2],(1*3)+0)]+
01658 y_table[indexY(king_y,effects[2],effects[3],(2*3)+0)]+
01659 x_table[indexX(king_x,effects[4],effects[2],(0*3)+0)]+
01660 y_table[indexY(king_y,effects[2],effects[4],(2*3)+1)];
01661 }
01662 else{
01663 return
01664 x_table[indexX(king_x,effects[0],effects[2],(0*3)+0)]+
01665 y_table[indexY(king_y,effects[0],effects[2],(0*3)+0)]+
01666 x_table[indexX(king_x,effects[0],effects[3],(0*3)+1)]+
01667 y_table[indexY(king_y,effects[0],effects[3],(0*3)+1)]+
01668 x_table[indexX(king_x,effects[0],effects[4],(0*3)+2)]+
01669 y_table[indexY(king_y,effects[0],effects[4],(0*3)+2)]+
01670 x_table[indexX(king_x,effects[1],effects[2],(1*3)+0)]+
01671 y_table[indexY(king_y,effects[1],effects[2],(1*3)+0)]+
01672 x_table[indexX(king_x,effects[1],effects[3],(1*3)+1)]+
01673 y_table[indexY(king_y,effects[1],effects[3],(1*3)+1)]+
01674 x_table[indexX(king_x,effects[1],effects[4],(1*3)+2)]+
01675 y_table[indexY(king_y,effects[1],effects[4],(1*3)+2)]+
01676 x_table[indexX(king_x,effects[2],effects[3],(2*3)+0)]+
01677 y_table[indexY(king_y,effects[2],effects[3],(2*3)+0)]+
01678 x_table[indexX(king_x,effects[2],effects[4],(2*3)+1)]+
01679 y_table[indexY(king_y,effects[2],effects[4],(2*3)+1)];
01680 }
01681 }
01682
01683 osl::MultiInt osl::eval::ml::
01684 King25BothSide::eval(const NumEffectState &state,
01685 const CArray<int, 5> &black,
01686 const CArray<int, 5> &white)
01687 {
01688 return evalOne<BLACK>(state,black)-evalOne<WHITE>(state,white);
01689 }
01690
01691 osl::CArray<MultiInt, 2400>
01692 osl::eval::ml::King25Effect3::table;
01693 osl::CArray<MultiInt, 21600>
01694 osl::eval::ml::King25Effect3::y_table;
01695
01696 void osl::eval::ml::King25Effect3::setUp(const Weights &weights)
01697 {
01698 for (int i = 0; i < ONE_DIM; ++i)
01699 {
01700 for (int s=0; s<NStages; ++s)
01701 table[i][s] = weights.value(i + ONE_DIM*s);
01702 }
01703 }
01704
01705 void osl::eval::ml::King25Effect3Y::setUp(const Weights &weights)
01706 {
01707 for (int i = 0; i < ONE_DIM; ++i)
01708 {
01709 for (int s=0; s<NStages; ++s)
01710 King25Effect3::y_table[i][s] = weights.value(i + ONE_DIM*s);
01711 }
01712 }
01713
01714 template <osl::Player Attack>
01715 osl::MultiInt osl::eval::ml::
01716 King25Effect3::evalOne(const NumEffectState &state,
01717 PieceMask king25)
01718 {
01719 king25 = king25 & state.piecesOnBoard(Attack);
01720 const PieceMask promoted_mask = (king25 & state.promotedPieces());
01721 const bool with_knight =
01722 (king25 & ~state.promotedPieces()).template selectBit<KNIGHT>().any();
01723 king25.clearBit<KNIGHT>();
01724 king25.clearBit<LANCE>();
01725 king25.clearBit<PAWN>();
01726 king25 = king25 | promoted_mask;
01727 const int piece_count = std::min(9, king25.countBit());
01728 const int stand_count = std::min(9,
01729 state.countPiecesOnStand<ROOK>(Attack) +
01730 state.countPiecesOnStand<BISHOP>(Attack) +
01731 state.countPiecesOnStand<GOLD>(Attack) +
01732 state.countPiecesOnStand<SILVER>(Attack));
01733 const bool stand_with_knight = state.hasPieceOnStand<KNIGHT>(Attack);
01734 const Player Defense = alt(Attack);
01735 PieceMask attacked =
01736 state.effectedMask(Attack) & state.piecesOnBoard(Defense);
01737 attacked.clearBit<KNIGHT>();
01738 attacked.clearBit<LANCE>();
01739 attacked.clearBit<PAWN>();
01740 PieceMask attacking;
01741 while (attacked.any())
01742 {
01743 const Piece piece = state.pieceOf(attacked.takeOneBit());
01744 attacking = attacking | state.effectSetAt(piece.square());
01745 }
01746 attacking = (attacking & state.piecesOnBoard(Attack) & ~king25);
01747 const int attacked_count = std::min(5, attacking.countBit());
01748 if (Attack == BLACK)
01749 {
01750 return table[index(piece_count, with_knight,
01751 stand_count, stand_with_knight, attacked_count)] +
01752 y_table[indexY(piece_count, with_knight,
01753 stand_count, stand_with_knight, attacked_count,
01754 state.kingSquare<WHITE>().y())];
01755 }
01756 else
01757 {
01758 return -(table[index(piece_count, with_knight,
01759 stand_count, stand_with_knight, attacked_count)] +
01760 y_table[indexY(piece_count, with_knight,
01761 stand_count, stand_with_knight, attacked_count,
01762 10 - state.kingSquare<BLACK>().y())]);
01763 }
01764 }
01765
01766 osl::MultiInt osl::eval::ml::
01767 King25Effect3::eval(const NumEffectState &state,
01768 const CArray<PieceMask, 2> &king25_mask)
01769 {
01770 return evalOne<BLACK>(state, king25_mask[WHITE]) +
01771 evalOne<WHITE>(state, king25_mask[BLACK]);
01772 }
01773
01774
01775 osl::CArray<MultiInt, 4096>
01776 osl::eval::ml::King25Mobility::table;
01777 osl::CArray<MultiInt, 20480>
01778 osl::eval::ml::King25Mobility::x_table;
01779 osl::CArray<MultiInt, 36864>
01780 osl::eval::ml::King25Mobility::y_table;
01781
01782 void osl::eval::ml::King25Mobility::setUp(const Weights &weights)
01783 {
01784 for (int i = 0; i < ONE_DIM; ++i)
01785 {
01786 for (int s=0; s<NStages; ++s)
01787 table[i][s] = weights.value(i + ONE_DIM*s);
01788 }
01789 }
01790
01791 void osl::eval::ml::King25MobilityX::setUp(const Weights &weights)
01792 {
01793 for (int i = 0; i < ONE_DIM; ++i)
01794 {
01795 for (int s=0; s<NStages; ++s)
01796 King25Mobility::x_table[i][s] = weights.value(i + ONE_DIM*s);
01797 }
01798 }
01799
01800 void osl::eval::ml::King25MobilityY::setUp(const Weights &weights)
01801 {
01802 for (int i = 0; i < ONE_DIM; ++i)
01803 {
01804 for (int s=0; s<NStages; ++s)
01805 King25Mobility::y_table[i][s] = weights.value(i + ONE_DIM*s);
01806 }
01807 }
01808
01809 osl::MultiInt osl::eval::ml::
01810 King25Mobility::eval(const NumEffectState &state,
01811 const CArray<int, 5> &black,
01812 const CArray<int, 5> &white)
01813 {
01814 const CArray<Square,2> kings = {{
01815 state.kingSquare<BLACK>(),
01816 state.kingSquare<WHITE>(),
01817 }};
01818 MultiInt result;
01819 for (size_t i = 1; i < black.size(); ++i)
01820 {
01821 result += (table[index(black[i - 1], black[i], i - 1)] +
01822 x_table[indexX<BLACK>(kings[BLACK],
01823 black[i - 1], black[i], i - 1)] +
01824 y_table[indexY<BLACK>(kings[BLACK],
01825 black[i - 1], black[i], i - 1)]);
01826 result -= (table[index(white[i - 1], white[i], i - 1)] +
01827 x_table[indexX<WHITE>(kings[WHITE],
01828 white[i - 1], white[i], i - 1)] +
01829 y_table[indexY<WHITE>(kings[WHITE],
01830 white[i - 1], white[i], i - 1)]);
01831 }
01832 return result;
01833 }
01834
01835
01836 osl::CArray<MultiInt, 100>
01837 osl::eval::ml::King25EffectCountCombination::table;
01838 osl::CArray<MultiInt, 900>
01839 osl::eval::ml::King25EffectCountCombination::y_table;
01840
01841 void osl::eval::ml::King25EffectCountCombination::setUp(const Weights &weights)
01842 {
01843 for (int i = 0; i < ONE_DIM; ++i)
01844 {
01845 for (int s=0; s<NStages; ++s)
01846 table[i][s] = weights.value(i + ONE_DIM*s);
01847 }
01848 }
01849
01850 void osl::eval::ml::King25EffectCountCombinationY::setUp(const Weights &weights)
01851 {
01852 for (int i = 0; i < ONE_DIM; ++i)
01853 {
01854 for (int s=0; s<NStages; ++s)
01855 King25EffectCountCombination::y_table[i][s] = weights.value(i + ONE_DIM*s);
01856 }
01857 }
01858
01859 template <osl::Player Attack>
01860 osl::MultiInt osl::eval::ml::
01861 King25EffectCountCombination::evalOne(const NumEffectState &state,
01862 PieceMask king25)
01863 {
01864 const Player Defense = alt(Attack);
01865 PieceMask attack = king25 & state.piecesOnBoard(Attack);
01866 PieceMask defense =
01867 king25 & state.piecesOnBoard(Defense);
01868 const PieceMask attack_promoted_mask = (attack & state.promotedPieces());
01869 const PieceMask defense_promoted_mask = (defense & state.promotedPieces());
01870 attack.clearBit<KNIGHT>();
01871 attack.clearBit<LANCE>();
01872 attack.clearBit<PAWN>();
01873 attack = attack | attack_promoted_mask;
01874 defense.clearBit<KNIGHT>();
01875 defense.clearBit<LANCE>();
01876 defense.clearBit<PAWN>();
01877 defense = defense | defense_promoted_mask;
01878 const int attack_count = std::min(9,
01879 attack.countBit() +
01880 state.countPiecesOnStand<ROOK>(Attack) +
01881 state.countPiecesOnStand<BISHOP>(Attack) +
01882 state.countPiecesOnStand<GOLD>(Attack) +
01883 state.countPiecesOnStand<SILVER>(Attack));
01884 const int defense_count = std::min(9,
01885 defense.countBit() +
01886 state.countPiecesOnStand<ROOK>(Defense) +
01887 state.countPiecesOnStand<BISHOP>(Defense) +
01888 state.countPiecesOnStand<GOLD>(Defense) +
01889 state.countPiecesOnStand<SILVER>(Defense));
01890 const int y = (Attack == BLACK ? state.kingSquare<Defense>().y() :
01891 10 - state.kingSquare<Defense>().y());
01892 MultiInt result = table[attack_count + 10 * defense_count] +
01893 y_table[y - 1 + 9 * (attack_count + 10 * defense_count)];
01894 if (Attack == BLACK)
01895 return result;
01896 else
01897 return -result;
01898 }
01899
01900 osl::MultiInt osl::eval::ml::
01901 King25EffectCountCombination::eval(const NumEffectState &state,
01902 const CArray<PieceMask, 2> &king25_mask)
01903 {
01904 return evalOne<BLACK>(state, king25_mask[WHITE]) +
01905 evalOne<WHITE>(state, king25_mask[BLACK]);
01906 }
01907
01908
01909 osl::CArray<int, 18*81*(45*2)*3> osl::eval::ml::BishopExchangeSilverKing::table;
01910 void osl::eval::ml::
01911 BishopExchangeSilverKing::setUp(const Weights & weights)
01912 {
01913 for (size_t i=0; i<weights.dimension(); ++i)
01914 table[i] = weights.value(i);
01915 }
01916
01917 int osl::eval::ml::
01918 BishopExchangeSilverKing::eval(const NumEffectState &state)
01919 {
01920 if (state.promotedPieces().any())
01921 return 0;
01922 PieceMask stand_all = state.standMask(BLACK) | state.standMask(WHITE);
01923 stand_all.clearBit<BISHOP>();
01924 stand_all.clearBit<PAWN>();
01925 if (stand_all.any())
01926 return 0;
01927 if (state.nth<BISHOP>(0).owner() == state.nth<BISHOP>(1).owner())
01928 return 0;
01929 if (state.nth<BISHOP>(0).isOnBoard() != state.nth<BISHOP>(1).isOnBoard())
01930 return 0;
01931 int offset = 0;
01932 if (state.nth<BISHOP>(0).isOnBoard()) {
01933 offset += BISHOP_ONE_DIM;
01934 if (state.hasEffectByPiece(state.nth<BISHOP>(0),
01935 state.nth<BISHOP>(1).square()))
01936 offset += BISHOP_ONE_DIM;
01937 }
01938 return evalOne<BLACK>(state, offset) + evalOne<WHITE>(state, offset);
01939 }
01940
01941 template <osl::Player KingOwner>
01942 int osl::eval::ml::
01943 BishopExchangeSilverKing::evalOne(const NumEffectState &state, int offset)
01944 {
01945 Square king = state.kingSquare(KingOwner);
01946 int king_index = indexKing(king.squareForBlack(alt(KingOwner)));
01947 if (king_index < 0)
01948 return 0;
01949 CArray<Piece,2> rook = {{
01950 state.nth<ROOK>(0), state.nth<ROOK>(1),
01951 }};
01952 if (rook[0].owner() == rook[1].owner())
01953 return 0;
01954 if (rook[0].owner() == KingOwner)
01955 std::swap(rook[0], rook[1]);
01956 int rook_index0 = indexKing(rook[0].square().squareForBlack(KingOwner));
01957 if (rook_index0 < 0)
01958 return 0;
01959 int rook_index1 = indexKing(rook[1].square().squareForBlack(alt(KingOwner)));
01960 if (rook_index1 < 0)
01961 return 0;
01962 FixedCapacityVector<Square, 4> silver;
01963 for (int i=0; i<state.nthLimit<SILVER>(); ++i) {
01964 Piece p = state.nth<SILVER>(i);
01965 assert(p.isOnBoard());
01966 if (p.owner() == KingOwner)
01967 continue;
01968 silver.push_back(p.square().squareForBlack(KingOwner));
01969 }
01970 if (silver.size() != 2 || silver[0].x() == silver[1].x())
01971 return 0;
01972 int silver_index
01973 = indexSilver((silver[0].x() > silver[1].x()) ? silver[0] : silver[1]);
01974 int index = offset + (king_index*81+silver_index)*90;
01975 return table[index + rook_index0] * sign(KingOwner)
01976 + table[index + 45 + rook_index1] * sign(KingOwner);
01977 }
01978
01979
01980
01981
01982 template <osl::Player KingOwner>
01983 int osl::eval::ml::
01984 EnterKingDefense::evalOne(const NumEffectState &state)
01985 {
01986 Square king = state.kingSquare(KingOwner);
01987 if (king.y() < 4 || king.y() > 6)
01988 return 0;
01989 CArray2d<int, 2, 2> count = {{{{ 0 }}}};
01990 for (int x=std::max(1, king.x()-2); x<=std::min(9, king.x()+2); ++x) {
01991 for (int y=king.y()-2*sign(KingOwner); 1; y-=sign(KingOwner)) {
01992 const Piece p = state.pieceAt(Square(x, y));
01993 if (p.isEdge())
01994 break;
01995 if (p.isEmpty())
01996 continue;
01997 count[p.owner() == KingOwner][p.ptype() == PAWN]++;
01998 }
01999 }
02000 const int c = king.squareForBlack(KingOwner).y() - 4;
02001 return table[c*(std::min(7, count[0][0]))] * sign(KingOwner)
02002 + table[c*(8 +std::min(7, count[0][1]))] * sign(KingOwner)
02003 + table[c*(16+std::min(7, count[1][0]))] * sign(KingOwner)
02004 + table[c*(24+std::min(7, count[1][1]))] * sign(KingOwner);
02005 }
02006
02007 int osl::eval::ml::
02008 EnterKingDefense::eval(const NumEffectState &state)
02009 {
02010 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
02011 }
02012
02013 osl::CArray<int, (8+8+8+8)*3> osl::eval::ml::EnterKingDefense::table;
02014 void osl::eval::ml::
02015 EnterKingDefense::setUp(const Weights & weights)
02016 {
02017 for (size_t i=0; i<weights.dimension(); ++i)
02018 table[i] = weights.value(i);
02019 }
02020
02021
02022
02023 namespace osl
02024 {
02025 namespace eval
02026 {
02027 namespace ml
02028 {
02029 template MultiInt KingPieceRelative::
02030 evalWithUpdate<BLACK>(const NumEffectState &state,
02031 Move moved, MultiInt const& last_value);
02032 template MultiInt KingPieceRelative::
02033 evalWithUpdate<WHITE>(const NumEffectState &state,
02034 Move moved, MultiInt const& last_value);
02035
02036 template class King25EffectEach<0>;
02037 template class King25EffectEach<1>;
02038 template class King25EffectEach<2>;
02039 template class King25EmptyAbs<true>;
02040 template class King25EmptyAbs<false>;
02041
02042 template void King25EffectBoth::countEffectAndPiecesBoth<BLACK>(const NumEffectState&, PieceMask&, PieceMask&, int&, int&, int&, int&, int&, CArray<int, 5>&, CArray<int, 5>&);
02043 template void King25EffectBoth::countEffectAndPiecesBoth<WHITE>(const NumEffectState&, PieceMask&, PieceMask&, int&, int&, int&, int&, int&, CArray<int, 5>&, CArray<int, 5>&);
02044
02045 template MultiInt King25BothSide::
02046 evalOne<BLACK>(const NumEffectState &state, const CArray<int, 5> &effects);
02047 template MultiInt King25BothSide::
02048 evalOne<WHITE>(const NumEffectState &state, const CArray<int, 5> &effects);
02049 }
02050 }
02051 }
02052
02053
02054
02055
02056