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