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