00001 #include "osl/eval/king8.h"
00002 #include <cstdlib>
00003 using osl::MultiInt;
00004 using osl::MultiIntPair;
00005
00006 template <bool Opening>
00007 osl::CArray<int, 32> osl::eval::ml::King8EffectEmptySquare<Opening>::table;
00008 template <bool Opening>
00009 osl::CArray<int, 32> osl::eval::ml::King8EffectDefenseSquare<Opening>::table;
00010
00011 osl::CArray<int, 32> osl::eval::ml::King8Effect::empty_table;
00012 osl::CArray<int, 32> osl::eval::ml::King8Effect::defense_table;
00013 osl::CArray<int, 288> osl::eval::ml::King8Effect::empty_y_table;
00014 osl::CArray<int, 288> osl::eval::ml::King8Effect::defense_y_table;
00015
00016 void osl::eval::ml::
00017 King8Effect::setUp(const Weights &weights)
00018 {
00019 for (size_t i = 0; i < empty_table.size(); ++i)
00020 {
00021 empty_table[i] = weights.value(i);
00022 }
00023 for (size_t i = 0; i < defense_table.size(); ++i)
00024 {
00025 defense_table[i] = weights.value(i + empty_table.size());
00026 }
00027 for (size_t i = 0; i < empty_y_table.size(); ++i)
00028 {
00029 empty_y_table[i] = weights.value(i + empty_table.size() +
00030 defense_table.size());
00031 }
00032 for (size_t i = 0; i < defense_y_table.size(); ++i)
00033 {
00034 defense_y_table[i] = weights.value(i + empty_table.size() +
00035 defense_table.size() +
00036 empty_y_table.size());
00037 }
00038 }
00039
00040 int osl::eval::ml::King8Effect::eval(
00041 const NumEffectState &state)
00042 {
00043 int result = 0;
00044 const Piece black_king = state.kingPiece<BLACK>();
00045 const Piece white_king = state.kingPiece<WHITE>();
00046 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00047 {
00048 const Direction dir = static_cast<Direction>(i);
00049 {
00050 EffectState empty, defense;
00051 effectState(state, BLACK, dir, empty, defense);
00052 if (empty != NOT_EMPTY)
00053 {
00054 result -= empty_table[index(dir, empty)];
00055 result -= empty_y_table[indexY(black_king, dir, empty)];
00056 }
00057 if (defense != NOT_EMPTY)
00058 {
00059 result -= defense_table[index(dir, defense)];
00060 result -= defense_y_table[indexY(black_king, dir, defense)];
00061 }
00062 }
00063 {
00064 EffectState empty, defense;
00065 effectState(state, WHITE, dir, empty, defense);
00066 if (empty != NOT_EMPTY)
00067 {
00068 result += empty_table[index(dir, empty)];
00069 result += empty_y_table[indexY(white_king, dir, empty)];
00070 }
00071 if (defense != NOT_EMPTY)
00072 {
00073 result += defense_table[index(dir, defense)];
00074 result += defense_y_table[indexY(white_king, dir, defense)];
00075 }
00076 }
00077 }
00078 return result;
00079 }
00080
00081 int osl::eval::ml::
00082 King8Effect::index(const Direction dir,
00083 EffectState state)
00084 {
00085 return (dir * 4 + state);
00086 }
00087
00088 int osl::eval::ml::
00089 King8Effect::indexY(Piece king,
00090 const Direction dir,
00091 EffectState state)
00092 {
00093 const int y = ((king.owner() == BLACK) ?
00094 king.square().y() : 10 - king.square().y());
00095 return (dir * 4 + state) * 9 + y - 1;
00096 }
00097
00098
00099
00100 void osl::eval::ml::
00101 King8Effect::effectState(const NumEffectState &state,
00102 const Player defenseP,
00103 const Direction dir,
00104 EffectState &empty,
00105 EffectState &defense)
00106 {
00107 const Square target =
00108 Board_Table.nextSquare(defenseP,
00109 state.kingSquare(defenseP),
00110 dir);
00111 if (!state.pieceAt(target).isEmpty())
00112 {
00113 empty = defense = NOT_EMPTY;
00114 return;
00115 }
00116 const int attack_count = state.countEffect(alt(defenseP), target);
00117 const int defense_count = state.countEffect(defenseP, target);
00118 if (attack_count == 0)
00119 {
00120 empty = NO_EFFECT;
00121 defense = NO_EFFECT;
00122 }
00123 else if (defense_count == 1)
00124 {
00125 empty = MORE_EFFECT_KING_ONLY;
00126 }
00127 else if (attack_count >= defense_count)
00128 {
00129 empty = MORE_EFFECT;
00130 }
00131 else
00132 {
00133 empty = LESS_EFFECT;
00134 }
00135 if (defense_count == 1 && attack_count > defense_count)
00136 {
00137 defense = MORE_EFFECT_KING_ONLY;
00138 }
00139 else if (attack_count > defense_count)
00140 {
00141 defense = MORE_EFFECT;
00142 }
00143 else
00144 {
00145 defense = LESS_EFFECT;
00146 }
00147 }
00148
00149
00150
00151 struct osl::eval::ml::King8EffectBase::
00152 MakeEffectStateSimple
00153 {
00154 EffectState operator()(const NumEffectState &state,
00155 const Player defense,
00156 const Direction dir) const
00157 {
00158 const Square target =
00159 Board_Table.nextSquare(defense,
00160 state.kingSquare(defense),
00161 dir);
00162 if (!state.pieceAt(target).isEmpty())
00163 return NOT_EMPTY;
00164
00165 const int attack_count = state.countEffect(alt(defense), target);
00166 if (attack_count == 0)
00167 return NO_EFFECT;
00168 const int defense_count = state.countEffect(defense, target);
00169 if (defense_count == 1)
00170 return MORE_EFFECT_KING_ONLY;
00171 else if (attack_count >= defense_count)
00172 return MORE_EFFECT;
00173 else
00174 return LESS_EFFECT;
00175 }
00176 };
00177
00178 struct osl::eval::ml::King8EffectBase::
00179 MakeEffectStateDefense
00180 {
00181 EffectState operator()(const NumEffectState &state,
00182 const Player defense,
00183 const Direction dir) const
00184 {
00185 const Square target =
00186 Board_Table.nextSquare(defense,
00187 state.kingSquare(defense),
00188 dir);
00189 if (!state.pieceAt(target).isOnBoardByOwner(defense))
00190 return NOT_EMPTY;
00191
00192 const int attack_count = state.countEffect(alt(defense), target);
00193 if (attack_count == 0)
00194 return NO_EFFECT;
00195
00196 const int defense_count = state.countEffect(defense, target);
00197 if (defense_count == 1 && attack_count > defense_count)
00198 return MORE_EFFECT_KING_ONLY;
00199 else if (attack_count > defense_count)
00200 return MORE_EFFECT;
00201 else
00202 return LESS_EFFECT;
00203 }
00204 };
00205
00206 template <class MakeEffectState>
00207 const osl::CArray<int,2>
00208 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00209 __attribute__ ((used))
00210 #endif
00211 osl::eval::ml::
00212 King8EffectBase::evalCommon(const NumEffectState &state, const table_t& table)
00213 {
00214 MakeEffectState f;
00215 CArray<int,2> result = {{0, 0}};
00216 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00217 {
00218 const Direction dir = static_cast<Direction>(i);
00219 const EffectState black_effect_state = f(state, BLACK, dir);
00220 if (black_effect_state != NOT_EMPTY)
00221 {
00222 result[0] -= table[index(dir, black_effect_state)];
00223 }
00224 const EffectState white_effect_state = f(state, WHITE, dir);
00225 if (white_effect_state != NOT_EMPTY)
00226 {
00227 result[1] += table[index(dir, white_effect_state)];
00228 }
00229 }
00230
00231 return result;
00232 }
00233
00234 template <class MakeEffectState>
00235 const osl::CArray<int,2>
00236 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00237 __attribute__ ((used))
00238 #endif
00239 osl::eval::ml::
00240 King8EffectBase::evalWithUpdateCommon(const NumEffectState &new_state, Move last_move,
00241 const CArray<int,2>& last_value, const table_t& table)
00242 {
00243 CArray<int,2> result = last_value;
00244 MakeEffectState f;
00245 BoardMask mask = new_state.changedEffects();
00246 mask.set(last_move.to()); mask.set(last_move.from());
00247 for (int z=0; z<2; ++z)
00248 {
00249 const Player pl = indexToPlayer(z);
00250 const Square king = new_state.kingSquare(pl);
00251 bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
00252 if (! update)
00253 continue;
00254 result[z] = 0;
00255 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00256 {
00257 const Direction dir = static_cast<Direction>(i);
00258 const EffectState effect_state = f(new_state, pl, dir);
00259 if (effect_state != NOT_EMPTY)
00260 {
00261 result[z] -= table[index(dir, effect_state)];
00262 }
00263 }
00264 if (z == 1)
00265 result[1] = -result[1];
00266 }
00267 return result;
00268 }
00269
00270 template <class MakeEffectState>
00271 inline
00272 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
00273 King8EffectBase::evalWithUpdateCommon(const NumEffectState &new_state, Move last_move,
00274 const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
00275 const table_t& table_o, const table_t& table_e)
00276 {
00277 CArray<int,2> result_o = last_value_o, result_e = last_value_e;
00278 MakeEffectState f;
00279 BoardMask mask = new_state.changedEffects();
00280 mask.set(last_move.to()); mask.set(last_move.from());
00281 for (int z=0; z<2; ++z)
00282 {
00283 const Player pl = indexToPlayer(z);
00284 const Square king = new_state.kingSquare(pl);
00285 bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
00286 if (! update)
00287 continue;
00288 result_o[z] = result_e[z] = 0;
00289 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00290 {
00291 const Direction dir = static_cast<Direction>(i);
00292 const EffectState effect_state = f(new_state, pl, dir);
00293 if (effect_state != NOT_EMPTY)
00294 {
00295 result_o[z] -= table_o[index(dir, effect_state)];
00296 result_e[z] -= table_e[index(dir, effect_state)];
00297 }
00298 }
00299 if (z == 1)
00300 {
00301 result_o[1] = -result_o[1];
00302 result_e[1] = -result_e[1];
00303 }
00304 }
00305 return std::make_pair(result_o, result_e);
00306 }
00307
00308 template <bool Opening>
00309 void osl::eval::ml::
00310 King8EffectEmptySquare<Opening>::setUp(const Weights &weights)
00311 {
00312 table.fill(0);
00313 for (size_t i = 0; i < weights.dimension(); ++i)
00314 {
00315 table[i] = weights.value(i);
00316 }
00317 }
00318
00319 template <bool Opening>
00320 const osl::CArray<int,2> osl::eval::ml::
00321 King8EffectEmptySquare<Opening>::eval(const NumEffectState &state)
00322 {
00323 return evalCommon<MakeEffectStateSimple>(state, table);
00324 }
00325 template <bool Opening>
00326 const osl::CArray<int,2> osl::eval::ml::
00327 King8EffectEmptySquare<Opening>::evalWithUpdate(const NumEffectState &new_state, Move last_move,
00328 const CArray<int,2>& last_value)
00329 {
00330 return evalWithUpdateCommon<MakeEffectStateSimple>
00331 (new_state, last_move, last_value, table);
00332 }
00333
00334 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
00335 osl::eval::ml::King8EffectEmptySquareBoth::
00336 evalWithUpdate(const NumEffectState &new_state, Move last_move,
00337 const CArray<int,2>& last_value_opening,
00338 const CArray<int,2>& last_value_ending)
00339 {
00340 return evalWithUpdateCommon<MakeEffectStateSimple>
00341 (new_state, last_move, last_value_opening, last_value_ending,
00342 King8EffectEmptySquare<true>::table, King8EffectEmptySquare<false>::table);
00343 }
00344
00345
00346 template <bool Opening>
00347 void osl::eval::ml::
00348 King8EffectDefenseSquare<Opening>::setUp(const Weights &weights)
00349 {
00350 table.fill(0);
00351 for (size_t i = 0; i < weights.dimension(); ++i)
00352 {
00353 table[i] = weights.value(i);
00354 }
00355 }
00356 template <bool Opening>
00357 const osl::CArray<int,2> osl::eval::ml::
00358 King8EffectDefenseSquare<Opening>::eval(const NumEffectState &state)
00359 {
00360 return evalCommon<MakeEffectStateDefense>(state, table);
00361 }
00362 template <bool Opening>
00363 const osl::CArray<int,2> osl::eval::ml::
00364 King8EffectDefenseSquare<Opening>::evalWithUpdate(const NumEffectState &new_state, Move last_move,
00365 const CArray<int,2>& last_value)
00366 {
00367 return evalWithUpdateCommon<MakeEffectStateDefense>
00368 (new_state, last_move, last_value, table);
00369 }
00370
00371
00372 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
00373 osl::eval::ml::King8EffectDefenseSquareBoth::
00374 evalWithUpdate(const NumEffectState &new_state, Move last_move,
00375 const CArray<int,2>& last_value_opening,
00376 const CArray<int,2>& last_value_ending)
00377 {
00378 return evalWithUpdateCommon<MakeEffectStateDefense>
00379 (new_state, last_move, last_value_opening, last_value_ending,
00380 King8EffectDefenseSquare<true>::table, King8EffectDefenseSquare<false>::table);
00381 }
00382
00383
00384
00385 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00386 osl::eval::ml::King8EffectAll::base_table;
00387 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00388 osl::eval::ml::King8EffectAll::u_table;
00389 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00390 osl::eval::ml::King8EffectAll::d_table;
00391 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00392 osl::eval::ml::King8EffectAll::l_table;
00393 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00394 osl::eval::ml::King8EffectAll::r_table;
00395
00396 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00397 osl::eval::ml::King8EffectAll::base_defense_piece_table;
00398 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00399 osl::eval::ml::King8EffectAll::u_defense_piece_table;
00400 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00401 osl::eval::ml::King8EffectAll::d_defense_piece_table;
00402 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00403 osl::eval::ml::King8EffectAll::l_defense_piece_table;
00404 osl::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00405 osl::eval::ml::King8EffectAll::r_defense_piece_table;
00406
00407 void osl::eval::ml::
00408 King8EffectAll::setUp(const Weights &weights)
00409 {
00410 base_table.fill(0);
00411 u_table.fill(0);
00412 d_table.fill(0);
00413 l_table.fill(0);
00414 r_table.fill(0);
00415 base_defense_piece_table.fill(0);
00416 u_defense_piece_table.fill(0);
00417 d_defense_piece_table.fill(0);
00418 l_defense_piece_table.fill(0);
00419 r_defense_piece_table.fill(0);
00420 for (size_t i = 0; i < ONE_DIM; ++i)
00421 {
00422 base_table[i] = weights.value(i);
00423 u_table[i] = weights.value(i+ONE_DIM);
00424 d_table[i] = weights.value(i+ONE_DIM*2);
00425 l_table[i] = weights.value(i+ONE_DIM*3);
00426 r_table[i] = weights.value(i+ONE_DIM*4);
00427 base_defense_piece_table[i] = weights.value(i+ONE_DIM*5);
00428 u_defense_piece_table[i] = weights.value(i+ONE_DIM*6);
00429 d_defense_piece_table[i] = weights.value(i+ONE_DIM*7);
00430 l_defense_piece_table[i] = weights.value(i+ONE_DIM*8);
00431 r_defense_piece_table[i] = weights.value(i+ONE_DIM*9);
00432 }
00433 }
00434
00435 void
00436 osl::eval::ml::King8EffectAll::effectState(
00437 const NumEffectState &state,
00438 const Player defense,
00439 const Direction dir,
00440 EffectState &empty, EffectState &defense_effect)
00441 {
00442 empty = NOT_EMPTY;
00443 defense_effect = NOT_EMPTY;
00444 const Square target =
00445 Board_Table.nextSquare(defense,
00446 state.kingSquare(defense),
00447 dir);
00448 const Piece piece = state.pieceAt(target);
00449 if (!target.isOnBoard() ||
00450 piece.isOnBoardByOwner(alt(defense)))
00451 return;
00452
00453 const int attack_count = state.countEffect(alt(defense), target);
00454 const int defense_count = state.countEffect(defense, target);
00455
00456 if (piece.isEmpty())
00457 {
00458 if (attack_count == 0)
00459 empty = NO_EFFECT;
00460 else if (defense_count == 1)
00461 empty = MORE_EFFECT_KING_ONLY;
00462 else if (attack_count >= defense_count)
00463 empty = MORE_EFFECT;
00464 else
00465 empty = LESS_EFFECT;
00466 }
00467 else
00468 {
00469 if (attack_count == 0)
00470 defense_effect = NO_EFFECT;
00471 else if (defense_count == 1 && attack_count > defense_count)
00472 defense_effect = MORE_EFFECT_KING_ONLY;
00473 else if (attack_count > defense_count)
00474 defense_effect = MORE_EFFECT;
00475 else
00476 defense_effect = LESS_EFFECT;
00477 }
00478 }
00479
00480 int osl::eval::ml::
00481 King8EffectAll::index(const Direction dir, EffectState state)
00482 {
00483 return dir * 4 + state;
00484 }
00485
00486 int osl::eval::ml::
00487 King8EffectAll::eval(const NumEffectState &state,
00488 PieceMask , PieceMask )
00489 {
00490 int result = 0;
00491 osl::checkmate::King8Info black_king(state.Iking8Info(BLACK));
00492 const int black_liberty = black_king.liberty();
00493 const bool black_u_blocked =
00494 (black_liberty & ((DirectionTraits<UL>::mask |
00495 DirectionTraits<U>::mask |
00496 DirectionTraits<UR>::mask))) == 0;
00497 const bool black_d_blocked =
00498 (black_liberty & ((DirectionTraits<DL>::mask |
00499 DirectionTraits<D>::mask |
00500 DirectionTraits<DR>::mask))) == 0;
00501 const bool black_l_blocked =
00502 (black_liberty & ((DirectionTraits<UL>::mask |
00503 DirectionTraits<L>::mask |
00504 DirectionTraits<DL>::mask))) == 0;
00505 const bool black_r_blocked =
00506 (black_liberty & ((DirectionTraits<UR>::mask |
00507 DirectionTraits<R>::mask |
00508 DirectionTraits<DR>::mask))) == 0;
00509 osl::checkmate::King8Info white_king(state.Iking8Info(WHITE));
00510 const int white_liberty = white_king.liberty();
00511 const bool white_u_blocked =
00512 (white_liberty & ((DirectionTraits<UL>::mask |
00513 DirectionTraits<U>::mask |
00514 DirectionTraits<UR>::mask))) == 0;
00515 const bool white_d_blocked =
00516 (white_liberty & ((DirectionTraits<DL>::mask |
00517 DirectionTraits<D>::mask |
00518 DirectionTraits<DR>::mask))) == 0;
00519 const bool white_l_blocked =
00520 (white_liberty & ((DirectionTraits<UL>::mask |
00521 DirectionTraits<L>::mask |
00522 DirectionTraits<DL>::mask))) == 0;
00523 const bool white_r_blocked =
00524 (white_liberty & ((DirectionTraits<UR>::mask |
00525 DirectionTraits<R>::mask |
00526 DirectionTraits<DR>::mask))) == 0;
00527
00528 for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00529 {
00530 const Direction dir = static_cast<Direction>(i);
00531 EffectState black_empty_effect_state,
00532 black_defense_effect_state;
00533 effectState(state, BLACK, dir,
00534 black_empty_effect_state, black_defense_effect_state);
00535 if (black_empty_effect_state != NOT_EMPTY)
00536 {
00537 const int idx = index(dir, black_empty_effect_state);
00538 result -= base_table[idx];
00539 if (black_u_blocked)
00540 result -= u_table[idx];
00541 if (black_d_blocked)
00542 result -= d_table[idx];
00543 if (black_l_blocked)
00544 result -= l_table[idx];
00545 if (black_r_blocked)
00546 result -= r_table[idx];
00547 }
00548 if (black_defense_effect_state != NOT_EMPTY)
00549 {
00550 const int idx = index(dir, black_defense_effect_state);
00551 result -= base_defense_piece_table[idx];
00552 if (black_u_blocked)
00553 result -= u_defense_piece_table[idx];
00554 if (black_d_blocked)
00555 result -= d_defense_piece_table[idx];
00556 if (black_l_blocked)
00557 result -= l_defense_piece_table[idx];
00558 if (black_r_blocked)
00559 result -= r_defense_piece_table[idx];
00560 }
00561 EffectState white_empty_effect_state,
00562 white_defense_effect_state;
00563 effectState(state, WHITE, dir,
00564 white_empty_effect_state, white_defense_effect_state);
00565 if (white_empty_effect_state != NOT_EMPTY)
00566 {
00567 const int idx = index(dir, white_empty_effect_state);
00568 result += base_table[idx];
00569 if (white_u_blocked)
00570 result += u_table[idx];
00571 if (white_d_blocked)
00572 result += d_table[idx];
00573 if (white_l_blocked)
00574 result += l_table[idx];
00575 if (white_r_blocked)
00576 result += r_table[idx];
00577 }
00578 if (white_defense_effect_state != NOT_EMPTY)
00579 {
00580 const int idx = index(dir, white_defense_effect_state);
00581 result += base_defense_piece_table[idx];
00582 if (white_u_blocked)
00583 result += u_defense_piece_table[idx];
00584 if (white_d_blocked)
00585 result += d_defense_piece_table[idx];
00586 if (white_l_blocked)
00587 result += l_defense_piece_table[idx];
00588 if (white_r_blocked)
00589 result += r_defense_piece_table[idx];
00590 }
00591 }
00592
00593 return result;
00594 }
00595
00596
00597 osl::CArray<MultiInt, osl::eval::ml::KingXBothBlocked::ONE_DIM>
00598 osl::eval::ml::KingXBothBlocked::table;
00599 osl::CArray<MultiInt, osl::eval::ml::KingXBothBlockedY::ONE_DIM>
00600 osl::eval::ml::KingXBothBlockedY::table;
00601
00602 void osl::eval::ml::
00603 KingXBothBlocked::setUp(const Weights &weights)
00604 {
00605 for (int i = 0; i < ONE_DIM; ++i)
00606 {
00607 for (int s=0; s<NStages; ++s)
00608 table[i][s] = weights.value(i + ONE_DIM*s);
00609 }
00610 }
00611
00612 void osl::eval::ml::
00613 KingXBothBlockedY::setUp(const Weights &weights)
00614 {
00615 for (int i = 0; i < ONE_DIM; ++i)
00616 {
00617 for (int s=0; s<NStages; ++s)
00618 table[i][s] = weights.value(i + ONE_DIM*s);
00619 }
00620 }
00621
00622 template <int Sign>
00623 inline
00624 void osl::eval::ml::
00625 KingXBothBlocked::adjust(int index, int index_y, MultiInt &out)
00626 {
00627 if(Sign>0)
00628 out += KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
00629 else
00630 out -= KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
00631 }
00632
00633 MultiIntPair osl::eval::ml::
00634 KingXBothBlocked::eval(const NumEffectState &state)
00635 {
00636 MultiIntPair result;
00637 King8Info black(state.Iking8Info(BLACK));
00638 if ((black.liberty() & (DirectionTraits<UL>::mask |
00639 DirectionTraits<L>::mask |
00640 DirectionTraits<DL>::mask |
00641 DirectionTraits<UR>::mask |
00642 DirectionTraits<R>::mask |
00643 DirectionTraits<DR>::mask)) == 0)
00644 {
00645 const Square black_king = state.kingSquare<BLACK>();
00646 adjust<1>(index(black_king),
00647 indexY<BLACK>(black_king),
00648 result[BLACK]);
00649 }
00650
00651 King8Info white(state.Iking8Info(WHITE));
00652 if ((white.liberty() & (DirectionTraits<UL>::mask |
00653 DirectionTraits<L>::mask |
00654 DirectionTraits<DL>::mask |
00655 DirectionTraits<UR>::mask |
00656 DirectionTraits<R>::mask |
00657 DirectionTraits<DR>::mask)) == 0)
00658 {
00659 const Square white_king = state.kingSquare<WHITE>();
00660 adjust<-1>(index(white_king),
00661 indexY<WHITE>(white_king),
00662 result[WHITE]);
00663 }
00664
00665 return result;
00666 }
00667
00668 template <osl::Player P>
00669 int osl::eval::ml::KingXBlockedBase::index(
00670 Square king, int diff)
00671 {
00672 const int king_x = king.x();
00673 if (P == BLACK)
00674 {
00675 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00676 int x_diff = diff;
00677 if (king_x >= 6)
00678 x_diff = -x_diff;
00679 return target_x - 1 + ((x_diff == 1) ? 0 : 5);
00680 }
00681 else
00682 {
00683 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00684 int x_diff = diff;
00685 if (king_x >= 5)
00686 x_diff = -x_diff;
00687 return target_x - 1 + ((x_diff == 1) ? 0 : 5);
00688 }
00689 }
00690
00691 template <osl::Player P>
00692 bool osl::eval::ml::KingXBlockedBase::isBlocked(
00693 const NumEffectState &state,
00694 int diff)
00695 {
00696 #if 1
00697 const King8Info info(state.Iking8Info(P));
00698 if ((diff == 1) ^ (P == BLACK))
00699 return (info.liberty() & (DirectionTraits<UR>::mask
00700 | DirectionTraits<R>::mask
00701 | DirectionTraits<DR>::mask)) == 0;
00702 assert((diff == 1 && P == BLACK) || (diff == -1 && P == WHITE));
00703 return (info.liberty() & (DirectionTraits<UL>::mask
00704 | DirectionTraits<L>::mask
00705 | DirectionTraits<DL>::mask)) == 0;
00706 #else
00707 const Square pos = state.kingSquare<P>();
00708 const int target_x = pos.x() + diff;
00709 for (int y = pos.y() - 1; y <= pos.y() + 1; ++y)
00710 {
00711 Square target(target_x, y);
00712 Piece p(state.pieceAt(target));
00713 if ((!p.isEdge()) && ! p.isOnBoardByOwner<P>() &&
00714 !state.hasEffectAt<alt(P)>(target))
00715 {
00716 return false;
00717 }
00718 }
00719 return true;
00720 #endif
00721 }
00722
00723 const MultiIntPair osl::eval::ml::
00724 KingXBlockedBase::eval(const NumEffectState &state, const table_t& table)
00725 {
00726 MultiIntPair val;
00727 const Square black_king = state.kingSquare<BLACK>();
00728 const Square white_king = state.kingSquare<WHITE>();
00729 const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
00730 if (isBlocked<BLACK>(state, 1))
00731 val[b] += table[index<BLACK>(black_king, 1)];
00732 if (isBlocked<BLACK>(state, -1))
00733 val[b] += table[index<BLACK>(black_king, -1)];
00734
00735 if (isBlocked<WHITE>(state, 1))
00736 val[w] -= table[index<WHITE>(white_king, 1)];
00737 if (isBlocked<WHITE>(state, -1))
00738 val[w] -= table[index<WHITE>(white_king, -1)];
00739 return val;
00740 }
00741
00742 const MultiIntPair osl::eval::ml::
00743 KingXBlockedYBase::eval(const NumEffectState &state,
00744 const table_t& table)
00745 {
00746 MultiIntPair val;
00747 const Square black_king = state.kingSquare<BLACK>();
00748 const Square white_king = state.kingSquare<WHITE>();
00749 const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
00750 const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(state, 1);
00751 const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(state, -1);
00752 if (black_r_blocked)
00753 val[b] += table[index<BLACK>(black_king, 1)];
00754 if (black_l_blocked)
00755 val[b] += table[index<BLACK>(black_king, -1)];
00756
00757 const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(state, 1);
00758 const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(state, -1);
00759 if (white_r_blocked)
00760 val[w] -= table[index<WHITE>(white_king, 1)];
00761 if (white_l_blocked)
00762 val[w] -= table[index<WHITE>(white_king, -1)];
00763 return val;
00764 }
00765
00766 #if 0
00767 inline
00768 std::pair<osl::CArray<int,2>,osl::CArray<int,2> >
00769 osl::eval::ml::
00770 KingXBlockedBase::evalWithUpdate(const NumEffectState &new_state, Move last_move,
00771 const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
00772 const table_t& table_o, const table_t& table_e)
00773 {
00774 CArray<int,2> val_o = last_value_o;
00775 CArray<int,2> val_e = last_value_e;
00776 const Square black_king = new_state.kingSquare<BLACK>();
00777 const Square white_king = new_state.kingSquare<WHITE>();
00778 BoardMask mask = new_state.changedEffects();
00779 mask.set(last_move.from()); mask.set(last_move.to());
00780 if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king)))
00781 {
00782 const int b = playerToIndex(BLACK);
00783 val_o[b] = val_e[b]= 0;
00784 if (isBlocked<BLACK>(new_state, 1)) {
00785 val_o[b] += table_o[index<BLACK>(black_king, 1)];
00786 val_e[b] += table_e[index<BLACK>(black_king, 1)];
00787 }
00788 if (isBlocked<BLACK>(new_state, -1)) {
00789 val_o[b] += table_o[index<BLACK>(black_king, -1)];
00790 val_e[b] += table_e[index<BLACK>(black_king, -1)];
00791 }
00792 }
00793 if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
00794 {
00795 const int w = playerToIndex(WHITE);
00796 val_o[w] = val_e[w]= 0;
00797 if (isBlocked<WHITE>(new_state, 1)) {
00798 val_o[w] -= table_o[index<WHITE>(white_king, 1)];
00799 val_e[w] -= table_e[index<WHITE>(white_king, 1)];
00800 }
00801 if (isBlocked<WHITE>(new_state, -1)) {
00802 val_o[w] -= table_o[index<WHITE>(white_king, -1)];
00803 val_e[w] -= table_e[index<WHITE>(white_king, -1)];
00804 }
00805 }
00806 return std::make_pair(val_o, val_e);
00807 }
00808 #endif
00809
00810 template <int Sign>
00811 inline
00812 void osl::eval::ml::
00813 KingXBlockedYBase::adjust(int index, int index_y, MultiInt &out)
00814 {
00815 if(Sign>0)
00816 out += KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
00817 else
00818 out -= KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
00819 }
00820
00821 inline
00822 void
00823 osl::eval::ml::
00824 KingXBlockedYBase::evalWithUpdateBang(const NumEffectState &new_state,
00825 Move last_move,
00826 MultiIntPair& values)
00827 {
00828 const Square black_king = new_state.kingSquare<BLACK>();
00829 const Square white_king = new_state.kingSquare<WHITE>();
00830 BoardMask mask = new_state.changedEffects();
00831 mask.set(last_move.from()); mask.set(last_move.to());
00832 if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king)))
00833 {
00834 values[BLACK].clear();
00835 const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, 1);
00836 const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, -1);
00837 if (black_r_blocked) {
00838 adjust<1>(KingXBlockedBase::index<BLACK>(black_king, 1),
00839 index<BLACK>(black_king, 1),
00840 values[BLACK]);
00841 }
00842 if (black_l_blocked) {
00843 adjust<1>(KingXBlockedBase::index<BLACK>(black_king, -1),
00844 index<BLACK>(black_king, -1),
00845 values[BLACK]);
00846 }
00847 if (black_r_blocked && black_l_blocked)
00848 {
00849 KingXBothBlocked::adjust<1>(KingXBothBlocked::index(black_king),
00850 KingXBothBlocked::indexY<BLACK>(black_king),
00851 values[BLACK]);
00852 }
00853 }
00854 if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
00855 {
00856 values[WHITE].clear();
00857 const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, 1);
00858 const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, -1);
00859 if (white_r_blocked) {
00860 adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, 1),
00861 index<WHITE>(white_king, 1),
00862 values[WHITE]);
00863 }
00864 if (white_l_blocked) {
00865 adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, -1),
00866 index<WHITE>(white_king, -1),
00867 values[WHITE]);
00868 }
00869 if (white_r_blocked && white_l_blocked)
00870 {
00871 KingXBothBlocked::adjust<-1>(KingXBothBlocked::index(white_king),
00872 KingXBothBlocked::indexY<WHITE>(white_king),
00873 values[WHITE]);
00874 }
00875 }
00876 }
00877
00878 template <osl::Player P> inline
00879 int osl::eval::ml::KingXBlockedYBase::index(
00880 Square king, int diff)
00881 {
00882 const int king_x = king.x();
00883 if (P == BLACK)
00884 {
00885 const int king_y = king.y();
00886 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00887 int x_diff = diff;
00888 if (king_x >= 6)
00889 x_diff = -x_diff;
00890 return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
00891 }
00892 else
00893 {
00894 const int king_y = 10 - king.y();
00895 const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00896 int x_diff = diff;
00897 if (king_x >= 5)
00898 x_diff = -x_diff;
00899 return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
00900 }
00901 }
00902
00903 osl::CArray<MultiInt, 10> osl::eval::ml::KingXBlocked::table;
00904 osl::CArray<MultiInt, 90> osl::eval::ml::KingXBlockedY::table;
00905
00906 void osl::eval::ml::
00907 KingXBlocked::setUp(const Weights &weights,int stage)
00908 {
00909 for (size_t i = 0; i < table.size(); ++i)
00910 {
00911 table[i][stage] = weights.value(i);
00912 }
00913 }
00914 void
00915 osl::eval::ml::
00916 KingXBlockedBoth::evalWithUpdateBang(const NumEffectState &new_state, Move last_move,
00917 MultiIntPair& last_values)
00918 {
00919 KingXBlockedYBase::evalWithUpdateBang
00920 (new_state, last_move, last_values);
00921 }
00922
00923 void osl::eval::ml::
00924 KingXBlockedY::setUp(const Weights &weights,int stage)
00925 {
00926 for (size_t i = 0; i < table.size(); ++i)
00927 {
00928 table[i][stage] = weights.value(i);
00929 }
00930 }
00931
00932
00933 osl::CArray<MultiInt, 80> osl::eval::ml::KingXBlocked3::table;
00934 osl::CArray<MultiInt, 720> osl::eval::ml::KingXBlocked3::y_table;
00935
00936 void osl::eval::ml::KingXBlocked3::setUp(const Weights &weights)
00937 {
00938 for (int i = 0; i < ONE_DIM; ++i)
00939 {
00940 for (int s=0; s<NStages; ++s)
00941 table[i][s] = weights.value(i + ONE_DIM*s);
00942 }
00943 }
00944
00945 void osl::eval::ml::KingXBlocked3Y::setUp(const Weights &weights)
00946 {
00947 for (int i = 0; i < ONE_DIM; ++i)
00948 {
00949 for (int s=0; s<NStages; ++s)
00950 KingXBlocked3::y_table[i][s] = weights.value(i + ONE_DIM*s);
00951 }
00952 for(int x=1;x<=5;x++)
00953 for(int y=1;y<=9;y++)
00954 for(int is_l=0;is_l<2;is_l++)
00955 for(int u_blocked=0;u_blocked<2;u_blocked++)
00956 for(int opp_u_blocked=0;opp_u_blocked<2;opp_u_blocked++)
00957 for(int opp_blocked=0;opp_blocked<2;opp_blocked++){
00958 int indexY=x - 1 + 5 * (y - 1 + 9 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1 : 0) + 2 * (opp_blocked ? 1 : 0)))));
00959 int index0=x - 1 + 5 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1 : 0) + 2 * (opp_blocked ? 1 : 0))));
00960 KingXBlocked3::y_table[indexY]+=KingXBlocked3::table[index0];
00961 }
00962 }
00963
00964 MultiInt osl::eval::ml::
00965 KingXBlocked3::eval(const NumEffectState &state)
00966 {
00967 MultiInt result;
00968 King8Info black(state.Iking8Info(BLACK));
00969 if ((black.liberty() & (DirectionTraits<UL>::mask |
00970 DirectionTraits<L>::mask |
00971 DirectionTraits<DL>::mask)) == 0)
00972 {
00973 adjust<1>(
00974 indexY<BLACK>(state.kingSquare<BLACK>(),
00975 true,
00976 (black.liberty() & DirectionTraits<U>::mask) == 0,
00977 (black.liberty() & DirectionTraits<UR>::mask) == 0,
00978 (black.liberty() & DirectionTraits<R>::mask) == 0),
00979 result);
00980 }
00981 if ((black.liberty() & (DirectionTraits<UR>::mask |
00982 DirectionTraits<R>::mask |
00983 DirectionTraits<DR>::mask)) == 0)
00984 {
00985 adjust<1>(
00986 indexY<BLACK>(state.kingSquare<BLACK>(),
00987 false,
00988 (black.liberty() & DirectionTraits<U>::mask) == 0,
00989 (black.liberty() & DirectionTraits<UL>::mask) == 0,
00990 (black.liberty() & DirectionTraits<L>::mask) == 0),
00991 result);
00992 }
00993 King8Info white(state.Iking8Info(WHITE));
00994 if ((white.liberty() & (DirectionTraits<UL>::mask |
00995 DirectionTraits<L>::mask |
00996 DirectionTraits<DL>::mask)) == 0)
00997 {
00998 adjust<-1>(
00999 indexY<WHITE>(state.kingSquare<WHITE>(),
01000 true,
01001 (white.liberty() & DirectionTraits<U>::mask) == 0,
01002 (white.liberty() & DirectionTraits<UR>::mask) == 0,
01003 (white.liberty() & DirectionTraits<R>::mask) == 0),
01004 result);
01005 }
01006 if ((white.liberty() & (DirectionTraits<UR>::mask |
01007 DirectionTraits<R>::mask |
01008 DirectionTraits<DR>::mask)) == 0)
01009 {
01010 adjust<-1>(
01011 indexY<WHITE>(state.kingSquare<WHITE>(),
01012 false,
01013 (white.liberty() & DirectionTraits<U>::mask) == 0,
01014 (white.liberty() & DirectionTraits<UL>::mask) == 0,
01015 (white.liberty() & DirectionTraits<L>::mask) == 0),
01016 result);
01017 }
01018 return result;
01019 }
01020
01021
01022
01023 osl::CArray<MultiInt, 4> osl::eval::ml::AnagumaEmpty::table;
01024
01025
01026 void osl::eval::ml::
01027 AnagumaEmpty::setUp(const Weights &weights,int stage)
01028 {
01029 for (size_t i = 0; i < table.size(); ++i)
01030 {
01031 table[i][stage] = weights.value(i);
01032 }
01033 }
01034
01035
01036 int osl::eval::ml::AnagumaEmpty::index(
01037 Square king, Square target)
01038 {
01039 return std::abs(king.x() - target.x()) + std::abs(king.y() - target.y()) * 2;
01040 }
01041
01042 template <osl::Player Defense>
01043 MultiInt osl::eval::ml::AnagumaEmpty::evalOne(const NumEffectState &state)
01044 {
01045 MultiInt result;
01046 const Square king = state.kingSquare<Defense>();
01047 if ((king.x() == 1 || king.x() == 9) &&
01048 ((Defense == BLACK && king.y() == 9) ||
01049 (Defense == WHITE && king.y() == 1))){
01050 const int x = (king.x() == 1 ? 2 : 8);
01051 const int y = (Defense == BLACK ? 8 : 2);
01052 if(Defense==BLACK){
01053 if (state.pieceAt(Square(king.x(), y)).isEmpty())
01054 result +=table[index(king, Square(king.x(), y))];
01055 if (state.pieceAt(Square(x, y)).isEmpty())
01056 result +=table[index(king, Square(x, y))];
01057 if (state.pieceAt(Square(x, king.y())).isEmpty())
01058 result +=table[index(king, Square(x, king.y()))];
01059 }
01060 else{
01061 if (state.pieceAt(Square(king.x(), y)).isEmpty())
01062 result -=table[index(king, Square(king.x(), y))];
01063 if (state.pieceAt(Square(x, y)).isEmpty())
01064 result -=table[index(king, Square(x, y))];
01065 if (state.pieceAt(Square(x, king.y())).isEmpty())
01066 result -=table[index(king, Square(x, king.y()))];
01067 }
01068 }
01069 return result;
01070 }
01071
01072 MultiInt osl::eval::ml::
01073 AnagumaEmpty::eval(const NumEffectState &state)
01074 {
01075 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
01076 }
01077
01078
01079
01080 namespace osl
01081 {
01082 namespace eval
01083 {
01084 namespace ml
01085 {
01086 template class King8EffectEmptySquare<true>;
01087 template class King8EffectEmptySquare<false>;
01088 template class King8EffectDefenseSquare<true>;
01089 template class King8EffectDefenseSquare<false>;
01090 }
01091 }
01092 }
01093
01094
01095
01096