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