minorPiece.cc
Go to the documentation of this file.
00001 #include "osl/eval/ml/minorPiece.h"
00002 #include "osl/effect_util/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::misc::CArray<osl::MultiInt, 9>
00016 osl::eval::ml::PawnDropBoth::attack_table;
00017 osl::misc::CArray<osl::MultiInt, 9>
00018 osl::eval::ml::PawnDropBoth::defense_table;
00019 osl::misc::CArray<osl::MultiInt, 81>
00020 osl::eval::ml::PawnDropBoth::attack_y_table;
00021 osl::misc::CArray<osl::MultiInt, 81>
00022 osl::eval::ml::PawnDropBoth::defense_y_table;
00023 osl::misc::CArray<osl::MultiInt, 90>
00024 osl::eval::ml::PawnDropBoth::x_table;
00025 osl::misc::CArray<osl::MultiInt, 18>
00026 osl::eval::ml::PawnDropBoth::stand_table;
00027 osl::misc::CArray<osl::MultiInt, 90>
00028 osl::eval::ml::PawnDropBoth::x_stand_table;
00029 osl::misc::CArray<osl::MultiInt, 162>
00030 osl::eval::ml::PawnDropBoth::y_stand_table;
00031 osl::misc::CArray<osl::MultiInt, 10>
00032 osl::eval::ml::PawnDropBoth::drop_non_drop_table;
00033 osl::misc::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::misc::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 osl::state::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 = PlayerTraits<P>::opponent;
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::misc::CArray<osl::MultiInt, 153>
00297 osl::eval::ml::SilverFeatures::head_table;
00298 osl::misc::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 osl::state::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::misc::CArray<osl::MultiInt, 153>
00370 osl::eval::ml::GoldFeatures::knight_table;
00371 osl::misc::CArray<osl::MultiInt, 9>
00372 osl::eval::ml::GoldFeatures::retreat_table;
00373 osl::misc::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 osl::state::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::misc::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 osl::state::NumEffectState &state,
00458                                   const osl::Piece knight)
00459 {
00460   // knight が敵陣一段目にいないと仮定
00461   // もしいる場合はSquare(1,1)のUURが駒台に衝突
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::misc::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::misc::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::misc::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::misc::CArray<MultiInt, 1024> osl::eval::ml::PawnPtypeOPtypeO::table;
00669 osl::misc::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::misc::CArray<MultiInt, 9> osl::eval::ml::PromotedMinorPieces::table;
00961 osl::misc::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<PlayerTraits<P>::opponent>();
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::misc::CArray<MultiInt, 64> osl::eval::ml::NonPawnAttacked::table;
01100 osl::misc::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::misc::CArray<MultiInt, 9> osl::eval::ml::KnightHead::table;
01363 osl::misc::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::misc::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::misc::CArray<MultiInt, 160>
01692 osl::eval::ml::PtypeCount::table;
01693 osl::misc::CArray<MultiInt, 2240>
01694 osl::eval::ml::PtypeCount::xy_table;
01695 osl::misc::CArray<MultiInt, 2240>
01696 osl::eval::ml::PtypeCount::xy_attack_table;
01697 osl::misc::CArray<MultiInt, 2240>
01698 osl::eval::ml::PtypeCount::xy_table_diff;
01699 osl::misc::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=PlayerTraits<P>::index;
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=PlayerTraits<P>::opponent;
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::misc::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::misc::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     // only skip pawn, not ppawns
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::misc::CArray<osl::MultiInt, 1215>
02202 osl::eval::ml::GoldAndSilverNearKing::table;
02203 osl::misc::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.size2(); ++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::misc::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(playerToMul(owner), 0);
02326     if (p.ptype() == GOLD)
02327       return std::make_pair(playerToMul(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(playerToMul(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;          // by turn
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)      // owner is black
02393       {
02394         result[BLACK] += table[match.second*2+1];
02395         result[WHITE] += value_attack;
02396       }
02397       else if (match.first < 0) // owner is white
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) { // negative value is better for attacker
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) { // negative value is better for attacker
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 - playerToMul(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]*playerToMul(P);
03018     if (count[p] > 1)
03019       ret += table[p-8]*(playerToMul(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   // todo changedEffects
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 // ;;; Local Variables:
03122 // ;;; mode:c++
03123 // ;;; c-basic-offset:2
03124 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines