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