00001 #include "osl/eval/ml/minorPiece.h"
00002 using osl::MultiInt;
00003
00004 void osl::eval::ml::PawnDropX::setUp(const Weights &weights)
00005 {
00006 for (size_t i = 0; i < ONE_DIM; ++i)
00007 {
00008 for (int s=0; s<NStages; ++s)
00009 PawnDropBoth::x_table[i][s] = weights.value(i+ONE_DIM*s);
00010 }
00011 }
00012
00013 osl::misc::CArray<osl::MultiInt, 9>
00014 osl::eval::ml::PawnDropBoth::attack_table;
00015 osl::misc::CArray<osl::MultiInt, 9>
00016 osl::eval::ml::PawnDropBoth::defense_table;
00017 osl::misc::CArray<osl::MultiInt, 81>
00018 osl::eval::ml::PawnDropBoth::attack_y_table;
00019 osl::misc::CArray<osl::MultiInt, 81>
00020 osl::eval::ml::PawnDropBoth::defense_y_table;
00021 osl::misc::CArray<osl::MultiInt, 90>
00022 osl::eval::ml::PawnDropBoth::x_table;
00023 osl::misc::CArray<osl::MultiInt, 18>
00024 osl::eval::ml::PawnDropBoth::stand_table;
00025 osl::misc::CArray<osl::MultiInt, 90>
00026 osl::eval::ml::PawnDropBoth::x_stand_table;
00027 osl::misc::CArray<osl::MultiInt, 162>
00028 osl::eval::ml::PawnDropBoth::y_stand_table;
00029 osl::misc::CArray<osl::MultiInt, 10>
00030 osl::eval::ml::PawnDropBoth::drop_non_drop_table;
00031 osl::misc::CArray<osl::MultiInt, 36>
00032 osl::eval::ml::PawnDropBoth::state_king_relative_table;
00033
00034 void osl::eval::ml::PawnDrop::setUp(const Weights &weights,int stage)
00035 {
00036 for (int i = 0; i < ONE_DIM; ++i)
00037 {
00038 PawnDropBoth::defense_table[i][stage] = weights.value(i);
00039 PawnDropBoth::attack_table[i][stage] = weights.value(i + ONE_DIM);
00040 }
00041 }
00042
00043 void osl::eval::ml::PawnDropY::setUp(const Weights &weights,int stage)
00044 {
00045 for (int i = 0; i < ONE_DIM; ++i)
00046 {
00047 PawnDropBoth::attack_y_table[i][stage] = weights.value(i);
00048 PawnDropBoth::defense_y_table[i][stage] = weights.value(i + ONE_DIM);
00049 }
00050 }
00051
00052 void osl::eval::ml::PawnDropPawnStand::setUp(const Weights &weights)
00053 {
00054 for (int i = 0; i < ONE_DIM; ++i)
00055 {
00056 for (int s=0; s<NStages; ++s)
00057 PawnDropBoth::stand_table[i][s] = weights.value(i + ONE_DIM*s);
00058 }
00059 }
00060
00061 void osl::eval::ml::PawnDropPawnStandX::setUp(const Weights &weights)
00062 {
00063 for (int i = 0; i < ONE_DIM; ++i)
00064 {
00065 for (int s=0; s<NStages; ++s)
00066 PawnDropBoth::x_stand_table[i][s] = weights.value(i + ONE_DIM*s);
00067 }
00068 }
00069 void osl::eval::ml::PawnDropPawnStandY::setUp(const Weights &weights)
00070 {
00071 for (int i = 0; i < ONE_DIM; ++i)
00072 {
00073 for (int s=0; s<NStages; ++s)
00074 PawnDropBoth::y_stand_table[i][s] = weights.value(i + ONE_DIM*s);
00075 }
00076 }
00077
00078 void osl::eval::ml::PawnDropNonDrop::setUp(const Weights &weights)
00079 {
00080 for (int i = 0; i < ONE_DIM; ++i)
00081 {
00082 for (int s=0; s<NStages; ++s)
00083 PawnDropBoth::drop_non_drop_table[i][s] = weights.value(i + ONE_DIM*s);
00084 }
00085 }
00086
00087 void osl::eval::ml::PawnStateKingRelative::setUp(const Weights &weights)
00088 {
00089 for (int i = 0; i < ONE_DIM; ++i)
00090 {
00091 for (int s=0; s<NStages; ++s)
00092 PawnDropBoth::state_king_relative_table[i][s] = weights.value(i + ONE_DIM*s);
00093 }
00094 }
00095
00096 osl::MultiInt osl::eval::ml::PawnDropBoth::eval(
00097 const NumEffectState &state)
00098 {
00099 osl::MultiInt result;
00100 CArray<Position, 2> kings = {{state.getKingPosition<BLACK>(),
00101 state.getKingPosition<WHITE>()}};
00102 CArray<Piece, 2> king_piece = {{state.getKingPiece<BLACK>(),
00103 state.getKingPiece<WHITE>()}};
00104 CArray<bool, 2> has_pawn = {{state.hasPieceOnStand<PAWN>(BLACK),
00105 state.hasPieceOnStand<PAWN>(WHITE)}};
00106 for (int x = 1; x <= 9; ++x)
00107 {
00108 const bool black_on_board = state.isPawnMaskSet<BLACK>(x);
00109 const bool white_on_board = state.isPawnMaskSet<WHITE>(x);
00110 if (!black_on_board)
00111 {
00112 const int attack_index = index(kings[WHITE], x);
00113 const int defense_index = index(kings[BLACK], x);
00114 const int attack_index_x =
00115 indexX<true>(king_piece[WHITE], x);
00116 const int defense_index_x =
00117 indexX<false>(king_piece[BLACK], x);
00118 const int attack_index_y = indexY<WHITE>(king_piece[WHITE], x);
00119 const int defense_index_y = indexY<BLACK>(king_piece[BLACK], x);
00120 result += value(attack_index, defense_index,
00121 attack_index_y, defense_index_y,
00122 attack_index_x, defense_index_x);
00123 if (has_pawn[BLACK])
00124 {
00125 result += standValue(attack_index, defense_index,
00126 attack_index_y, defense_index_y,
00127 attack_index_x, defense_index_x);
00128 }
00129 }
00130 if (!white_on_board)
00131 {
00132 const int attack_index = index(kings[BLACK], x);
00133 const int defense_index = index(kings[WHITE], x);
00134 const int attack_index_x =
00135 indexX<true>(king_piece[BLACK], x);
00136 const int defense_index_x =
00137 indexX<false>(king_piece[WHITE], x);
00138 const int attack_index_y = indexY<BLACK>(king_piece[BLACK], x);
00139 const int defense_index_y = indexY<WHITE>(king_piece[WHITE], x);
00140 result -= value(attack_index, defense_index,
00141 attack_index_y, defense_index_y,
00142 attack_index_x, defense_index_x);
00143 if (has_pawn[WHITE])
00144 {
00145 result -= standValue(attack_index, defense_index,
00146 attack_index_y, defense_index_y,
00147 attack_index_x, defense_index_x);
00148 }
00149 }
00150 const int index_x = (x > 5 ? 10 - x : x);
00151 if (black_on_board && white_on_board)
00152 {
00153 result +=
00154 state_king_relative_table[std::abs(kings[BLACK].x() - x) +
00155 BOTH_ON_BOARD * 9];
00156 result -=
00157 state_king_relative_table[std::abs(kings[WHITE].x() - x) +
00158 BOTH_ON_BOARD * 9];
00159 }
00160 else if (black_on_board && !white_on_board)
00161 {
00162 result += drop_non_drop_table[index_x - 1];
00163 result -= drop_non_drop_table[index_x - 1 + 5];
00164 result +=
00165 state_king_relative_table[std::abs(kings[BLACK].x() - x) +
00166 SELF_ON_BOARD * 9];
00167 result -=
00168 state_king_relative_table[std::abs(kings[WHITE].x() - x) +
00169 OPP_ON_BOARD * 9];
00170 }
00171 else if (!black_on_board && white_on_board)
00172 {
00173 result += drop_non_drop_table[index_x - 1 + 5];
00174 result -= drop_non_drop_table[index_x - 1];
00175 result +=
00176 state_king_relative_table[std::abs(kings[BLACK].x() - x) +
00177 OPP_ON_BOARD * 9];
00178 result -=
00179 state_king_relative_table[std::abs(kings[WHITE].x() - x) +
00180 SELF_ON_BOARD * 9];
00181 }
00182 else
00183 {
00184 result +=
00185 state_king_relative_table[std::abs(kings[BLACK].x() - x) +
00186 BOTH_ON_STAND * 9];
00187 result -=
00188 state_king_relative_table[std::abs(kings[WHITE].x() - x) +
00189 BOTH_ON_STAND * 9];
00190 }
00191 }
00192 return result;
00193 }
00194
00195
00196
00197 osl::MultiInt osl::eval::ml::NoPawnOnStand::weight;
00198
00199 void osl::eval::ml::
00200 NoPawnOnStand::setUp(const Weights &weights,int stage)
00201 {
00202 weight[stage] = weights.value(0);
00203 }
00204
00205
00206
00207 osl::misc::CArray<osl::MultiInt, 9> osl::eval::ml::PawnAdvance::table;
00208
00209 void osl::eval::ml::
00210 PawnAdvance::setUp(const Weights &weights,int stage)
00211 {
00212 for (size_t i = 0; i < weights.dimension(); ++i) {
00213 table[i][stage] = weights.value(i);
00214 }
00215 }
00216
00217 osl::MultiInt osl::eval::ml::PawnAdvance::eval(
00218 const NumEffectState &state)
00219 {
00220 MultiInt result;
00221 for (int i = PtypeTraits<PAWN>::indexMin;
00222 i < PtypeTraits<PAWN>::indexLimit; ++i)
00223 {
00224 const Piece pawn = state.getPieceOf(i);
00225 if (pawn.isOnBoard() && !pawn.isPromoted() &&
00226 cantAdvance(state, pawn))
00227 {
00228 if (pawn.owner() == BLACK)
00229 result += table[index(BLACK, pawn.position())];
00230 else
00231 result -= table[index(WHITE, pawn.position())];
00232 }
00233 }
00234 return result;
00235 }
00236
00237 template <osl::Player P> inline
00238 void osl::eval::ml::
00239 PawnAdvanceAll::adjust(int index, MultiInt& values)
00240 {
00241 if(P==BLACK)
00242 values += PawnAdvance::table[index];
00243 else
00244 values -= PawnAdvance::table[index];
00245 }
00246
00247 template <osl::Player P>
00248 void osl::eval::ml::
00249 PawnAdvanceAll::evalWithUpdateBang(const osl::state::NumEffectState &state,
00250 osl::Move moved, MultiInt& values)
00251 {
00252 assert(moved.player() == P);
00253 if (moved.ptype() == PAWN)
00254 {
00255 if (cantAdvance(state, moved.ptypeO(), moved.to()))
00256 {
00257 adjust<P>(index(P, moved.to()), values);
00258 return;
00259 }
00260 }
00261 const Player Opponent = PlayerTraits<P>::opponent;
00262 Ptype captured = moved.capturePtype();
00263 if (captured == PAWN)
00264 {
00265 if (cantAdvance(state, moved.capturePtypeO(), moved.to()))
00266 adjust<P>(index(Opponent, moved.to()), values);
00267 }
00268 else if (captured != PTYPE_EMPTY)
00269 {
00270 const Piece piece = state.getPieceAt(
00271 moved.to() + DirectionPlayerTraits<D, Opponent>::offset());
00272 if (piece.isOnBoardByOwner<Opponent>() &&
00273 piece.ptype() == PAWN)
00274 adjust<P>(index(Opponent, piece.position()), values);
00275 }
00276 if (!moved.isDrop())
00277 {
00278 const Piece piece = state.getPieceAt(
00279 moved.from() + DirectionPlayerTraits<D, P>::offset());
00280 if (piece.isOnBoardByOwner<P>() &&
00281 piece.ptype() == PAWN)
00282 adjust<Opponent>(index(P, piece.position()), values);
00283 }
00284 {
00285 const Piece piece = state.getPieceAt(
00286 moved.to()+DirectionPlayerTraits<D,P>::offset());
00287 if (piece.isOnBoardByOwner<P>() &&
00288 piece.ptype() == PAWN)
00289 adjust<P>(index(P, piece.position()), values);
00290 }
00291 }
00292
00293
00294
00295 osl::misc::CArray<osl::MultiInt, 153>
00296 osl::eval::ml::SilverFeatures::head_table;
00297 osl::misc::CArray<osl::MultiInt, 9>
00298 osl::eval::ml::SilverFeatures::retreat_table;
00299
00300 void osl::eval::ml::
00301 SilverHeadPawnKingRelative::setUp(const Weights &weights)
00302 {
00303 for (size_t i = 0; i < ONE_DIM; ++i)
00304 {
00305 for (int s=0; s<NStages; ++s)
00306 head_table[i][s] = weights.value(i + ONE_DIM*s);
00307 }
00308 }
00309
00310 osl::MultiInt osl::eval::ml::
00311 SilverFeatures::eval(const NumEffectState &state)
00312 {
00313 MultiInt result;
00314 CArray<Position, 2> kings = {{state.getKingPosition<BLACK>(),
00315 state.getKingPosition<WHITE>()}};
00316 for (int i = PtypeTraits<SILVER>::indexMin;
00317 i < PtypeTraits<SILVER>::indexLimit; ++i)
00318 {
00319 const Piece silver = state.getPieceOf(i);
00320 if (!silver.isOnBoard() || silver.isPromoted()) continue;
00321 if (silver.owner()==BLACK){
00322 result += evalOne<BLACK>(state, silver, kings);
00323 }
00324 else{
00325 result -= evalOne<WHITE>(state, silver, kings);
00326 }
00327 }
00328 return result;
00329 }
00330
00331 template<osl::Player P>
00332 inline
00333 bool osl::eval::ml::
00334 SilverFeatures::canRetreat(const osl::state::NumEffectState &state,
00335 const osl::Piece silver)
00336 {
00337 assert(silver.isOnBoard() && !silver.isPromoted());
00338 assert(silver.owner()==P);
00339 if ((P == BLACK && silver.position().y() != 9) ||
00340 (P == WHITE && silver.position().y() != 1))
00341 {
00342 Position dl = silver.position()+DirectionPlayerTraits<DL,P>::offset();
00343 Piece pdl = state.getPieceAt(dl);
00344 if (!pdl.canMoveOn<P>() ||
00345 state.hasEffectBy(alt(P), dl))
00346 {
00347 Position dr = silver.position()+DirectionPlayerTraits<DR,P>::offset();
00348 Piece pdr = state.getPieceAt(dr);
00349 if (!pdr.canMoveOn<P>() ||
00350 state.hasEffectBy(alt(P), dr))
00351 {
00352 return false;
00353 }
00354 }
00355 }
00356 return true;
00357 }
00358
00359 void osl::eval::ml::
00360 SilverRetreat::setUp(const Weights &weights, int stage)
00361 {
00362 for (size_t i = 0; i < weights.dimension(); ++i) {
00363 retreat_table[i][stage] = weights.value(i);
00364 }
00365 }
00366
00367
00368 osl::misc::CArray<osl::MultiInt, 153>
00369 osl::eval::ml::GoldFeatures::knight_table;
00370 osl::misc::CArray<osl::MultiInt, 9>
00371 osl::eval::ml::GoldFeatures::retreat_table;
00372 osl::misc::CArray<osl::MultiInt, 14>
00373 osl::eval::ml::GoldFeatures::side_table;
00374
00375 void osl::eval::ml::
00376 GoldKnightKingRelative::setUp(const Weights &weights)
00377 {
00378 for (size_t i = 0; i < ONE_DIM; ++i)
00379 {
00380 for (int s=0; s<NStages; ++s)
00381 knight_table[i][s] = weights.value(i + ONE_DIM*s);
00382 }
00383 }
00384
00385 void osl::eval::ml::
00386 GoldSideMove::setUp(const Weights &weights)
00387 {
00388 for (size_t i = 0; i < ONE_DIM; ++i)
00389 {
00390 for (int s=0; s<NStages; ++s)
00391 side_table[i][s] = weights.value(i + ONE_DIM*s);
00392 }
00393 }
00394
00395 osl::MultiInt osl::eval::ml::
00396 GoldFeatures::eval(const NumEffectState &state)
00397 {
00398 MultiInt result;
00399 CArray<Position, 2> kings = {{state.getKingPosition<BLACK>(),
00400 state.getKingPosition<WHITE>()}};
00401 for (int i = PtypeTraits<GOLD>::indexMin;
00402 i < PtypeTraits<GOLD>::indexLimit; ++i)
00403 {
00404 const Piece gold = state.getPieceOf(i);
00405 if (!gold.isOnBoard())
00406 continue;
00407 if (gold.owner() == BLACK)
00408 {
00409 result += evalOne<BLACK>(state, gold, kings);
00410 }
00411 else
00412 {
00413 result -= evalOne<WHITE>(state, gold, kings);
00414 }
00415 }
00416 return result;
00417 }
00418
00419 template<osl::Player P>
00420 inline
00421 bool osl::eval::ml::
00422 GoldFeatures::canRetreat(const osl::state::NumEffectState &state,
00423 const osl::Piece gold)
00424 {
00425 assert(gold.isOnBoard());
00426 assert(P==gold.owner());
00427
00428 if ((P == BLACK && gold.position().y() != 9) ||
00429 (P == WHITE && gold.position().y() != 1))
00430 {
00431 Position d = gold.position()+DirectionPlayerTraits<D,P>::offset();
00432 if ((state.getPieceAt(d).isOnBoardByOwner(P) ||
00433 state.hasEffectBy(alt(P), d)))
00434 {
00435 return false;
00436 }
00437 }
00438 return true;
00439 }
00440
00441 void osl::eval::ml::
00442 GoldRetreat::setUp(const Weights &weights,int stage)
00443 {
00444 for (size_t i = 0; i < weights.dimension(); ++i) {
00445 retreat_table[i][stage] = weights.value(i);
00446 }
00447 }
00448
00449
00450
00451 osl::misc::CArray<MultiInt, 9> osl::eval::ml::KnightAdvance::table;
00452
00453 template<osl::Player P>
00454 inline
00455 bool osl::eval::ml::
00456 KnightAdvance::cantAdvance(const osl::state::NumEffectState &state,
00457 const osl::Piece knight)
00458 {
00459
00460
00461 assert(P==knight.owner());
00462 Position uul = knight.position()+DirectionPlayerTraits<UUL,P>::offset();
00463 const Piece puul = state.getPieceAt(uul);
00464 if (!puul.canMoveOn<P>())
00465 {
00466 Position uur = knight.position()+DirectionPlayerTraits<UUR,P>::offset();
00467 const Piece puur = state.getPieceAt(uur);
00468 if (!puur.canMoveOn<P>())
00469 return true;
00470 }
00471 return false;
00472 }
00473
00474 void osl::eval::ml::
00475 KnightAdvance::setUp(const Weights &weights,int stage)
00476 {
00477 for (size_t i = 0; i < weights.dimension(); ++i) {
00478 table[i][stage] = weights.value(i);
00479 }
00480 }
00481
00482 MultiInt osl::eval::ml::KnightAdvance::eval(
00483 const NumEffectState &state)
00484 {
00485 MultiInt result;
00486 for (int i = PtypeTraits<KNIGHT>::indexMin;
00487 i < PtypeTraits<KNIGHT>::indexLimit; ++i)
00488 {
00489 const Piece knight = state.getPieceOf(i);
00490 if (!knight.isOnBoard() || knight.isPromoted()) continue;
00491 if (knight.owner() == BLACK){
00492 if(cantAdvance<BLACK>(state,knight))
00493 result += table[index(BLACK, knight.position())];
00494 }
00495 else if(cantAdvance<WHITE>(state,knight)){
00496 result -= table[index(WHITE, knight.position())];
00497 }
00498 }
00499 return result;
00500 }
00501
00502
00503 MultiInt osl::eval::ml::AllGold::weight;
00504
00505 void osl::eval::ml::
00506 AllGold::setUp(const Weights &weights,int stage)
00507 {
00508 weight[stage] = weights.value(0);
00509 }
00510
00511
00512
00513 osl::misc::CArray<MultiInt, 144> osl::eval::ml::PtypeY::table;
00514
00515 void osl::eval::ml::
00516 PtypeY::setUp(const Weights &weights,int stage)
00517 {
00518 for (size_t i = 0; i < weights.dimension(); ++i)
00519 {
00520 table[i][stage] = weights.value(i);
00521 }
00522 }
00523
00524 MultiInt osl::eval::ml::PtypeY::eval(const NumEffectState &state)
00525 {
00526 MultiInt result;
00527 for (int i = 0; i < Piece::SIZE; ++i)
00528 {
00529 const Piece p = state.getPieceOf(i);
00530 if (!p.isOnBoard())
00531 continue;
00532 if (p.owner() == BLACK)
00533 result += table[index(BLACK,p.ptype(),p.position())];
00534 else
00535 result -= table[index(WHITE,p.ptype(),p.position())];
00536 }
00537 return result;
00538 }
00539
00540 template<osl::Player P>
00541 MultiInt osl::eval::ml::
00542 PtypeY::evalWithUpdate(const NumEffectState &, Move moved,
00543 MultiInt const& last_value)
00544 {
00545 MultiInt result(last_value);
00546
00547 if (!moved.isDrop())
00548 {
00549 if (P == BLACK)
00550 result -= table[index(BLACK, moved.oldPtype(), moved.from())];
00551 else
00552 result += table[index(WHITE, moved.oldPtype(), moved.from())];
00553 }
00554 Ptype captured = moved.capturePtype();
00555 if (captured != PTYPE_EMPTY)
00556 {
00557 const MultiInt weight =
00558 table[index(alt(P), captured, moved.to())];
00559 if (P == BLACK)
00560 result += weight;
00561 else
00562 result -= weight;
00563 }
00564 {
00565 if (P == BLACK)
00566 result += table[index(BLACK, moved.ptype(), moved.to())];
00567 else
00568 result -= table[index(WHITE, moved.ptype(), moved.to())];
00569 }
00570
00571 return result;
00572 }
00573
00574
00575 osl::misc::CArray<MultiInt, 80> osl::eval::ml::PtypeX::table;
00576
00577 void osl::eval::ml::
00578 PtypeX::setUp(const Weights &weights,int stage)
00579 {
00580 for (size_t i = 0; i < weights.dimension(); ++i)
00581 {
00582 table[i][stage] = weights.value(i);
00583 }
00584 }
00585
00586 MultiInt osl::eval::ml::PtypeX::eval(const NumEffectState &state)
00587 {
00588 MultiInt result;
00589 for (int i = 0; i < Piece::SIZE; ++i)
00590 {
00591 const Piece p = state.getPieceOf(i);
00592 if (!p.isOnBoard())
00593 continue;
00594 if (p.owner() == BLACK)
00595 result += table[index(BLACK,p.ptype(),p.position())];
00596 else
00597 result -= table[index(WHITE,p.ptype(),p.position())];
00598 }
00599 return result;
00600 }
00601
00602 template<osl::Player P>
00603 MultiInt osl::eval::ml::
00604 PtypeX::evalWithUpdate(const NumEffectState &, Move moved,
00605 MultiInt const& last_value)
00606 {
00607 MultiInt result(last_value);
00608
00609 if (!moved.isDrop())
00610 {
00611 if (P == BLACK)
00612 result -= table[index(BLACK, moved.oldPtype(), moved.from())];
00613 else
00614 result += table[index(WHITE, moved.oldPtype(), moved.from())];
00615 Ptype captured = moved.capturePtype();
00616 if (captured != PTYPE_EMPTY)
00617 {
00618 if (P == BLACK)
00619 result += table[index(WHITE, captured, moved.to())];
00620 else
00621 result -= table[index(BLACK, captured, moved.to())];
00622 }
00623 }
00624 if (P == BLACK)
00625 result += table[index(BLACK, moved.ptype(), moved.to())];
00626 else
00627 result -= table[index(WHITE, moved.ptype(), moved.to())];
00628 return result;
00629 }
00630
00631
00632 MultiInt osl::eval::ml::KnightCheck::weight;
00633 osl::misc::CArray<MultiInt, 9> osl::eval::ml::KnightCheck::y_table;
00634
00635 void osl::eval::ml::KnightCheck::setUp(const Weights &weights,int stage)
00636 {
00637 KnightCheck::weight[stage] = weights.value(0);
00638 }
00639
00640 void osl::eval::ml::
00641 KnightCheckY::setUp(const Weights &weights)
00642 {
00643 for (size_t i = 0; i < ONE_DIM; ++i)
00644 {
00645 for (int s=0; s<NStages; ++s)
00646 KnightCheck::y_table[i][s] = weights.value(i + ONE_DIM*s);
00647 }
00648 }
00649
00650 MultiInt osl::eval::ml::
00651 KnightCheck::eval(const NumEffectState &state)
00652 {
00653 MultiInt result;
00654 if (canCheck<BLACK>(state))
00655 {
00656 const int index_y = indexY<BLACK>(state.getKingPosition<BLACK>().y());
00657 result += value(index_y);
00658 }
00659 if (canCheck<WHITE>(state))
00660 {
00661 const int index_y = indexY<WHITE>(state.getKingPosition<WHITE>().y());
00662 result -= value(index_y);
00663 }
00664 return result;
00665 }
00666
00667 osl::misc::CArray<MultiInt, 1024> osl::eval::ml::PawnPtypeOPtypeO::table;
00668 osl::misc::CArray<MultiInt, 9216> osl::eval::ml::PawnPtypeOPtypeO::y_table;
00669
00670 void osl::eval::ml::
00671 PawnPtypeOPtypeO::setUp(const Weights &weights)
00672 {
00673 for (size_t i = 0; i < ONE_DIM; ++i)
00674 {
00675 for (int s=0; s<NStages; ++s)
00676 table[i][s] = weights.value(i + ONE_DIM*s);
00677 }
00678 }
00679
00680 void osl::eval::ml::
00681 PawnPtypeOPtypeOY::setUp(const Weights &weights)
00682 {
00683 for (size_t i = 0; i < ONE_DIM; ++i)
00684 {
00685 for (int s=0; s<NStages; ++s)
00686 PawnPtypeOPtypeO::y_table[i][s] = weights.value(i + ONE_DIM*s);
00687 }
00688 }
00689
00690 MultiInt osl::eval::ml::
00691 PawnPtypeOPtypeO::eval(const NumEffectState &state)
00692 {
00693 MultiInt result;
00694 for (int i = PtypeTraits<PAWN>::indexMin;
00695 i < PtypeTraits<PAWN>::indexLimit; ++i)
00696 {
00697 Piece pawn = state.getPieceOf(i);
00698 if (pawn.isOnBoard() && !pawn.isPromoted())
00699 {
00700 const Position up = Board_Table.nextPosition(pawn.owner(),
00701 pawn.position(), U);
00702 const Position up_up = Board_Table.nextPosition(pawn.owner(),
00703 up, U);
00704 PtypeO up_p =
00705 (up.isOnBoard() ? state.getPieceAt(up).ptypeO() : PTYPEO_EDGE);
00706 PtypeO up_up_p =
00707 (up_up.isOnBoard() ? state.getPieceAt(up_up).ptypeO() : PTYPEO_EDGE);
00708 const int idx = index(pawn.owner(), up_p, up_up_p);
00709 const int idx_y = indexY(pawn.owner(), up_p, up_up_p,
00710 pawn.position().y());
00711 if (pawn.owner() == BLACK)
00712 result += table[idx] + y_table[idx_y];
00713 else
00714 result -= table[idx] + y_table[idx_y];
00715 }
00716 }
00717 return result;
00718 }
00719
00720 template<osl::Player P>
00721 MultiInt
00722 #ifdef __GNUC__
00723 __attribute__((__flatten__))
00724 #endif
00725 osl::eval::ml::
00726 PawnPtypeOPtypeO::evalWithUpdate(const NumEffectState &state, Move moved,
00727 const CArray2d<int, 2, 9> &pawns,
00728 const MultiInt &last_value)
00729 {
00730 assert(moved.player()==P);
00731 MultiInt result(last_value);
00732 if (!moved.isDrop())
00733 {
00734 if (moved.oldPtype() == PAWN)
00735 {
00736 const Position up_up = moved.to() + DirectionPlayerTraits<U,P>::offset();
00737 const PtypeO up_up_p =
00738 (up_up.isOnBoard() ? state.getPieceAt(up_up).ptypeO() : PTYPEO_EDGE);
00739 const int i = index(P, moved.capturePtypeOSafe(), up_up_p);
00740 const int i_y = indexY(P, moved.capturePtypeOSafe(),
00741 up_up_p, moved.from().y());
00742 if (P == BLACK)
00743 result -= table[i]+y_table[i_y];
00744 else
00745 result += table[i]+y_table[i_y];
00746 }
00747 if (pawns[BLACK][moved.from().x() - 1] != 0)
00748 {
00749 if (pawns[BLACK][moved.from().x() - 1] ==
00750 moved.from().y() + 1)
00751 {
00752 const Position up_up = moved.from() + DirectionPlayerTraits<U,BLACK>::offset();
00753 const PtypeO up_up_p =
00754 (up_up.isOnBoard() ? (up_up == moved.to() ? moved.capturePtypeOSafe() :
00755 state.getPieceAt(up_up).ptypeO()) :
00756 PTYPEO_EDGE);
00757 const int i = index(BLACK, moved.oldPtypeO(), up_up_p);
00758 const int i_y = indexY(BLACK, moved.oldPtypeO(), up_up_p,
00759 moved.from().y() + 1);
00760 result -= table[i]+y_table[i_y];
00761 if (up_up != moved.to())
00762 {
00763 const int new_i = index(BLACK, PTYPEO_EMPTY, up_up_p);
00764 const int new_i_y = indexY(BLACK, PTYPEO_EMPTY, up_up_p,
00765 moved.from().y() + 1);
00766 result += table[new_i]+y_table[new_i_y];
00767 }
00768 }
00769 if (pawns[BLACK][moved.from().x() - 1] ==
00770 moved.from().y() + 2)
00771 {
00772 const Position up = moved.from() + DirectionPlayerTraits<D,BLACK>::offset();
00773 const PtypeO up_p =
00774 (up.isOnBoard() ? (up == moved.to() ? moved.capturePtypeOSafe() :
00775 state.getPieceAt(up).ptypeO()) : PTYPEO_EDGE);
00776 const int i = index(BLACK, up_p, moved.oldPtypeO());
00777 const int i_y = indexY(BLACK, up_p, moved.oldPtypeO(),
00778 moved.from().y() + 2);
00779 result -= table[i]+y_table[i_y];
00780 if (moved.to() != up)
00781 {
00782 const int new_i = index(BLACK, up_p, PTYPEO_EMPTY);
00783 const int new_i_y = indexY(BLACK, up_p, PTYPEO_EMPTY,
00784 moved.from().y() + 2);
00785 result += table[new_i]+y_table[new_i_y];
00786 }
00787 }
00788 }
00789 if (pawns[WHITE][moved.from().x() - 1] != 0)
00790 {
00791 if (pawns[WHITE][moved.from().x() - 1] ==
00792 moved.from().y() - 1)
00793 {
00794 const Position up_up = moved.from() + DirectionPlayerTraits<U,WHITE>::offset();
00795 const PtypeO up_up_p =
00796 (up_up.isOnBoard() ? (up_up == moved.to() ? moved.capturePtypeOSafe() :
00797 state.getPieceAt(up_up).ptypeO()) :
00798 PTYPEO_EDGE);
00799 const int i = index(WHITE, moved.oldPtypeO(), up_up_p);
00800 const int i_y = indexY(WHITE, moved.oldPtypeO(), up_up_p,
00801 moved.from().y() - 1);
00802 result += table[i]+y_table[i_y];
00803 if (moved.to() != up_up)
00804 {
00805 const int new_i = index(WHITE, PTYPEO_EMPTY, up_up_p);
00806 const int new_i_y = indexY(WHITE, PTYPEO_EMPTY, up_up_p,
00807 moved.from().y() - 1);
00808 result -= table[new_i]+y_table[new_i_y];
00809 }
00810 }
00811 if (pawns[WHITE][moved.from().x() - 1] ==
00812 moved.from().y() - 2)
00813 {
00814 const Position up = moved.from() + DirectionPlayerTraits<D,WHITE>::offset();
00815 const PtypeO up_p =
00816 (up.isOnBoard() ? (up == moved.to() ? moved.capturePtypeOSafe() :
00817 state.getPieceAt(up).ptypeO()) : PTYPEO_EDGE);
00818 const int i = index(WHITE, up_p, moved.oldPtypeO());
00819 const int i_y = indexY(WHITE, up_p, moved.oldPtypeO(),
00820 moved.from().y() - 2);
00821 result += table[i]+y_table[i_y];
00822 if (moved.to() != up)
00823 {
00824 const int new_i = index(WHITE, up_p, PTYPEO_EMPTY);
00825 const int new_i_y = indexY(WHITE, up_p, PTYPEO_EMPTY,
00826 moved.from().y() - 2);
00827 result -= table[new_i]+y_table[new_i_y];
00828 }
00829 }
00830 }
00831 }
00832 Ptype captured = moved.capturePtype();
00833 if (captured == PAWN)
00834 {
00835 const Position up = moved.to() + DirectionPlayerTraits<D,P>::offset();
00836 const Position up_up = up + DirectionPlayerTraits<D,P>::offset();
00837 const PtypeO up_p =
00838 (up.isOnBoard() ? (up == moved.from() ? moved.oldPtypeO() :
00839 state.getPieceAt(up).ptypeO()) : PTYPEO_EDGE);
00840 const PtypeO up_up_p =
00841 (up_up.isOnBoard() ? (up_up == moved.from() ? moved.oldPtypeO() :
00842 state.getPieceAt(up_up).ptypeO()) : PTYPEO_EDGE);
00843 const int i = index(alt(P), up_p, up_up_p);
00844 const int i_y = indexY(alt(P), up_p, up_up_p,
00845 moved.to().y());
00846 if (P == BLACK)
00847 {
00848 result += table[i]+y_table[i_y];
00849 }
00850 else
00851 {
00852 result -= table[i]+y_table[i_y];
00853 }
00854 }
00855 if (moved.ptype() == PAWN)
00856 {
00857 const Position up = moved.to() + DirectionPlayerTraits<U,P>::offset();
00858 const Position up_up = up + DirectionPlayerTraits<U,P>::offset();
00859 const PtypeO up_p =
00860 (up.isOnBoard() ? (up == moved.from() ? moved.oldPtypeO() :
00861 state.getPieceAt(up).ptypeO()) : PTYPEO_EDGE);
00862 const PtypeO up_up_p =
00863 (up_up.isOnBoard() ? (up_up == moved.from() ? moved.oldPtypeO() :
00864 state.getPieceAt(up_up).ptypeO()) : PTYPEO_EDGE);
00865 const int i = index(P, up_p, up_up_p);
00866 const int i_y = indexY(P, up_p, up_up_p, moved.to().y());
00867 if (P == BLACK)
00868 {
00869 result += table[i]+y_table[i_y];
00870 }
00871 else
00872 {
00873 result -= table[i]+y_table[i_y];
00874 }
00875 }
00876 if (pawns[BLACK][moved.to().x() - 1] != 0)
00877 {
00878 if (pawns[BLACK][moved.to().x() - 1] ==
00879 moved.to().y() + 1)
00880 {
00881 const Position up_up = moved.to() + DirectionPlayerTraits<U,BLACK>::offset();
00882 const PtypeO up_up_p =
00883 (up_up.isOnBoard() ? state.getPieceAt(up_up).ptypeO() :
00884 PTYPEO_EDGE);
00885 const int i = index(BLACK, moved.ptypeO(), up_up_p);
00886 const int i_y = indexY(BLACK, moved.ptypeO(), up_up_p,
00887 moved.to().y() + 1);
00888 result += table[i]+y_table[i_y];
00889 if (moved.isDrop() || moved.from() != up_up)
00890 {
00891 const int old_i = index(BLACK, moved.capturePtypeOSafe(), up_up_p);
00892 const int old_i_y = indexY(BLACK, moved.capturePtypeOSafe(),
00893 up_up_p, moved.to().y() + 1);
00894 result -= table[old_i]+y_table[old_i_y];
00895 }
00896 }
00897 if (pawns[BLACK][moved.to().x() - 1] ==
00898 moved.to().y() + 2)
00899 {
00900 const Position up = moved.to() + DirectionPlayerTraits<D,BLACK>::offset();
00901 const PtypeO up_p =
00902 (up.isOnBoard() ? state.getPieceAt(up).ptypeO() : PTYPEO_EDGE);
00903 const int i = index(BLACK, up_p, moved.ptypeO());
00904 const int i_y = indexY(BLACK, up_p, moved.ptypeO(), moved.to().y() + 2);
00905 result += table[i]+y_table[i_y];
00906 if (moved.isDrop() || up != moved.from())
00907 {
00908 const int old_i = index(BLACK, up_p, moved.capturePtypeOSafe());
00909 const int old_i_y = indexY(BLACK, up_p, moved.capturePtypeOSafe(),
00910 moved.to().y() + 2);
00911 result -= table[old_i]+y_table[old_i_y];
00912 }
00913 }
00914 }
00915 if (pawns[WHITE][moved.to().x() - 1] != 0)
00916 {
00917 if (pawns[WHITE][moved.to().x() - 1] ==
00918 moved.to().y() - 1)
00919 {
00920 const Position up_up = moved.to() + DirectionPlayerTraits<U,WHITE>::offset();
00921 const PtypeO up_up_p =
00922 (up_up.isOnBoard() ? state.getPieceAt(up_up).ptypeO() :
00923 PTYPEO_EDGE);
00924 const int i = index(WHITE, moved.ptypeO(), up_up_p);
00925 const int i_y = indexY(WHITE, moved.ptypeO(), up_up_p,
00926 moved.to().y() - 1);
00927 result -= table[i]+y_table[i_y];
00928 if (up_up != moved.from())
00929 {
00930 const int old_i = index(WHITE, moved.capturePtypeOSafe(), up_up_p);
00931 const int old_i_y = indexY(WHITE, moved.capturePtypeOSafe(), up_up_p,
00932 moved.to().y() - 1);
00933 result += table[old_i]+y_table[old_i_y];
00934 }
00935 }
00936 if (pawns[WHITE][moved.to().x() - 1] ==
00937 moved.to().y() - 2)
00938 {
00939 const Position up = moved.to() + DirectionPlayerTraits<D,WHITE>::offset();
00940 const PtypeO up_p =
00941 (up.isOnBoard() ? state.getPieceAt(up).ptypeO() : PTYPEO_EDGE);
00942 const int i = index(WHITE, up_p, moved.ptypeO());
00943 const int i_y = indexY(WHITE, up_p, moved.ptypeO(), moved.to().y() - 2);
00944 result -= table[i]+y_table[i_y];
00945 if (moved.isDrop() || up != moved.from())
00946 {
00947 const int old_i = index(WHITE, up_p, moved.capturePtypeOSafe());
00948 const int old_i_y = indexY(WHITE, up_p, moved.capturePtypeOSafe(),
00949 moved.to().y() - 2);
00950 result += table[old_i]+y_table[old_i_y];
00951 }
00952 }
00953 }
00954 return result;
00955 }
00956
00957
00958
00959 osl::misc::CArray<MultiInt, 9> osl::eval::ml::PromotedMinorPieces::table;
00960 osl::misc::CArray<MultiInt, 162> osl::eval::ml::PromotedMinorPieces::y_table;
00961
00962 void osl::eval::ml::
00963 PromotedMinorPieces::setUp(const Weights &weights)
00964 {
00965 for (size_t i = 0; i < ONE_DIM; ++i)
00966 {
00967 for (int s=0; s<NStages; ++s)
00968 table[i][s] = weights.value(i + ONE_DIM*s);
00969 }
00970 }
00971
00972 void osl::eval::ml::
00973 PromotedMinorPiecesY::setUp(const Weights &weights)
00974 {
00975 for (size_t i = 0; i < ONE_DIM; ++i)
00976 {
00977 for (int s=0; s<NStages; ++s)
00978 PromotedMinorPieces::y_table[i][s] = weights.value(i + ONE_DIM*s);
00979 }
00980 }
00981
00982 template <int Sign>
00983 inline void osl::eval::ml::
00984 PromotedMinorPieces::adjust(int index, int index_attack, int index_defense,
00985 MultiInt &result)
00986 {
00987 if(Sign>0)
00988 result+= table[index] + y_table[index_attack] + y_table[index_defense];
00989 else
00990 result-= table[index] + y_table[index_attack] + y_table[index_defense];
00991 }
00992 template <osl::Player P>
00993 void osl::eval::ml::
00994 PromotedMinorPieces::evalOne(const NumEffectState &state,
00995 const PieceMask promoted,
00996 MultiInt &result)
00997 {
00998 PieceMask attack = promoted & state.getOnBoardMask(P);
00999 const Position king = state.getKingPosition<PlayerTraits<P>::opponent>();
01000 const Position self_king = state.getKingPosition<P>();
01001 int min_left = -10;
01002 int min_right = 10;
01003 while (attack.any())
01004 {
01005 const Piece p = state.getPieceOf(attack.takeOneBit());
01006 const int x_diff = (P == BLACK ? p.position().x() - king.x() :
01007 king.x() - p.position().x());
01008 if (x_diff <= 0)
01009 {
01010 if (x_diff > min_left)
01011 {
01012 if (min_left != -10)
01013 {
01014 if (P == BLACK)
01015 adjust<1>(-min_left, indexY<true, P>(king, -min_left),
01016 indexY<false, P>(self_king, -min_left), result);
01017 else
01018 adjust<-1>(-min_left, indexY<true, P>(king, -min_left),
01019 indexY<false, P>(self_king, -min_left), result);
01020 }
01021 min_left = x_diff;
01022 }
01023 else
01024 {
01025 if (P == BLACK)
01026 adjust<1>(-x_diff, indexY<true, P>(king, -x_diff),
01027 indexY<false, P>(self_king, -x_diff),
01028 result);
01029 else
01030 adjust<-1>(-x_diff, indexY<true, P>(king, -x_diff),
01031 indexY<false, P>(self_king, -x_diff),
01032 result);
01033 }
01034 }
01035 if (x_diff >= 0)
01036 {
01037 if (x_diff < min_right)
01038 {
01039 if (min_right != 10)
01040 {
01041 if (P == BLACK)
01042 adjust<1>(min_right, indexY<true, P>(king, min_right),
01043 indexY<false, P>(self_king, min_right),
01044 result);
01045 else
01046 adjust<-1>(min_right, indexY<true, P>(king, min_right),
01047 indexY<false, P>(self_king, min_right),
01048 result);
01049 }
01050 min_right = x_diff;
01051 }
01052 else if (x_diff != 0)
01053 {
01054 if (P == BLACK)
01055 adjust<1>(x_diff, indexY<true, P>(king, x_diff),
01056 indexY<false, P>(self_king, x_diff),
01057 result);
01058 else
01059 adjust<-1>(x_diff, indexY<true, P>(king, x_diff),
01060 indexY<false, P>(self_king, x_diff),
01061 result);
01062 }
01063 }
01064 }
01065 }
01066
01067 MultiInt osl::eval::ml::
01068 PromotedMinorPieces::eval(const NumEffectState &state)
01069 {
01070 MultiInt result;
01071 PieceMask promoted_pieces = state.promotedPieces();
01072 promoted_pieces.clearBit<ROOK>();
01073 promoted_pieces.clearBit<BISHOP>();
01074 if (promoted_pieces.none())
01075 return result;
01076
01077 evalOne<BLACK>(state, promoted_pieces, result);
01078 evalOne<WHITE>(state, promoted_pieces, result);
01079 return result;
01080 }
01081
01082 MultiInt osl::eval::ml::
01083 PromotedMinorPieces::evalWithUpdate(const NumEffectState &state,
01084 Move moved,
01085 const MultiInt &last_values)
01086 {
01087 Ptype captured = moved.capturePtype();
01088 if (moved.ptype() == KING ||
01089 (isPromoted(moved.ptype()) && !isMajor(moved.ptype())) ||
01090 (captured != PTYPE_EMPTY && isPromoted(captured) &&
01091 !isMajor(captured)))
01092 return eval(state);
01093
01094 return last_values;
01095 }
01096
01097
01098 osl::misc::CArray<MultiInt, 64> osl::eval::ml::NonPawnAttacked::table;
01099 osl::misc::CArray<MultiInt, 19584> osl::eval::ml::NonPawnAttacked::king_table;
01100
01101 void osl::eval::ml::NonPawnAttacked::setUp(const Weights &weights)
01102 {
01103 for (size_t i = 0; i < ONE_DIM; ++i)
01104 {
01105 for (int s=0; s<NStages; ++s)
01106 table[i][s] = weights.value(i + ONE_DIM*s);
01107 }
01108 }
01109
01110 void osl::eval::ml::NonPawnAttackedKingRelative::setUp(
01111 const Weights &weights)
01112 {
01113 for (size_t i = 0; i < ONE_DIM; ++i)
01114 {
01115 for (int s=0; s<NStages; ++s)
01116 NonPawnAttacked::king_table[i][s] = weights.value(i + ONE_DIM*s);
01117 }
01118 for(int x_diff=0;x_diff<9;x_diff++)
01119 for(int y_diff= -8;y_diff<=8;y_diff++)
01120 for(int has_support=0;has_support<2;has_support++)
01121 for(int same_turn=0;same_turn<2;same_turn++)
01122 for(int ptype=0;ptype<PTYPE_SIZE;ptype++){
01123 int index=((ptype + (same_turn ? 0 : PTYPE_SIZE) +
01124 (has_support ? 0 : PTYPE_SIZE*2))* 9 + x_diff) * 17 +
01125 y_diff + 8;
01126 int index0=ptype + (same_turn ? 0 : PTYPE_SIZE) +
01127 (has_support ? 0 : PTYPE_SIZE * 2);
01128 NonPawnAttacked::king_table[index] += NonPawnAttacked::table[index0];
01129 }
01130 }
01131
01132 template <int Sign>
01133 void osl::eval::ml::
01134 NonPawnAttacked::adjust(int black_turn_king_attack,
01135 int black_turn_king_defense,
01136 int white_turn_king_attack,
01137 int white_turn_king_defense,
01138 MultiIntPair &result)
01139 {
01140 if(Sign>0){
01141 result[BLACK] += king_table[black_turn_king_attack] +
01142 king_table[black_turn_king_defense];
01143 result[WHITE] += king_table[white_turn_king_attack] +
01144 king_table[white_turn_king_defense];
01145 }
01146 else{
01147 result[BLACK] -= king_table[black_turn_king_attack] +
01148 king_table[black_turn_king_defense];
01149 result[WHITE] -= king_table[white_turn_king_attack] +
01150 king_table[white_turn_king_defense];
01151 }
01152 }
01153
01154 void osl::eval::ml::
01155 NonPawnAttacked::eval(const NumEffectState &state, MultiIntPair& result)
01156 {
01157 result = MultiIntPair();
01158 CArray<Position, 2> kings = {{state.getKingPosition<BLACK>(),
01159 state.getKingPosition<WHITE>()}};
01160 PieceMask black_attacked = state.effectedMask(WHITE) & state.getOnBoardMask(BLACK);
01161 black_attacked.reset(KingTraits<BLACK>::index);
01162 mask_t black_ppawn = state.promotedPieces().getMask<PAWN>() & black_attacked.selectBit<PAWN>();
01163 black_attacked.clearBit<PAWN>();
01164 black_attacked.orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
01165 PieceMask black_with_support = state.effectedMask(BLACK) & black_attacked;
01166 PieceMask black_without_support = (~state.effectedMask(BLACK)) & black_attacked;
01167 while (black_with_support.any())
01168 {
01169 const Piece piece = state.getPieceOf(black_with_support.takeOneBit());
01170 const int index_king_black_turn_attack =
01171 indexK<true>(kings[WHITE], true, true, piece);
01172 const int index_king_white_turn_attack =
01173 indexK<true>(kings[WHITE], false, true, piece);
01174 const int index_king_black_turn_defense =
01175 indexK<false>(kings[BLACK], true, true, piece);
01176 const int index_king_white_turn_defense =
01177 indexK<false>(kings[BLACK], false, true, piece);
01178 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
01179 index_king_white_turn_attack, index_king_white_turn_defense,
01180 result);
01181 }
01182 while (black_without_support.any())
01183 {
01184 const Piece piece = state.getPieceOf(black_without_support.takeOneBit());
01185 const int index_king_black_turn_attack =
01186 indexK<true>(kings[WHITE], true, false, piece);
01187 const int index_king_white_turn_attack =
01188 indexK<true>(kings[WHITE], false, false, piece);
01189 const int index_king_black_turn_defense =
01190 indexK<false>(kings[BLACK], true, false, piece);
01191 const int index_king_white_turn_defense =
01192 indexK<false>(kings[BLACK], false, false, piece);
01193 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
01194 index_king_white_turn_attack, index_king_white_turn_defense,
01195 result);
01196 }
01197
01198 PieceMask white_attacked = state.effectedMask(BLACK) & state.getOnBoardMask(WHITE);
01199 white_attacked.reset(KingTraits<WHITE>::index);
01200 mask_t white_ppawn = state.promotedPieces().getMask<PAWN>() & white_attacked.selectBit<PAWN>();
01201 white_attacked.clearBit<PAWN>();
01202 white_attacked.orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
01203 PieceMask white_with_support = state.effectedMask(WHITE) & white_attacked;
01204 PieceMask white_without_support = (~state.effectedMask(WHITE)) & white_attacked;
01205 while (white_with_support.any())
01206 {
01207 const Piece piece = state.getPieceOf(white_with_support.takeOneBit());
01208 const int index_king_black_turn_attack =
01209 indexK<true>(kings[BLACK], false, true, piece);
01210 const int index_king_white_turn_attack =
01211 indexK<true>(kings[BLACK], true, true, piece);
01212 const int index_king_black_turn_defense =
01213 indexK<false>(kings[WHITE], false, true, piece);
01214 const int index_king_white_turn_defense =
01215 indexK<false>(kings[WHITE], true, true, piece);
01216 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
01217 index_king_white_turn_attack, index_king_white_turn_defense,
01218 result);
01219 }
01220 while (white_without_support.any())
01221 {
01222 const Piece piece = state.getPieceOf(white_without_support.takeOneBit());
01223 const int index_king_black_turn_attack =
01224 indexK<true>(kings[BLACK], false, false, piece);
01225 const int index_king_white_turn_attack =
01226 indexK<true>(kings[BLACK], true, false, piece);
01227 const int index_king_black_turn_defense =
01228 indexK<false>(kings[WHITE], false, false, piece);
01229 const int index_king_white_turn_defense =
01230 indexK<false>(kings[WHITE], true, false, piece);
01231 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
01232 index_king_white_turn_attack, index_king_white_turn_defense,
01233 result);
01234 }
01235 }
01236
01237 template<osl::Player P>
01238 void osl::eval::ml::
01239 NonPawnAttacked::evalWithUpdateBang(
01240 const NumEffectState &state,
01241 Move moved,
01242 const CArray<PieceMask, 2> &effected,
01243 MultiIntPair &result)
01244 {
01245 if (moved.ptype() == KING)
01246 {
01247 eval(state, result);
01248 return;
01249 }
01250
01251 CArray<PieceMask, 2> effected_mask = effected;
01252 effected_mask[0].clearBit<KING>();
01253 effected_mask[1].clearBit<KING>();
01254 CArray<PieceMask, 2> new_mask = {{
01255 state.effectedMask(BLACK),
01256 state.effectedMask(WHITE)
01257 }};
01258
01259 mask_t black_ppawn =
01260 new_mask[0].selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
01261 mask_t white_ppawn =
01262 new_mask[1].template selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
01263 new_mask[0].clearBit<PAWN>();
01264 new_mask[1].clearBit<PAWN>();
01265 new_mask[0].orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
01266 new_mask[1].orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
01267 new_mask[0].clearBit<KING>();
01268 new_mask[1].clearBit<KING>();
01269 CArray<Position, 2> kings = {{ state.getKingPosition<BLACK>(),
01270 state.getKingPosition<WHITE>() }};
01271 const Piece p = state.getPieceAt(moved.to());
01272 assert(p.owner()==P);
01273 if (!moved.isDrop())
01274 {
01275 if (effected_mask[alt(P)].test(p.number()))
01276 {
01277 const bool has_support = effected_mask[P].test(p.number());
01278 const int index_king_black_turn_attack =
01279 indexK<true>(kings[alt(P)], BLACK == P,
01280 has_support, moved.from(), P, moved.oldPtype());
01281 const int index_king_white_turn_attack =
01282 indexK<true>(kings[alt(P)], WHITE == P,
01283 has_support, moved.from(), P, moved.oldPtype());
01284 const int index_king_black_turn_defense =
01285 indexK<false>(kings[P], BLACK == P,
01286 has_support, moved.from(), P, moved.oldPtype());
01287 const int index_king_white_turn_defense =
01288 indexK<false>(kings[P], WHITE == P,
01289 has_support, moved.from(), P, moved.oldPtype());
01290 if (P == BLACK)
01291 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
01292 index_king_white_turn_attack, index_king_white_turn_defense,
01293 result);
01294 else
01295 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
01296 index_king_white_turn_attack, index_king_white_turn_defense,
01297 result);
01298 }
01299 }
01300 if (new_mask[alt(P)].test(p.number()))
01301 {
01302 const bool has_support = new_mask[P].test(p.number());
01303 const int index_king_black_turn_attack =
01304 indexK<true>(kings[alt(P)], BLACK == P,
01305 has_support, p);
01306 const int index_king_white_turn_attack =
01307 indexK<true>(kings[alt(P)], WHITE == P,
01308 has_support, p);
01309 const int index_king_black_turn_defense =
01310 indexK<false>(kings[P], BLACK == P,
01311 has_support, p);
01312 const int index_king_white_turn_defense =
01313 indexK<false>(kings[P], WHITE == P,
01314 has_support, p);
01315 if (P == BLACK)
01316 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
01317 index_king_white_turn_attack, index_king_white_turn_defense,
01318 result);
01319 else
01320 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
01321 index_king_white_turn_attack, index_king_white_turn_defense,
01322 result);
01323 }
01324 const Ptype captured = moved.capturePtype();
01325 if (captured != PTYPE_EMPTY && captured != PAWN)
01326 {
01327 PieceMask captured_mask =
01328 effected_mask[P] & (~state.getOnBoardMask(BLACK)) &
01329 (~state.getOnBoardMask(WHITE));
01330
01331 const bool has_support = effected_mask[alt(P)].test(captured_mask.takeOneBit());
01332 const int index_king_black_turn_attack =
01333 indexK<true>(kings[P], WHITE == P,
01334 has_support, moved.to(), alt(P), captured);
01335 const int index_king_white_turn_attack =
01336 indexK<true>(kings[P], BLACK == P,
01337 has_support, moved.to(), alt(P), captured);
01338 const int index_king_black_turn_defense =
01339 indexK<false>(kings[alt(P)], WHITE == P,
01340 has_support, moved.to(), alt(P), captured);
01341 const int index_king_white_turn_defense =
01342 indexK<false>(kings[alt(P)], BLACK == P,
01343 has_support, moved.to(), alt(P), captured);
01344 if (P == BLACK)
01345 adjust<1>(index_king_black_turn_attack, index_king_black_turn_defense,
01346 index_king_white_turn_attack, index_king_white_turn_defense,
01347 result);
01348 else
01349 adjust<-1>(index_king_black_turn_attack, index_king_black_turn_defense,
01350 index_king_white_turn_attack, index_king_white_turn_defense,
01351 result);
01352 }
01353
01354 updateEffectChanged<BLACK>(state, effected_mask, new_mask, p.number(),
01355 result);
01356 updateEffectChanged<WHITE>(state, effected_mask, new_mask, p.number(),
01357 result);
01358 }
01359
01360
01361 osl::misc::CArray<MultiInt, 9> osl::eval::ml::KnightHead::table;
01362 osl::misc::CArray<MultiInt, 144> osl::eval::ml::KnightHead::opp_table;
01363
01364 void osl::eval::ml::
01365 KnightHead::setUp(const Weights &weights)
01366 {
01367 for (size_t i = 0; i < ONE_DIM; ++i)
01368 {
01369 for (int s=0; s<NStages; ++s)
01370 table[i][s] = weights.value(i + ONE_DIM*s);
01371 }
01372 }
01373
01374 void osl::eval::ml::
01375 KnightHeadOppPiecePawnOnStand::setUp(const Weights &weights)
01376 {
01377 for (size_t i = 0; i < ONE_DIM; ++i)
01378 {
01379 for (int s=0; s<NStages; ++s)
01380 KnightHead::opp_table[i][s] = weights.value(i + ONE_DIM*s);
01381 }
01382 }
01383
01384 MultiInt osl::eval::ml::
01385 KnightHead::eval(const NumEffectState &state)
01386 {
01387 MultiInt result;
01388 for (int i = PtypeTraits<KNIGHT>::indexMin;
01389 i < PtypeTraits<KNIGHT>::indexLimit;
01390 ++i)
01391 {
01392 const Piece knight = state.getPieceOf(i);
01393 if (knight.isOnBoard() && !knight.isPromoted())
01394 {
01395 const Position up = Board_Table.nextPosition(knight.owner(),
01396 knight.position(), U);
01397 const Piece up_piece = state.getPieceAt(up);
01398 if ((up_piece.isEmpty() && state.hasPieceOnStand<PAWN>(knight.owner()) &&
01399 !state.isPawnMaskSet(knight.owner(), knight.position().x()) &&
01400 state.countEffect(knight.owner(), up) >=
01401 state.countEffect(alt(knight.owner()), up)) ||
01402 (state.hasEffectByPtypeStrict<PAWN>(knight.owner(), up) &&
01403 (up_piece.isEmpty() || up_piece.owner() != knight.owner()) &&
01404 state.countEffect(knight.owner(), up) >
01405 state.countEffect(alt(knight.owner()), up)))
01406 {
01407 const int y = knight.position().y();
01408 if (knight.owner() == BLACK)
01409 {
01410 result += table[y - 1];
01411 }
01412 else
01413 {
01414 result -= table[9 - y];
01415 }
01416 }
01417 else if (up_piece.isPiece() && up_piece.owner() != knight.owner() &&
01418 state.hasPieceOnStand<PAWN>(up_piece.owner()))
01419 {
01420 const int y = (knight.owner() == BLACK ? knight.position().y() :
01421 10 - knight.position().y());
01422 const int index = up_piece.ptype() * 9 + y - 1;
01423 if (knight.owner() == BLACK)
01424 {
01425 result += opp_table[index];
01426 }
01427 else
01428 {
01429 result -= opp_table[index];
01430 }
01431 }
01432 }
01433 }
01434 return result;
01435 }
01436
01437
01438 osl::misc::CArray<MultiInt, 1024> osl::eval::ml::NonPawnAttackedPtype::table;
01439
01440 void osl::eval::ml::
01441 NonPawnAttackedPtype::setUp(const Weights &weights)
01442 {
01443 for (size_t i = 0; i < ONE_DIM; ++i)
01444 {
01445 for (int s=0; s<NStages; ++s)
01446 table[i][s] = weights.value(i + ONE_DIM*s);
01447 }
01448 }
01449
01450 void osl::eval::ml::
01451 NonPawnAttackedPtype::eval(const NumEffectState &state,
01452 CArray<PieceMask, 40> &attacked_mask,
01453 MultiIntPair &result)
01454 {
01455 result = MultiIntPair();
01456 PieceMask black_attacked = state.effectedMask(WHITE) & state.getOnBoardMask(BLACK);
01457 black_attacked.reset(KingTraits<BLACK>::index);
01458 mask_t black_ppawn = state.promotedPieces().getMask<PAWN>() & black_attacked.selectBit<PAWN>();
01459 black_attacked.clearBit<PAWN>();
01460 black_attacked.orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
01461 while (black_attacked.any())
01462 {
01463 const Piece piece = state.getPieceOf(black_attacked.takeOneBit());
01464 const bool with_support = state.effectedMask(BLACK).test(piece.number());
01465 PieceMask attacking =
01466 state.getEffect(piece.position()) & state.getOnBoardMask(WHITE);
01467 attacked_mask[piece.number()] = attacking;
01468
01469 while (attacking.any())
01470 {
01471 const Piece attack = state.getPieceOf(attacking.takeOneBit());
01472 const int index_black_turn = index(true, with_support,
01473 piece.ptype(), attack.ptype());
01474 const int index_white_turn = index(false, with_support,
01475 piece.ptype(), attack.ptype());
01476 adjust<1>(index_black_turn, index_white_turn, result);
01477 }
01478 }
01479 PieceMask white_attacked = state.effectedMask(BLACK) & state.getOnBoardMask(WHITE);
01480 white_attacked.reset(KingTraits<WHITE>::index);
01481 mask_t white_ppawn = state.promotedPieces().getMask<PAWN>() & white_attacked.selectBit<PAWN>();
01482 white_attacked.clearBit<PAWN>();
01483 white_attacked.orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
01484 while (white_attacked.any())
01485 {
01486 const Piece piece = state.getPieceOf(white_attacked.takeOneBit());
01487 const bool with_support = state.effectedMask(WHITE).test(piece.number());
01488 PieceMask attacking =
01489 state.getEffect(piece.position()) & state.getOnBoardMask(BLACK);
01490 attacked_mask[piece.number()] = attacking;
01491 while (attacking.any())
01492 {
01493 const Piece attack = state.getPieceOf(attacking.takeOneBit());
01494 const int index_black_turn = index(false, with_support,
01495 piece.ptype(), attack.ptype());
01496 const int index_white_turn = index(true, with_support,
01497 piece.ptype(), attack.ptype());
01498 adjust<-1>(index_black_turn, index_white_turn, result);
01499 }
01500 }
01501 }
01502
01503 template<osl::Player P>
01504 void osl::eval::ml::
01505 NonPawnAttackedPtype::evalWithUpdateBang(
01506 const NumEffectState &state,
01507 Move moved,
01508 const CArray<PieceMask, 2> &effected,
01509 CArray<PieceMask, 40> &attacked_mask,
01510 MultiIntPair &result)
01511 {
01512 CArray<PieceMask, 2> effected_mask = effected;
01513 effected_mask[0].clearBit<KING>();
01514 effected_mask[1].clearBit<KING>();
01515 CArray<PieceMask, 2> new_mask = {{
01516 state.effectedMask(BLACK),
01517 state.effectedMask(WHITE)
01518 }};
01519 mask_t black_ppawn =
01520 new_mask[0].selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
01521 mask_t white_ppawn =
01522 new_mask[1].selectBit<PAWN>() & state.promotedPieces().template getMask<PAWN>();
01523 new_mask[0].clearBit<PAWN>();
01524 new_mask[1].clearBit<PAWN>();
01525 new_mask[0].orMask(PtypeFuns<PAWN>::indexNum, black_ppawn);
01526 new_mask[1].orMask(PtypeFuns<PAWN>::indexNum, white_ppawn);
01527 new_mask[0].clearBit<KING>();
01528 new_mask[1].clearBit<KING>();
01529 const Piece p = state.getPieceAt(moved.to());
01530 assert(p.owner()==P);
01531 assert(moved.player()==P);
01532 const Ptype captured = moved.capturePtype();
01533 int captured_number = -1;
01534 if (captured != PTYPE_EMPTY && captured != PAWN)
01535 {
01536 PieceMask captured_mask =
01537 effected_mask[P] & (~state.getOnBoardMask(BLACK)) &
01538 (~state.getOnBoardMask(WHITE));
01539 captured_number = captured_mask.takeOneBit();
01540 }
01541 if (!moved.isDrop() && moved.oldPtype() != PAWN)
01542 {
01543 if (effected_mask[alt(P)].test(p.number()))
01544 {
01545 const bool has_support = effected_mask[P].test(p.number());
01546 PieceMask attacking = attacked_mask[p.number()];
01547 if (captured_number != -1)
01548 {
01549 if (attacking.test(captured_number))
01550 {
01551 if (P == BLACK)
01552 {
01553 evalOnePiece<false>(P, moved.oldPtype(), captured,
01554 has_support, result);
01555 }
01556 else
01557 {
01558 evalOnePiece<true>(P, moved.oldPtype(), captured,
01559 has_support, result);
01560 }
01561 attacking.reset(captured_number);
01562 }
01563 }
01564 while (attacking.any())
01565 {
01566 const Piece attack = state.getPieceOf(attacking.takeOneBit());
01567 if (P == BLACK)
01568 {
01569 evalOnePiece<false>(P, moved.oldPtype(), attack.ptype(),
01570 has_support, result);
01571 }
01572 else
01573 {
01574 evalOnePiece<true>(P, moved.oldPtype(), attack.ptype(),
01575 has_support, result);
01576 }
01577 }
01578 }
01579 }
01580 if (new_mask[alt(P)].test(p.number()))
01581 {
01582 const bool has_support = new_mask[P].test(p.number());
01583 PieceMask attacking =
01584 state.getEffect(moved.to()) & state.getOnBoardMask(alt(P));
01585 attacked_mask[p.number()] = attacking;
01586 while (attacking.any())
01587 {
01588 const Piece attack = state.getPieceOf(attacking.takeOneBit());
01589 if (P == BLACK)
01590 {
01591 evalOnePiece<true>(P, p.ptype(), attack.ptype(),
01592 has_support, result);
01593 }
01594 else
01595 {
01596 evalOnePiece<false>(P, p.ptype(), attack.ptype(),
01597 has_support, result);
01598 }
01599 }
01600 }
01601 if (captured_number != -1)
01602 {
01603 const bool has_support = effected_mask[alt(P)].test(captured_number);
01604 PieceMask attacking = attacked_mask[captured_number];
01605 if (attacking.test(p.number()))
01606 {
01607 if (P == BLACK)
01608 {
01609 evalOnePiece<true>(alt(P), captured, moved.oldPtype(),
01610 has_support, result);
01611 }
01612 else
01613 {
01614 evalOnePiece<false>(alt(P), captured, moved.oldPtype(),
01615 has_support, result);
01616 }
01617 attacking.reset(p.number());
01618 }
01619 while (attacking.any())
01620 {
01621 const Piece attack = state.getPieceOf(attacking.takeOneBit());
01622 if (P == BLACK)
01623 {
01624 evalOnePiece<true>(alt(P), captured, attack.ptype(),
01625 has_support, result);
01626 }
01627 else
01628 {
01629 evalOnePiece<false>(alt(P), captured, attack.ptype(),
01630 has_support, result);
01631 }
01632 }
01633 }
01634 updateChanged<BLACK>(state, p, moved, captured_number,
01635 effected_mask, new_mask, attacked_mask, result);
01636 updateChanged<WHITE>(state, p, moved, captured_number,
01637 effected_mask, new_mask, attacked_mask, result);
01638 }
01639
01640 osl::CArray<osl::MultiInt, 512*512>
01641 osl::eval::ml::NonPawnAttackedPtypePair::table;
01642 void osl::eval::ml::NonPawnAttackedPtypePair::setUp(const Weights &weights)
01643 {
01644 for (int i = 0; i < ONE_DIM; ++i)
01645 {
01646 for (int s=0; s<NStages; ++s)
01647 table[i][s] = weights.value(i + ONE_DIM*s);
01648 }
01649 for (int i=0; i<PTYPE_SIZE*2*PTYPE_SIZE; ++i)
01650 for (int j=i+1; j<PTYPE_SIZE*2*PTYPE_SIZE; ++j) {
01651 table[index2(j,i)] = table[index2(i,j)];
01652 }
01653 }
01654 template <osl::Player Owner>
01655 osl::MultiInt osl::eval::ml::NonPawnAttackedPtypePair::
01656 evalOne(const NumEffectState &state)
01657 {
01658 MultiInt result;
01659 PieceMask attacked = state.effectedMask(alt(Owner)) & state.getOnBoardMask(Owner);
01660 attacked.reset(state.getKingPiece<Owner>().number());
01661 mask_t ppawn = state.promotedPieces().getMask<PAWN>() & attacked.selectBit<PAWN>();
01662 attacked.clearBit<PAWN>();
01663 attacked.orMask(PtypeFuns<PAWN>::indexNum, ppawn);
01664 PieceVector pieces;
01665 while (attacked.any())
01666 {
01667 const Piece piece = state.getPieceOf(attacked.takeOneBit());
01668 pieces.push_back(piece);
01669 }
01670 for (size_t i=0; i+1<pieces.size(); ++i) {
01671 const int i0 = index1(state, pieces[i]);
01672 for (size_t j=i+1; j<pieces.size(); ++j) {
01673 const int i1 = index1(state, pieces[j]);
01674 if (Owner == BLACK)
01675 result += table[index2(i0, i1)];
01676 else
01677 result -= table[index2(i0, i1)];
01678 }
01679 }
01680 return result;
01681 }
01682
01683 osl::MultiInt osl::eval::ml::NonPawnAttackedPtypePair::
01684 eval(const NumEffectState &state)
01685 {
01686 return evalOne<BLACK>(state) + evalOne<WHITE>(state);
01687 }
01688
01689
01690 osl::misc::CArray<MultiInt, 160>
01691 osl::eval::ml::PtypeCount::table;
01692 osl::misc::CArray<MultiInt, 2240>
01693 osl::eval::ml::PtypeCount::xy_table;
01694 osl::misc::CArray<MultiInt, 2240>
01695 osl::eval::ml::PtypeCount::xy_attack_table;
01696 osl::misc::CArray<MultiInt, 2240>
01697 osl::eval::ml::PtypeCount::xy_table_diff;
01698 osl::misc::CArray<MultiInt, 2240>
01699 osl::eval::ml::PtypeCount::xy_attack_table_diff;
01700 void osl::eval::ml::PtypeCount::setUp(const Weights &weights)
01701 {
01702 for (size_t i = 0; i < ONE_DIM; ++i)
01703 {
01704 for (int s=0; s<NStages; ++s)
01705 table[i][s] = weights.value(i + ONE_DIM*s);
01706 }
01707 }
01708
01709 void osl::eval::ml::PtypeCountXY::setUp(const Weights &weights)
01710 {
01711 for (size_t i = 0; i < ONE_DIM; ++i)
01712 {
01713 for (int s=0; s<NStages; ++s)
01714 PtypeCount::xy_table[i][s] = weights.value(i + ONE_DIM*s);
01715 }
01716 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
01717 Ptype ptype=static_cast<Ptype>(i);
01718 int indexMin=Ptype_Table.getIndexMin(ptype);
01719 int size=Ptype_Table.getIndexLimit(ptype)-indexMin;
01720 for(int x=0;x<5;x++){
01721 for(int j=0;j<size;j++){
01722 for(int k=0;k<160;k+=40){
01723 PtypeCount::xy_table[(indexMin+j+k)*5+x]+=PtypeCount::table[indexMin+j+k];
01724 }
01725 }
01726 }
01727 }
01728 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
01729 Ptype ptype=static_cast<Ptype>(i);
01730 int indexMin=Ptype_Table.getIndexMin(ptype);
01731 int size=Ptype_Table.getIndexLimit(ptype)-indexMin;
01732 for(int x=0;x<5;x++){
01733 for(int k=0;k<160;k+=40)
01734 PtypeCount::xy_table_diff[(indexMin+k)*5+x]=PtypeCount::xy_table[(indexMin+k)*5+x];
01735 for(int j=1;j<size;j++){
01736 for(int k=0;k<160;k+=40)
01737 PtypeCount::xy_table_diff[(indexMin+k+j)*5+x]=PtypeCount::xy_table[(indexMin+k+j)*5+x]-PtypeCount::xy_table[(indexMin+k+j-1)*5+x];
01738 }
01739 }
01740 for(int y=0;y<9;y++){
01741 for(int k=0;k<160;k+=40)
01742 PtypeCount::xy_table_diff[800+(indexMin+k)*9+y]=PtypeCount::xy_table[800+(indexMin+k)*9+y];
01743 for(int j=1;j<size;j++){
01744 for(int k=0;k<160;k+=40)
01745 PtypeCount::xy_table_diff[800+(indexMin+k+j)*9+y]=PtypeCount::xy_table[800+(indexMin+k+j)*9+y]-PtypeCount::xy_table[800+(indexMin+k+j-1)*9+y];
01746 }
01747 }
01748 }
01749 }
01750
01751 void osl::eval::ml::PtypeCountXYAttack::setUp(const Weights &weights)
01752 {
01753 for (size_t i = 0; i < ONE_DIM; ++i)
01754 {
01755 for (int s=0; s<NStages; ++s)
01756 PtypeCount::xy_attack_table[i][s] = weights.value(i + ONE_DIM*s);
01757 }
01758 for(int i=PTYPE_BASIC_MIN;i<=PTYPE_MAX;i++){
01759 Ptype ptype=static_cast<Ptype>(i);
01760 int indexMin=Ptype_Table.getIndexMin(ptype);
01761 int size=Ptype_Table.getIndexLimit(ptype)-indexMin;
01762 for(int x=0;x<5;x++){
01763 for(int k=0;k<160;k+=40)
01764 PtypeCount::xy_attack_table_diff[(indexMin+k)*5+x]=PtypeCount::xy_attack_table[(indexMin+k)*5+x];
01765 for(int j=1;j<size;j++){
01766 for(int k=0;k<160;k+=40)
01767 PtypeCount::xy_attack_table_diff[(indexMin+k+j)*5+x]=PtypeCount::xy_attack_table[(indexMin+k+j)*5+x]-PtypeCount::xy_attack_table[(indexMin+k+j-1)*5+x];
01768 }
01769 }
01770 for(int y=0;y<9;y++){
01771 for(int k=0;k<160;k+=40)
01772 PtypeCount::xy_attack_table_diff[800+(indexMin+k)*9+y]=PtypeCount::xy_attack_table[800+(indexMin+k)*9+y];
01773 for(int j=1;j<size;j++){
01774 for(int k=0;k<160;k+=40)
01775 PtypeCount::xy_attack_table_diff[800+(indexMin+k+j)*9+y]=PtypeCount::xy_attack_table[800+(indexMin+k+j)*9+y]-PtypeCount::xy_attack_table[800+(indexMin+k+j-1)*9+y];
01776 }
01777 }
01778 }
01779 }
01780
01781 template<osl::Player P,osl::Ptype T>
01782 MultiInt osl::eval::ml::PtypeCount::
01783 evalPlayerPtype(const osl::CArray2d<int, 2, osl::PTYPE_SIZE> &ptype_count,
01784 const osl::CArray2d<int, 2, osl::PTYPE_SIZE> &ptype_board_count,
01785 const osl::CArray<int,2> &kings_x,
01786 const osl::CArray<int,2> &kings_y)
01787 {
01788 MultiInt out;
01789 int i=PlayerTraits<P>::index;
01790 int j=static_cast<int>(T);
01791 if (ptype_count[i][j] != 0)
01792 {
01793 const int index_x = indexCountX<T>(ptype_count[i][j], kings_x[i]);
01794 const int index_y = indexCountY<T>(ptype_count[i][j], kings_y[i]);
01795 const int index_x_attack =
01796 indexCountX<T>(ptype_count[i][j], kings_x[1-i]);
01797 const int index_y_attack =
01798 indexCountY<T>(ptype_count[i][j], kings_y[1-i]);
01799 if (P == BLACK)
01800 {
01801 out += xy_table[index_x] + xy_table[index_y];
01802 out += xy_attack_table[index_x_attack] +
01803 xy_attack_table[index_y_attack];
01804 }
01805 else
01806 {
01807 out -= (xy_table[index_x] + xy_table[index_y]);
01808 out -= (xy_attack_table[index_x_attack] +
01809 xy_attack_table[index_y_attack]);
01810 }
01811 if (ptype_board_count[i][j] != 0)
01812 {
01813 const int index_x =
01814 indexBoardCountX<T>(ptype_board_count[i][j], kings_x[i]);
01815 const int index_y =
01816 indexBoardCountY<T>(ptype_board_count[i][j], kings_y[i]);
01817 const int index_x_attack =
01818 indexBoardCountX<T>(ptype_board_count[i][j], kings_x[(i + 1) & 1]);
01819 const int index_y_attack =
01820 indexBoardCountY<T>(ptype_board_count[i][j], kings_y[(i + 1) & 1]);
01821 if (P == BLACK)
01822 {
01823 out += xy_table[index_x] + xy_table[index_y];
01824 out += xy_attack_table[index_x_attack] +
01825 xy_attack_table[index_y_attack];
01826 }
01827 else
01828 {
01829 out -= (xy_table[index_x] + xy_table[index_y]);
01830 out -= (xy_attack_table[index_x_attack] +
01831 xy_attack_table[index_y_attack]);
01832 }
01833 }
01834 }
01835 return out;
01836 }
01837
01838 void
01839 #ifdef __GNUC__
01840 __attribute__((__flatten__))
01841 #endif
01842 osl::eval::ml::PtypeCount::eval(
01843 const NumEffectState &state,
01844 const CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
01845 const CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
01846 MultiInt &out)
01847 {
01848 out.clear();
01849 CArray<int, 2> kings_x = {{ state.getKingPosition<BLACK>().x(),
01850 state.getKingPosition<WHITE>().x() }};
01851 CArray<int, 2> kings_y = {{ state.getKingPosition<BLACK>().y(),
01852 10 - state.getKingPosition<WHITE>().y() }};
01853 if (kings_x[0] > 5)
01854 kings_x[0] = 10 - kings_x[0];
01855 if (kings_x[1] > 5)
01856 kings_x[1] = 10 - kings_x[1];
01857 out =
01858 evalPlayerPtype<BLACK,PPAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
01859 evalPlayerPtype<BLACK,PLANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
01860 evalPlayerPtype<BLACK,PKNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
01861 evalPlayerPtype<BLACK,PSILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
01862 evalPlayerPtype<BLACK,PBISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
01863 evalPlayerPtype<BLACK,PROOK>(ptype_count,ptype_board_count,kings_x,kings_y)+
01864 evalPlayerPtype<BLACK,GOLD>(ptype_count,ptype_board_count,kings_x,kings_y)+
01865 evalPlayerPtype<BLACK,PAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
01866 evalPlayerPtype<BLACK,LANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
01867 evalPlayerPtype<BLACK,KNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
01868 evalPlayerPtype<BLACK,SILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
01869 evalPlayerPtype<BLACK,BISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
01870 evalPlayerPtype<BLACK,ROOK>(ptype_count,ptype_board_count,kings_x,kings_y)+
01871 evalPlayerPtype<WHITE,PPAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
01872 evalPlayerPtype<WHITE,PLANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
01873 evalPlayerPtype<WHITE,PKNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
01874 evalPlayerPtype<WHITE,PSILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
01875 evalPlayerPtype<WHITE,PBISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
01876 evalPlayerPtype<WHITE,PROOK>(ptype_count,ptype_board_count,kings_x,kings_y)+
01877 evalPlayerPtype<WHITE,GOLD>(ptype_count,ptype_board_count,kings_x,kings_y)+
01878 evalPlayerPtype<WHITE,PAWN>(ptype_count,ptype_board_count,kings_x,kings_y)+
01879 evalPlayerPtype<WHITE,LANCE>(ptype_count,ptype_board_count,kings_x,kings_y)+
01880 evalPlayerPtype<WHITE,KNIGHT>(ptype_count,ptype_board_count,kings_x,kings_y)+
01881 evalPlayerPtype<WHITE,SILVER>(ptype_count,ptype_board_count,kings_x,kings_y)+
01882 evalPlayerPtype<WHITE,BISHOP>(ptype_count,ptype_board_count,kings_x,kings_y)+
01883 evalPlayerPtype<WHITE,ROOK>(ptype_count,ptype_board_count,kings_x,kings_y);
01884 }
01885
01886 template<osl::Player P>
01887 void osl::eval::ml::PtypeCount::evalWithUpdateBang(
01888 const NumEffectState &state,
01889 Move last_move,
01890 CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
01891 CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
01892 MultiInt &last_value_and_out,
01893 unsigned int &ptypeo_mask)
01894 {
01895 assert(last_move.player()==P);
01896 const Player altP=PlayerTraits<P>::opponent;
01897 CArray<int, 2> kings_x = {{ state.getKingPosition<BLACK>().x(),
01898 state.getKingPosition<WHITE>().x() }};
01899 CArray<int, 2> kings_y = {{ state.getKingPosition<BLACK>().y(),
01900 10 - state.getKingPosition<WHITE>().y() }};
01901 if (kings_x[0] > 5)
01902 kings_x[0] = 10 - kings_x[0];
01903 if (kings_x[1] > 5)
01904 kings_x[1] = 10 - kings_x[1];
01905
01906 if (last_move.ptype() == KING)
01907 {
01908 const Ptype capturedPtype = last_move.capturePtype();
01909 if (capturedPtype != PTYPE_EMPTY)
01910 {
01911 const PtypeO capturedPtypeO = last_move.capturePtypeO();
01912 if(--ptype_count[altP][capturedPtype]==0)
01913 ptypeo_mask &= ~(1<<(last_move.capturePtypeO()-PTYPEO_MIN));
01914 --ptype_board_count[altP][capturedPtype];
01915 const Ptype base_captured = unpromote(capturedPtype);
01916 ++ptype_count[P][base_captured];
01917 ptypeo_mask |= (1<<(captured(capturedPtypeO)-PTYPEO_MIN));
01918 }
01919 eval(state, ptype_count, ptype_board_count, last_value_and_out);
01920 return;
01921 }
01922
01923 MultiInt sum;
01924 if (last_move.isDrop())
01925 {
01926 const int count = ++ptype_board_count[P][last_move.ptype()];
01927 sum = valueBoardAll(last_move.ptype(),count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP]);
01928 }
01929 else{
01930 Ptype capturedPtype = last_move.capturePtype();
01931 if (capturedPtype != PTYPE_EMPTY)
01932 {
01933 const int count = --ptype_count[altP][capturedPtype];
01934 if(count==0)
01935 ptypeo_mask &= ~(1<<(last_move.capturePtypeO()-PTYPEO_MIN));
01936 const int board_count = --ptype_board_count[altP][capturedPtype];
01937 const Ptype base_captured = unpromote(capturedPtype);
01938 const int c_count = ++ptype_count[P][base_captured];
01939 ptypeo_mask |= 1<<(captured(last_move.capturePtypeO())-PTYPEO_MIN);
01940 sum=valueAll(capturedPtype,count+1,kings_x[altP],kings_y[altP],kings_x[P],kings_y[P])+
01941 valueBoardAll(capturedPtype,board_count+1,kings_x[altP],kings_y[altP],kings_x[P],kings_y[P])+
01942 valueAll(base_captured,c_count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP]);
01943 }
01944 if (last_move.isPromote())
01945 {
01946 const Ptype old_ptype = last_move.oldPtype();
01947 const Ptype new_ptype = last_move.ptype();
01948 const int base_count = --ptype_count[P][old_ptype];
01949 const int base_board_count = --ptype_board_count[P][old_ptype];
01950 const int count = ++ptype_count[P][new_ptype];
01951 const int board_count = ++ptype_board_count[P][new_ptype];
01952 if(base_count==0)
01953 ptypeo_mask &= ~(1<<(last_move.oldPtypeO()-PTYPEO_MIN));
01954 ptypeo_mask |= (1<<(last_move.ptypeO()-PTYPEO_MIN));
01955 sum+=valueAll(new_ptype,count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP])+
01956 valueBoardAll(new_ptype,board_count,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP])-
01957 valueAll(old_ptype,base_count+1,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP])-
01958 valueBoardAll(old_ptype,base_board_count+1,kings_x[P],kings_y[P],kings_x[altP],kings_y[altP]);
01959 }
01960 }
01961 if(P==BLACK) last_value_and_out+= sum;
01962 else last_value_and_out-= sum;
01963 }
01964
01965 void osl::eval::ml::
01966 LanceEffectPieceKingRelative::setUp(const Weights &weights)
01967 {
01968 for (size_t i = 0; i < ONE_DIM; ++i)
01969 {
01970 for (int s=0; s<NStages; ++s)
01971 table[i][s] = weights.value(i + ONE_DIM*s);
01972 }
01973 }
01974
01975 osl::misc::CArray<MultiInt, 9792>
01976 osl::eval::ml::LanceEffectPieceKingRelative::table;
01977
01978 MultiInt osl::eval::ml::
01979 LanceEffectPieceKingRelative::eval(const NumEffectState &state)
01980 {
01981 MultiInt result;
01982 for (int i = PtypeTraits<LANCE>::indexMin;
01983 i < PtypeTraits<LANCE>::indexLimit;
01984 ++i)
01985 {
01986 const Piece lance = state.getPieceOf(i);
01987 if (lance.isOnBoard() && !lance.isPromoted())
01988 {
01989 const Position self_king = state.getKingPosition(lance.owner());
01990 const Position opp_king = state.getKingPosition(alt(lance.owner()));
01991 Position p = state.getMobility(lance.owner() == BLACK ? U : D,
01992 lance.number());
01993 if (!p.isOnBoard())
01994 {
01995 const int index1 = 0 + 0 + (PTYPEO_EDGE - PTYPEO_MIN) * 17 * 9;
01996 const int index2 = 0 + 0 + (PTYPEO_EDGE - PTYPEO_MIN) * 17 * 9 + 4896;
01997 if (lance.owner() == BLACK)
01998 {
01999 result += table[index1];
02000 result += table[index2];
02001 }
02002 else
02003 {
02004 result -= table[index1];
02005 result -= table[index2];
02006 }
02007 }
02008 else
02009 {
02010 const int index1 = index(lance.owner(), p, opp_king,
02011 state.getPieceAt(p).ptypeO(), true);
02012 const int index2 = index(lance.owner(), p, self_king,
02013 state.getPieceAt(p).ptypeO(), false);
02014 if (lance.owner() == BLACK)
02015 {
02016 result += table[index1];
02017 result += table[index2];
02018 }
02019 else
02020 {
02021 result -= table[index1];
02022 result -= table[index2];
02023 }
02024 }
02025 }
02026 }
02027 return result;
02028 }
02029
02030 osl::misc::CArray<MultiInt, 1440>
02031 osl::eval::ml::PtypeYPawnY::table;
02032
02033 void osl::eval::ml::PtypeYPawnY::setUp(const Weights &weights)
02034 {
02035 for (size_t i = 0; i < ONE_DIM; ++i)
02036 {
02037 for (int s = 0; s < NStages; ++s)
02038 {
02039 table[i][s] = weights.value(i + ONE_DIM*s);
02040 }
02041 }
02042 }
02043
02044 osl::MultiInt osl::eval::ml::
02045 PtypeYPawnY::eval(const NumEffectState &state,
02046 const CArray2d<int, 2, 9> &pawns)
02047 {
02048 MultiInt result;
02049 for (int i = 0; i < Piece::SIZE; ++i)
02050 {
02051 const Piece piece = state.getPieceOf(i);
02052
02053 if (piece.ptype() == PAWN)
02054 continue;
02055 if (!piece.isOnBoard())
02056 continue;
02057
02058 const int idx = index(piece.owner(), piece.ptype(), piece.position().y(),
02059 pawns[piece.owner()][piece.position().x() - 1]);
02060 if (piece.owner() == BLACK)
02061 {
02062 result += table[idx];
02063 }
02064 else
02065 {
02066 result -= table[idx];
02067 }
02068 }
02069
02070 return result;
02071 }
02072
02073 template<osl::Player P>
02074 void osl::eval::ml::
02075 PtypeYPawnY::evalWithUpdateBang(const NumEffectState &state,
02076 Move moved,
02077 const CArray2d<int, 2, 9> &pawns,
02078 MultiInt& last_value)
02079 {
02080 Ptype captured = moved.capturePtype();
02081 assert(P==moved.player());
02082
02083 if (moved.oldPtype() == PAWN)
02084 {
02085 const int x = moved.to().x();
02086 const int old_pawn_y = (moved.isDrop() ? 0 : moved.from().y());
02087 const int new_pawn_y = pawns[P][moved.to().x() - 1];
02088 for (int y = 1; y <= 9; ++y)
02089 {
02090 const Piece p = state.getPieceAt(Position(x, y));
02091 if (y == moved.to().y())
02092 {
02093 if (p.ptype() == PPAWN)
02094 {
02095 const int idx_new = index(P, p.ptype(), y, new_pawn_y);
02096 if (P == BLACK)
02097 {
02098 last_value += table[idx_new];
02099 }
02100 else
02101 {
02102 last_value -= table[idx_new];
02103 }
02104 }
02105 }
02106 else if (!p.isEmpty() && p.owner() == P)
02107 {
02108 const int idx_old = index(P, p.ptype(), y, old_pawn_y);
02109 const int idx_new = index(P, p.ptype(), y, new_pawn_y);
02110 if (P == BLACK)
02111 {
02112 last_value -= table[idx_old];
02113 last_value += table[idx_new];
02114 }
02115 else
02116 {
02117 last_value += table[idx_old];
02118 last_value -= table[idx_new];
02119 }
02120 }
02121 }
02122 }
02123 else
02124 {
02125 if (!moved.isDrop())
02126 {
02127 const int pawn_y = pawns[P][moved.from().x() - 1];
02128 const int idx = index(P, moved.oldPtype(), moved.from().y(),
02129 pawn_y);
02130 if (P == BLACK)
02131 {
02132 last_value -= table[idx];
02133 }
02134 else
02135 {
02136 last_value += table[idx];
02137 }
02138 }
02139 {
02140 const int pawn_y = pawns[P][moved.to().x() - 1];
02141 const int idx = index(P, moved.ptype(), moved.to().y(),
02142 pawn_y);
02143 if (P == BLACK)
02144 {
02145 last_value += table[idx];
02146 }
02147 else
02148 {
02149 last_value -= table[idx];
02150 }
02151 }
02152 }
02153
02154 if (captured != PTYPE_EMPTY)
02155 {
02156 if (captured == PAWN)
02157 {
02158 const int old_pawn_y = moved.to().y();
02159 const int new_pawn_y = 0;
02160 const int x = moved.to().x();
02161 for (int y = 1; y <= 9; ++y)
02162 {
02163 const Piece p = state.getPieceAt(Position(x, y));
02164 if (!p.isEmpty() && p.owner() == alt(P))
02165 {
02166 const int idx_old = index(alt(P), p.ptype(), y,
02167 old_pawn_y);
02168 const int idx_new = index(alt(P), p.ptype(), y,
02169 new_pawn_y);
02170 if (P == BLACK)
02171 {
02172 last_value += table[idx_old];
02173 last_value -= table[idx_new];
02174 }
02175 else
02176 {
02177 last_value -= table[idx_old];
02178 last_value += table[idx_new];
02179 }
02180 }
02181 }
02182 }
02183 else
02184 {
02185 const int pawn_y = pawns[alt(P)][moved.to().x() - 1];
02186 const int idx = index(alt(P), captured, moved.to().y(),
02187 pawn_y);
02188 if (P == BLACK)
02189 {
02190 last_value += table[idx];
02191 }
02192 else
02193 {
02194 last_value -= table[idx];
02195 }
02196 }
02197 }
02198 }
02199
02200 osl::misc::CArray<osl::MultiInt, 1215>
02201 osl::eval::ml::GoldAndSilverNearKing::table;
02202 osl::misc::CArray<osl::MultiInt, 9720>
02203 osl::eval::ml::GoldAndSilverNearKing::combination_table;
02204
02205 void osl::eval::ml::
02206 GoldAndSilverNearKing::setUp(const Weights &weights)
02207 {
02208 for (size_t i = 0; i < ONE_DIM; ++i)
02209 {
02210 for (int s=0; s<NStages; ++s)
02211 table[i][s] = weights.value(i + ONE_DIM*s);
02212 }
02213 }
02214
02215 void osl::eval::ml::
02216 GoldAndSilverNearKingCombination::setUp(const Weights &weights)
02217 {
02218 for (size_t i = 0; i < ONE_DIM; ++i)
02219 {
02220 for (int s=0; s<NStages; ++s)
02221 GoldAndSilverNearKing::combination_table[i][s] =
02222 weights.value(i + ONE_DIM*s);
02223 }
02224 }
02225
02226 template <osl::Player P>
02227 osl::MultiInt osl::eval::ml::
02228 GoldAndSilverNearKing::evalOne(const NumEffectState &state,
02229 const CArray2d<int, 2, 3> &gs_count)
02230 {
02231 MultiInt result;
02232 int total = 0;
02233 const Position king = state.getKingPosition<P>();
02234 for (size_t i = 0; i < gs_count.size2(); ++i)
02235 {
02236 total += gs_count[P][i];
02237 if (total != 0)
02238 {
02239 result += table[index<P>(king, i, total)];
02240 }
02241 }
02242 result += combination_table[
02243 indexCombination<P>(king, gs_count[P][0],
02244 gs_count[P][1], gs_count[P][2])];
02245 return P == BLACK ? result : -result;
02246 }
02247
02248 osl::MultiInt osl::eval::ml::
02249 GoldAndSilverNearKing::eval(const NumEffectState &state,
02250 const CArray2d<int, 2, 3> &gs_count)
02251 {
02252 return evalOne<BLACK>(state, gs_count) + evalOne<WHITE>(state, gs_count);
02253 }
02254
02255
02256 osl::misc::CArray<osl::MultiInt, 8192>
02257 osl::eval::ml::PtypeCombination::table;
02258
02259 void osl::eval::ml::
02260 PtypeCombination::setUp(const Weights &weights)
02261 {
02262 static CArray<MultiInt, 8192> orig_table;
02263 for (size_t i = 0; i < ONE_DIM; ++i)
02264 {
02265 for (int s = 0; s < NStages; ++s)
02266 {
02267 orig_table[i][s] = weights.value(i + ONE_DIM*s);
02268 }
02269 }
02270 for(int i=0;i<8192;i++){
02271 int pawn=(i>>12)&1;
02272 int ppawn=(i>>6)&1;
02273 int lance=(i>>11)&1;
02274 int plance=(i>>5)&1;
02275 int knight=(i>>10)&1;
02276 int pknight=(i>>4)&1;
02277 int silver=(i>>9)&1;
02278 int psilver=(i>>3)&1;
02279 int bishop=(i>>8)&1;
02280 int pbishop=(i>>2)&1;
02281 int rook=(i>>7)&1;
02282 int prook=(i>>1)&1;
02283 int gold=(i>>0)&1;
02284 int newIndex=ppawn|(plance<<1)|(pknight<<2)|(psilver<<3)|(pbishop<<4)|
02285 (prook<<5)|(gold<<6)|(pawn<<7)|(lance<<8)|(knight<<9)|(silver<<10)|
02286 (bishop<<11)|(rook<<12);
02287 table[newIndex]=orig_table[i];
02288 }
02289 }
02290
02291 osl::MultiInt osl::eval::ml::
02292 PtypeCombination::eval(unsigned int ptypeo_mask)
02293 {
02294 return evalOne<BLACK>(ptypeo_mask) + evalOne<WHITE>(ptypeo_mask);
02295 }
02296
02297
02298 osl::CArray<osl::MultiInt, 5*2>
02299 osl::eval::ml::SilverFork::table;
02300 inline
02301 std::pair<int,int> osl::eval::ml::
02302 SilverFork::matchRook(const NumEffectState& state, Piece rook,
02303 const CArray<bool,2>& has_silver,
02304 Position& silver_drop)
02305 {
02306 const Position sq = rook.position();
02307 if (rook.isPromoted() || sq.isPieceStand())
02308 return std::make_pair(0,0);
02309 const Player owner = rook.owner();
02310 if (! has_silver[alt(owner)] || ! sq.canPromote(alt(owner)))
02311 return std::make_pair(0,0);
02312 const CArray<Offset,2> offset = {{
02313 Board_Table.getOffset(owner, UL), Board_Table.getOffset(owner, UR)
02314 }};
02315 for (size_t i=0; i<offset.size(); ++i) {
02316 const Position next = sq+offset[i], next2 = next+offset[i];
02317 if (! state.getPieceAt(next).isEmpty() || state.hasEffectBy(owner, next))
02318 continue;
02319 const Piece p = state.getPieceAt(next2);
02320 if (! p.isOnBoardByOwner(owner))
02321 continue;
02322 silver_drop = next;
02323 if (p.ptype() == ROOK)
02324 return std::make_pair(playerToMul(owner), 0);
02325 if (p.ptype() == GOLD)
02326 return std::make_pair(playerToMul(owner), state.hasEffectBy(owner, next2) ? 1 : 2);
02327 }
02328 return std::make_pair(0,0);
02329 }
02330 inline
02331 std::pair<int,int> osl::eval::ml::
02332 SilverFork::matchGold(const NumEffectState& state, Piece gold,
02333 const CArray<bool,2>& has_silver, Position& silver_drop)
02334 {
02335 const Position sq = gold.position();
02336 if (sq.isPieceStand())
02337 return std::make_pair(0,0);
02338 const Player owner = gold.owner();
02339 if (! has_silver[alt(owner)] || ! sq.canPromote(alt(owner)))
02340 return std::make_pair(0,0);
02341 const CArray<Offset,2> offset = {{
02342 Board_Table.getOffset(BLACK, L), Board_Table.getOffset(BLACK, R)
02343 }};
02344 const bool guarded = state.hasEffectBy(owner, sq);
02345 for (size_t i=0; i<offset.size(); ++i) {
02346 const Position next = sq+offset[i], next2 = next+offset[i];
02347 const Piece np = state.getPieceAt(next);
02348 if (np.isEdge())
02349 continue;
02350 const Position next_down = next + Board_Table.getOffset(owner, D);
02351 if (! state.getPieceAt(next_down).isEmpty() || state.hasEffectBy(owner, next_down))
02352 continue;
02353 const Piece p = state.getPieceAt(next2);
02354 if (! p.isOnBoardByOwner(owner))
02355 continue;
02356 if (p.ptype() == ROOK || p.ptype() == GOLD) {
02357 silver_drop = next_down;
02358 const bool recaputure = guarded
02359 || (p.ptype() == GOLD && state.hasEffectBy(owner, next2))
02360 || (np.canMoveOn(owner) && ! state.hasEffectBy(alt(owner), next));
02361 return std::make_pair(playerToMul(owner), 3 + recaputure);
02362 }
02363 }
02364 return std::make_pair(0,0);
02365 }
02366
02367 osl::MultiIntPair osl::eval::ml::
02368 SilverFork::eval(const NumEffectState& state, CArray<std::pair<Position,int>,2>& silver_drop)
02369 {
02370 silver_drop.fill(std::make_pair(Position(),0));
02371 MultiIntPair result;
02372 const CArray<bool,2> has_silver = {{
02373 state.hasPieceOnStand<SILVER>(BLACK),
02374 state.hasPieceOnStand<SILVER>(WHITE),
02375 }};
02376 if (! has_silver[BLACK] && ! has_silver[WHITE])
02377 return result;
02378 Position drop;
02379 for (int i = PtypeTraits<ROOK>::indexMin;
02380 i < PtypeTraits<ROOK>::indexLimit; ++i)
02381 {
02382 const Piece rook = state.getPieceOf(i);
02383 std::pair<int,int> match = matchRook(state, rook, has_silver, drop);
02384 if (match.first) {
02385 const MultiInt value_attack = table[match.second*2];
02386 const Player attack = (match.first > 0) ? WHITE : BLACK;
02387 if (-value_attack[0] > silver_drop[attack].second) {
02388 silver_drop[attack].second = -value_attack[0];
02389 silver_drop[attack].first = drop;
02390 }
02391 if (match.first > 0)
02392 {
02393 result[BLACK] += table[match.second*2+1];
02394 result[WHITE] += value_attack;
02395 }
02396 else if (match.first < 0)
02397 {
02398 result[BLACK] -= value_attack;
02399 result[WHITE] -= table[match.second*2+1];
02400 }
02401 }
02402 }
02403
02404 for (int i = PtypeTraits<GOLD>::indexMin;
02405 i < PtypeTraits<GOLD>::indexLimit; ++i)
02406 {
02407 const Piece gold = state.getPieceOf(i);
02408 std::pair<int,int> match = matchGold(state, gold, has_silver, drop);
02409 if (match.first) {
02410 const MultiInt value_attack = table[match.second*2];
02411 const Player attack = (match.first > 0) ? WHITE : BLACK;
02412 if (-value_attack[0] > silver_drop[attack].second) {
02413 silver_drop[attack].second = -value_attack[0];
02414 silver_drop[attack].first = drop;
02415 }
02416 if (match.first > 0)
02417 {
02418 result[BLACK] += table[match.second*2+1];
02419 result[WHITE] += value_attack;
02420 }
02421 else if (match.first < 0)
02422 {
02423 result[BLACK] -= value_attack;
02424 result[WHITE] -= table[match.second*2+1];
02425 }
02426 }
02427 }
02428 return result;
02429 }
02430
02431 void osl::eval::ml::SilverFork::setUp(const Weights &weights)
02432 {
02433 for (int i = 0; i < ONE_DIM; ++i)
02434 {
02435 for (int s=0; s<NStages; ++s)
02436 table[i][s] = weights.value(i + ONE_DIM*s);
02437 }
02438 }
02439
02440 osl::CArray<osl::MultiInt, 256*2*2>
02441 osl::eval::ml::BishopRookFork::table;
02442 void osl::eval::ml::BishopRookFork::setUp(const Weights &weights)
02443 {
02444 for (int i = 0; i < ONE_DIM; ++i)
02445 {
02446 for (int s=0; s<NStages; ++s)
02447 table[i][s] = weights.value(i + ONE_DIM*s);
02448 }
02449 for (int i=0; i<PTYPE_SIZE; ++i)
02450 for (int j=i+1; j<PTYPE_SIZE; ++j)
02451 {
02452 table[bishopIndex((Ptype)j,(Ptype)i)*2] = table[bishopIndex((Ptype)i,(Ptype)j)*2];
02453 table[bishopIndex((Ptype)j,(Ptype)i)*2+1] = table[bishopIndex((Ptype)i,(Ptype)j)*2+1];
02454 table[rookIndex((Ptype)j,(Ptype)i)*2] = table[rookIndex((Ptype)i,(Ptype)j)*2];
02455 table[rookIndex((Ptype)j,(Ptype)i)*2+1] = table[rookIndex((Ptype)i,(Ptype)j)*2+1];
02456 }
02457 }
02458 inline
02459 const osl::Position osl::eval::ml::BishopRookFork::
02460 findDropInLine(const NumEffectState& state, Player defense,
02461 const Position a, const Position b, Piece king)
02462 {
02463 Offset offset = Board_Table.getShortOffset(Offset32(b,a));
02464 Position drop_position;
02465 Position sq=a+offset;
02466 for (Piece p=state.getPieceAt(sq); p.isEmpty(); sq+=offset, p=state.getPieceAt(sq))
02467 {
02468 if (! drop_position.isPieceStand())
02469 continue;
02470 if (! state.hasEffectBy(defense, sq)
02471 || (state.hasEffectBy(alt(defense), sq)
02472 && ! state.hasEffectNotBy(defense, king, sq)))
02473 drop_position = sq;
02474 }
02475 return (sq == b) ? drop_position : Position();
02476 }
02477 inline
02478 bool osl::eval::ml::BishopRookFork::
02479 testCenter(const NumEffectState& state, Player defense,
02480 const Position a, const Position b, Piece king,
02481 Position center)
02482 {
02483 const Piece p = state.getPieceAt(center);
02484 if (! p.isEmpty()
02485 || (state.hasEffectBy(defense, center)
02486 && (! state.hasEffectBy(alt(defense), center)
02487 || state.hasEffectNotBy(defense, king, center))))
02488 return false;
02489 return state.isEmptyBetween(center, a, true)
02490 && state.isEmptyBetween(center, b, true);
02491 }
02492 inline
02493 const osl::Position osl::eval::ml::
02494 BishopRookFork::isBishopForkPosition(const NumEffectState& state, Player defense,
02495 const Position a, const Position b)
02496 {
02497 const Piece king = state.getKingPiece(defense);
02498 const int cx = b.x() - a.x(), cy = b.y() - a.y();
02499 if ((cx + cy) % 2)
02500 return Position();
02501 const int p = (cx+cy)/2, q = (cx-cy)/2;
02502 if (p == 0 || q == 0)
02503 return findDropInLine(state, defense, a, b, king);
02504
02505 const CArray<Position,2> centers = {{
02506 b + Offset(-p,-p), b + Offset(-q,q)
02507 }};
02508
02509 for (size_t i=0; i<centers.size(); ++i) {
02510 if (! centers[i].isOnBoardRegion())
02511 continue;
02512 if (testCenter(state, defense, a, b, king, centers[i]))
02513 return centers[i];
02514 }
02515 return Position();
02516 }
02517
02518 inline
02519 const osl::Position osl::eval::ml::
02520 BishopRookFork::isRookForkPosition(const NumEffectState& state, Player defense,
02521 const Position a, const Position b)
02522 {
02523 const Piece king = state.getKingPiece(defense);
02524 const CArray<Position,2> centers = {{
02525 Position(a.x(), b.y()), Position(b.x(), a.y())
02526 }};
02527 if (centers[0] == a || centers[0] == b)
02528 return findDropInLine(state, defense, a, b, king);
02529 for (size_t i=0; i<centers.size(); ++i)
02530 {
02531 assert(centers[i].isOnBoardRegion());
02532 if (testCenter(state, defense, a, b, king, centers[i]))
02533 return centers[i];
02534 }
02535 return Position();
02536 }
02537
02538 template <osl::Player Defense>
02539 osl::MultiIntPair osl::eval::ml::
02540 BishopRookFork::evalOne(const NumEffectState &state, const PieceVector& target,
02541 std::pair<Position,int>& bishop_drop,
02542 std::pair<Position,int>& rook_drop)
02543 {
02544 MultiIntPair result;
02545 for (size_t i=0; i<target.size(); ++i)
02546 {
02547 const Piece pi = target[i];
02548 assert(pi.isOnBoardByOwner(Defense));
02549 for (size_t j=i+1; j<target.size(); ++j)
02550 {
02551 const Piece pj = target[j];
02552 assert(pj.isOnBoardByOwner(Defense));
02553 if (state.hasPieceOnStand<BISHOP>(alt(Defense)))
02554 {
02555 const Position center
02556 = isBishopForkPosition(state, Defense, pi.position(), pj.position());
02557 if (! center.isPieceStand()) {
02558 const int index = bishopIndex(pi.ptype(), pj.ptype())*2;
02559 const MultiInt value_attack = table[index];
02560 if (-value_attack[0] > bishop_drop.second) {
02561 bishop_drop.second = -value_attack[0];
02562 bishop_drop.first = center;
02563 }
02564 if (Defense == BLACK)
02565 {
02566 result[BLACK] += table[index+1];
02567 result[WHITE] += value_attack;
02568 }
02569 else
02570 {
02571 result[BLACK] -= value_attack;
02572 result[WHITE] -= table[index+1];
02573 }
02574 }
02575 }
02576 if (state.hasPieceOnStand<ROOK>(alt(Defense)))
02577 {
02578 const Position center
02579 = isRookForkPosition(state, Defense, pi.position(), pj.position());
02580 if (! center.isPieceStand()) {
02581 const int index = rookIndex(pi.ptype(), pj.ptype())*2;
02582 const MultiInt value_attack = table[index];
02583 if (-value_attack[0] > rook_drop.second) {
02584 rook_drop.second = -value_attack[0];
02585 rook_drop.first = center;
02586 }
02587 if (Defense == BLACK)
02588 {
02589 result[BLACK] += table[index+1];
02590 result[WHITE] += value_attack;
02591 }
02592 else
02593 {
02594 result[BLACK] -= value_attack;
02595 result[WHITE] -= table[index+1];
02596 }
02597 }
02598 }
02599 }
02600 }
02601 assert(bishop_drop.second == 0 || ! bishop_drop.first.isPieceStand());
02602 return result;
02603 }
02604
02605 osl::MultiIntPair osl::eval::ml::
02606 BishopRookFork::eval(const NumEffectState &state,
02607 CArray<std::pair<Position,int>,2>& bishop_drop,
02608 CArray<std::pair<Position,int>,2>& rook_drop)
02609 {
02610 bishop_drop.fill(std::make_pair(Position(),0));
02611 rook_drop.fill(std::make_pair(Position(),0));
02612 MultiIntPair result;
02613 const CArray<bool,2> has_bishop = {{
02614 state.hasPieceOnStand<BISHOP>(BLACK),
02615 state.hasPieceOnStand<BISHOP>(WHITE),
02616 }};
02617 const CArray<bool,2> has_rook = {{
02618 state.hasPieceOnStand<ROOK>(BLACK),
02619 state.hasPieceOnStand<ROOK>(WHITE),
02620 }};
02621 if (has_bishop[BLACK] + has_bishop[WHITE]
02622 + has_rook[BLACK] + has_rook[WHITE] == 0)
02623 return result;
02624 CArray<PieceVector,2> pieces;
02625 {
02626 PieceMask notcovered = ~state.effectedMask(BLACK);
02627 notcovered &= ~state.effectedMask(WHITE);
02628 notcovered.clearBit<PAWN>();
02629 notcovered.setBit<KING>();
02630 for (int z=0; z<2; ++z)
02631 {
02632 PieceMask target = notcovered & state.getOnBoardMask(indexToPlayer(z));
02633 while (target.any())
02634 pieces[z].push_back(state.getPieceOf(target.takeOneBit()));
02635 }
02636 }
02637 if (has_bishop[WHITE] + has_rook[WHITE])
02638 result += evalOne<BLACK>(state, pieces[BLACK], bishop_drop[WHITE], rook_drop[WHITE]);
02639 if (has_bishop[BLACK] + has_rook[BLACK])
02640 result += evalOne<WHITE>(state, pieces[WHITE], bishop_drop[BLACK], rook_drop[BLACK]);
02641 return result;
02642 }
02643
02644
02645
02646 osl::CArray<osl::MultiInt, 256*2*2>
02647 osl::eval::ml::KnightFork::table;
02648 void osl::eval::ml::KnightFork::setUp(const Weights &weights)
02649 {
02650 for (int i = 0; i < ONE_DIM; ++i)
02651 {
02652 for (int s=0; s<NStages; ++s)
02653 table[i][s] = weights.value(i + ONE_DIM*s);
02654 }
02655 for (int i=0; i<PTYPE_SIZE; ++i)
02656 for (int j=i+1; j<PTYPE_SIZE; ++j) {
02657 table[index((Ptype)j,(Ptype)i)*2] = table[index((Ptype)i,(Ptype)j)*2];
02658 table[index((Ptype)j,(Ptype)i)*2+1] = table[index((Ptype)i,(Ptype)j)*2+1];
02659 table[(index((Ptype)j,(Ptype)i)+DROP_DIM)*2] = table[(index((Ptype)i,(Ptype)j)+DROP_DIM)*2];
02660 table[(index((Ptype)j,(Ptype)i)+DROP_DIM)*2+1] = table[(index((Ptype)i,(Ptype)j)+DROP_DIM)*2+1];
02661 }
02662 }
02663
02664 template <osl::Player Defense>
02665 osl::MultiIntPair osl::eval::ml::
02666 KnightFork::evalOne(const NumEffectState &state, const CArray<PieceVector,10>& pieces,
02667 bool has_knight, std::pair<Position,int>& knight_drop)
02668 {
02669 MultiIntPair result;
02670 const int z = playerToIndex(Defense);
02671 for (int y=3-z*2; y<=9-z*2; ++y) {
02672 const int y_drop = y - playerToMul(Defense)*2;
02673 for (size_t i=0; i<pieces[y].size(); ++i)
02674 {
02675 const Piece pi = pieces[y][i];
02676 assert(pi.isOnBoardByOwner(Defense));
02677 assert(pi.position().y() == y);
02678 for (size_t j=i+1; j<pieces[y].size(); ++j)
02679 {
02680 const Piece pj = pieces[y][j];
02681 assert(pj.isOnBoardByOwner(Defense));
02682 assert(pj.position().y() == y);
02683 if (! isForkPosition(state, Defense, y_drop,
02684 pi.position().x(), pj.position().x()))
02685 continue;
02686 int found = index(pi.ptype(), pj.ptype());
02687 if (! has_knight)
02688 found += DROP_DIM;
02689 found *= 2;
02690 const MultiInt value_attack = table[found];
02691 if (Defense == BLACK)
02692 {
02693 result[BLACK] += table[found+1];
02694 result[WHITE] += value_attack;
02695 }
02696 else
02697 {
02698 result[BLACK] -= value_attack;
02699 result[WHITE] -= table[found+1];
02700 }
02701 if (has_knight && -value_attack[0] > knight_drop.second) {
02702 knight_drop.second = -value_attack[0];
02703 knight_drop.first = Position((pi.position().x()+pj.position().x())/2, y_drop);
02704 }
02705 }
02706 }
02707 }
02708 return result;
02709 }
02710
02711 inline bool osl::eval::ml::
02712 KnightFork::isForkPosition(const NumEffectState& state, Player defense,
02713 int y, int x0, int x1)
02714 {
02715 if (abs(x0 -x1) != 2)
02716 return false;
02717 const Position drop = Position((x0+x1)/2, y);
02718 return state.getPieceAt(drop).isEmpty() && ! state.hasEffectBy(defense, drop);
02719 }
02720
02721 osl::MultiIntPair osl::eval::ml::
02722 KnightFork::eval(const NumEffectState &state, CArray<std::pair<Position,int>,2>& knight_drop)
02723 {
02724 knight_drop.fill(std::make_pair(Position(),0));
02725 MultiIntPair result;
02726 const CArray<bool,2> has_knight = {{
02727 state.hasPieceOnStand<KNIGHT>(BLACK),
02728 state.hasPieceOnStand<KNIGHT>(WHITE),
02729 }};
02730
02731 const CArray<bool,2> may_have_knight = {{
02732 has_knight[BLACK]
02733 || (state.effectedMask(BLACK).selectBit<KNIGHT>()
02734 & ~state.effectedMask(WHITE).selectBit<KNIGHT>()
02735 & state.getOnBoardMask(WHITE).getMask(PtypeFuns<KNIGHT>::indexNum)).any(),
02736 has_knight[WHITE]
02737 || (state.effectedMask(WHITE).selectBit<KNIGHT>()
02738 & ~state.effectedMask(BLACK).selectBit<KNIGHT>()
02739 & state.getOnBoardMask(BLACK).getMask(PtypeFuns<KNIGHT>::indexNum)).any(),
02740 }};
02741 if (has_knight[BLACK] + has_knight[WHITE]
02742 + may_have_knight[BLACK] + may_have_knight[WHITE] == 0)
02743 return result;
02744 CArray<CArray<PieceVector,10>,2> pieces;
02745 {
02746 PieceMask not_target;
02747 not_target.setBit<PAWN>();
02748 not_target.setBit<LANCE>();
02749 not_target.setBit<KNIGHT>();
02750 for (int z=0; z<2; ++z)
02751 {
02752 PieceMask target = state.getOnBoardMask(indexToPlayer(z));
02753 target &= ~not_target;
02754 while (target.any()) {
02755 const Piece p = state.getPieceOf(target.takeOneBit());
02756 pieces[z][p.position().y()].push_back(p);
02757 }
02758 }
02759 }
02760 {
02761 const Player Defense = BLACK;
02762 if (has_knight[alt(Defense)] + may_have_knight[alt(Defense)] > 0)
02763 result += evalOne<Defense>(state, pieces[Defense], has_knight[alt(Defense)],
02764 knight_drop[alt(Defense)]);
02765 }
02766 {
02767 const Player Defense = WHITE;
02768 if (has_knight[alt(Defense)] + may_have_knight[alt(Defense)] > 0)
02769 result += evalOne<Defense>(state, pieces[Defense], has_knight[alt(Defense)],
02770 knight_drop[alt(Defense)]);
02771 }
02772 return result;
02773 }
02774
02775
02776 namespace osl
02777 {
02778 namespace eval
02779 {
02780 namespace ml
02781 {
02782 template void PawnAdvanceAll::
02783 evalWithUpdateBang<BLACK>(const NumEffectState &, Move,MultiInt&);
02784 template void PawnAdvanceAll::
02785 evalWithUpdateBang<WHITE>(const NumEffectState &, Move,MultiInt&);
02786 template MultiInt PtypeY::
02787 evalWithUpdate<BLACK>(const NumEffectState &, Move, MultiInt const&);
02788 template MultiInt PtypeY::
02789 evalWithUpdate<WHITE>(const NumEffectState &, Move, MultiInt const&);
02790 template MultiInt PtypeX::
02791 evalWithUpdate<BLACK>(const NumEffectState &, Move, MultiInt const&);
02792 template MultiInt PtypeX::
02793 evalWithUpdate<WHITE>(const NumEffectState &, Move, MultiInt const&);
02794 template MultiInt PawnPtypeOPtypeO::
02795 evalWithUpdate<BLACK>(const NumEffectState &, Move, const CArray2d<int, 2, 9> &, MultiInt const&);
02796 template MultiInt PawnPtypeOPtypeO::
02797 evalWithUpdate<WHITE>(const NumEffectState &, Move, const CArray2d<int, 2, 9> &, MultiInt const&);
02798
02799 template void osl::eval::ml::NonPawnAttacked::
02800 evalWithUpdateBang<BLACK>(const NumEffectState &state,
02801 Move moved,
02802 const CArray<PieceMask, 2> &effected,
02803 MultiIntPair &result);
02804 template void osl::eval::ml::NonPawnAttacked::
02805 evalWithUpdateBang<WHITE>(const NumEffectState &state,
02806 Move moved,
02807 const CArray<PieceMask, 2> &effected,
02808 MultiIntPair &result);
02809 template void osl::eval::ml::NonPawnAttackedPtype::
02810 evalWithUpdateBang<BLACK>(
02811 const NumEffectState &state,
02812 Move moved,
02813 const CArray<PieceMask, 2> &effected,
02814 CArray<PieceMask, 40> &attacked_mask,
02815 MultiIntPair &result);
02816 template void osl::eval::ml::NonPawnAttackedPtype::
02817 evalWithUpdateBang<WHITE>(
02818 const NumEffectState &state,
02819 Move moved,
02820 const CArray<PieceMask, 2> &effected,
02821 CArray<PieceMask, 40> &attacked_mask,
02822 MultiIntPair &result);
02823 template void osl::eval::ml::PtypeYPawnY::
02824 evalWithUpdateBang<BLACK>(const NumEffectState &state,
02825 Move moved,
02826 const CArray2d<int, 2, 9> &pawns,
02827 MultiInt& last_value);
02828 template void osl::eval::ml::PtypeYPawnY::
02829 evalWithUpdateBang<WHITE>(const NumEffectState &state,
02830 Move moved,
02831 const CArray2d<int, 2, 9> &pawns,
02832 MultiInt& last_value);
02833 template void PtypeCount::
02834 evalWithUpdateBang<BLACK>(const NumEffectState &state,Move last_move,
02835 CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
02836 CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
02837 MultiInt &last_value_and_out,
02838 unsigned int &ptypeo_mask);
02839 template void PtypeCount::
02840 evalWithUpdateBang<WHITE>(const NumEffectState &state,Move last_move,
02841 CArray2d<int, 2, PTYPE_SIZE> &ptype_count,
02842 CArray2d<int, 2, PTYPE_SIZE> &ptype_board_count,
02843 MultiInt &last_value_and_out,
02844 unsigned int &ptypeo_mask);
02845 }
02846 }
02847 }
02848
02849
02850
02851