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