kingTable.cc
Go to the documentation of this file.
00001 #include "osl/eval/ml/kingTable.h"
00002 #include "osl/misc/fixedCapacityVector.h"
00003 using osl::MultiInt;
00004 
00005 osl::misc::CArray2d<MultiInt, osl::PTYPE_SIZE, 17 * 9> osl::eval::ml::KingPieceRelative::attack_table;
00006 osl::misc::CArray2d<MultiInt, osl::PTYPE_SIZE, 17 * 9> osl::eval::ml::KingPieceRelative::defense_table;
00007 
00008 void osl::eval::ml::
00009 KingPieceRelative::setUp(const Weights &weights, int stage)
00010 {
00011   for (int i = PTYPE_PIECE_MIN; i <= PTYPE_MAX; ++i)
00012   {
00013     for (int y = 0; y <= 16; ++y)
00014     {
00015       for (int x = 0; x <= 8; ++x)
00016       {
00017         const int distance = x * 17 + y;
00018         attack_table[i][distance][stage] =
00019           weights.value((i - PTYPE_PIECE_MIN) * 17 * 9 + distance);
00020         defense_table[i][distance][stage] =
00021           weights.value((i - PTYPE_PIECE_MIN) * 17 * 9 + distance + TABLE_DIM);
00022       }
00023     }
00024   }
00025 }
00026 
00027 MultiInt osl::eval::ml::
00028 KingPieceRelative::eval(const NumEffectState &state)
00029 {
00030   MultiInt value;
00031   const Square b_king = state.kingSquare(BLACK);
00032   const Square w_king = state.kingSquare(WHITE);
00033   for (int i = 0; i < osl::Piece::SIZE; ++i)
00034   {
00035     const osl::Piece piece = state.pieceOf(i);
00036     if (!piece.isOnBoard())
00037       continue;
00038     const Ptype ptype = piece.ptype();
00039     const Square position = piece.square();
00040     if (piece.owner() == BLACK)
00041     {
00042       const int attack_index = index(state, BLACK,position, w_king);
00043       const int defense_index = index(state, BLACK,position, b_king);
00044       value += attack_table[ptype][attack_index];
00045       value += defense_table[ptype][defense_index];
00046     }
00047     else
00048     {
00049       const int attack_index = index(state, WHITE,position, b_king);
00050       const int defense_index = index(state, WHITE,position, w_king);
00051       value -= attack_table[ptype][attack_index];
00052       value -= defense_table[ptype][defense_index];
00053     }
00054   }
00055   return value;
00056 }
00057 
00058 template<osl::Player P>
00059 MultiInt osl::eval::ml::
00060 KingPieceRelative::evalWithUpdate(const NumEffectState &state,
00061                                   Move moved, MultiInt const& last_value)
00062 {
00063   if (moved.isPass())
00064     return last_value;
00065 
00066   if (moved.ptype() == osl::KING)
00067   {
00068     return eval(state);
00069   }
00070 
00071   MultiInt value(last_value);
00072   if (!moved.isDrop())
00073   {
00074     const PtypeO ptypeO = moved.oldPtypeO();
00075     const int attack_index = index(state, ptypeO, moved.from(), false);
00076     const int defense_index = index(state,ptypeO, moved.from(), true);
00077     if (P == BLACK)
00078     {
00079       value -= attack_table[moved.oldPtype()][attack_index];
00080       value -= defense_table[moved.oldPtype()][defense_index];
00081     }
00082     else
00083     {
00084       value += attack_table[moved.oldPtype()][attack_index];
00085       value += defense_table[moved.oldPtype()][defense_index];
00086     }
00087   }
00088   {
00089     const int attack_index = index(state, moved.ptypeO(), moved.to(), false);
00090     const int defense_index = index(state, moved.ptypeO(), moved.to(), true);
00091     if (P == BLACK)
00092     {
00093       value += attack_table[moved.ptype()][attack_index];
00094       value += defense_table[moved.ptype()][defense_index];
00095     }
00096     else
00097     {
00098       value -= attack_table[moved.ptype()][attack_index];
00099       value -= defense_table[moved.ptype()][defense_index];
00100     }
00101   }
00102   const Ptype captured = moved.capturePtype();
00103   if (captured != PTYPE_EMPTY)
00104   {
00105     const PtypeO ptypeO = moved.capturePtypeO();
00106     const int attack_index = index(state, ptypeO, moved.to(), false);
00107     const int defense_index = index(state,ptypeO, moved.to(), true);
00108     if (P == BLACK)
00109     {
00110       value += attack_table[captured][attack_index];
00111       value += defense_table[captured][defense_index];
00112     }
00113     else
00114     {
00115       value -= attack_table[captured][attack_index];
00116       value -= defense_table[captured][defense_index];
00117     }
00118   }
00119   return value;
00120 }
00121 
00122 
00123 osl::misc::CArray<MultiInt, osl::eval::ml::KingPieceRelativeNoSupport::ONE_DIM>
00124 osl::eval::ml::KingPieceRelativeNoSupport::table;
00125 
00126 void osl::eval::ml::
00127 KingPieceRelativeNoSupport::setUp(const Weights &weights)
00128 {
00129   for (int i = 0; i < ONE_DIM; ++i)
00130   {
00131     for (int s=0; s<NStages; ++s)
00132       table[i][s] = weights.value(i + ONE_DIM*s);
00133   }
00134 }
00135 
00136 template <int Sign> inline
00137 void osl::eval::ml::
00138 KingPieceRelativeNoSupport::adjust(int attack, int defense, MultiInt& out)
00139 {
00140   if(Sign>0)
00141     out += table[attack] + table[defense];
00142   else
00143     out -= table[attack] + table[defense];
00144 }
00145 
00146 MultiInt osl::eval::ml::
00147 KingPieceRelativeNoSupport::eval(const NumEffectState &state)
00148 {
00149   MultiInt result;
00150   const CArray<Square, 2> kings = {{ 
00151       state.kingSquare(BLACK),
00152       state.kingSquare(WHITE),
00153     }};
00154   PieceMask black = (~state.effectedMask(BLACK)) & state.piecesOnBoard(BLACK);
00155   black.reset(KingTraits<BLACK>::index);
00156   while (black.any())
00157   {
00158     const Piece piece = state.pieceOf(black.takeOneBit());
00159     const int index_attack = index(BLACK, kings[WHITE],
00160                                    piece);
00161     const int index_defense = index(BLACK, kings[BLACK],
00162                                     piece) + ONE_DIM / 2;
00163     adjust<1>(index_attack, index_defense, result);
00164   }
00165   PieceMask white = (~state.effectedMask(WHITE)) & state.piecesOnBoard(WHITE);
00166   white.reset(KingTraits<WHITE>::index);
00167   while (white.any())
00168   {
00169     const Piece piece = state.pieceOf(white.takeOneBit());
00170     const int index_attack = index(WHITE, kings[BLACK],
00171                                    piece);
00172     const int index_defense = index(WHITE, kings[WHITE],
00173                                     piece) + ONE_DIM / 2;
00174     adjust<-1>(index_attack, index_defense, result);
00175   }
00176   return result;
00177 }
00178 
00179 MultiInt osl::eval::ml::
00180 KingPieceRelativeNoSupport::evalWithUpdate(
00181   const NumEffectState &state,
00182   Move moved,
00183   const CArray<PieceMask, 2> &effected_mask,
00184   const MultiInt &last_values)
00185 {
00186   if (moved.ptype() == KING)
00187     return eval(state);
00188 
00189   const CArray<PieceMask, 2> new_mask = {{
00190       state.effectedMask(BLACK),
00191       state.effectedMask(WHITE)
00192     }};
00193   const CArray<Square, 2> kings = {{ 
00194       state.kingSquare<BLACK>(),
00195       state.kingSquare<WHITE>(),
00196     }};
00197 
00198   MultiInt result(last_values);
00199   const Piece p = state.pieceAt(moved.to());
00200   if (!moved.isDrop())
00201   {
00202     if (!effected_mask[p.owner()].test(p.number()))
00203     {
00204       const int index_attack =
00205         index(p.owner(), kings[alt(p.owner())],
00206               moved.oldPtype(), moved.from());
00207       const int index_defense =
00208         index(p.owner(), kings[p.owner()], moved.oldPtype(),
00209               moved.from()) + ONE_DIM / 2;
00210       if (p.owner() == BLACK)
00211         adjust<-1>(index_attack, index_defense, result);
00212       else
00213         adjust<1>(index_attack, index_defense, result);
00214     }
00215   }
00216   const Ptype captured = moved.capturePtype();
00217   if (captured != PTYPE_EMPTY)
00218   {
00219     PieceMask captured_mask =
00220       effected_mask[moved.player()] & (~state.piecesOnBoard(BLACK)) &
00221       (~state.piecesOnBoard(WHITE));
00222     
00223     if (!effected_mask[alt(moved.player())].test(captured_mask.takeOneBit()))
00224     {
00225       const int index_attack =
00226         index(alt(p.owner()), kings[p.owner()],
00227               captured, moved.to());
00228       const int index_defense =
00229         index(alt(p.owner()), kings[alt(p.owner())], captured,
00230               moved.to()) + ONE_DIM / 2;
00231       if (p.owner() == BLACK)
00232         adjust<1>(index_attack, index_defense, result);
00233       else
00234         adjust<-1>(index_attack, index_defense, result);
00235     }
00236   }
00237   if (!new_mask[p.owner()].test(p.number()))
00238   {
00239     const int index_attack =
00240       index(p.owner(), kings[alt(p.owner())],
00241             moved.ptype(), moved.to());
00242     const int index_defense =
00243       index(p.owner(), kings[p.owner()], moved.ptype(),
00244             moved.to()) + ONE_DIM / 2;
00245     if (p.owner() == BLACK)
00246       adjust<1>(index_attack, index_defense, result);
00247     else
00248       adjust<-1>(index_attack, index_defense, result);
00249   }
00250   PieceMask onboard_black = state.piecesOnBoard(BLACK);
00251   onboard_black.reset(KingTraits<BLACK>::index);
00252   // old 0, new, 1
00253   PieceMask black_old = (~effected_mask[0]) & new_mask[0] & onboard_black;
00254   black_old.reset(p.number());
00255   while (black_old.any())
00256   {
00257     const Piece piece = state.pieceOf(black_old.takeOneBit());
00258     const int index_attack =
00259       index(BLACK, kings[WHITE], piece);
00260     const int index_defense =
00261       index(BLACK, kings[BLACK], piece) + ONE_DIM / 2;
00262     adjust<-1>(index_attack, index_defense, result);
00263   }
00264   // old 1, new 0
00265   PieceMask black_new = effected_mask[0] & (~new_mask[0]) & onboard_black;
00266   black_new.reset(p.number());
00267   while (black_new.any())
00268   {
00269     const Piece piece = state.pieceOf(black_new.takeOneBit());
00270     const int index_attack =
00271       index(BLACK, kings[WHITE], piece);
00272     const int index_defense =
00273       index(BLACK, kings[BLACK], piece) + ONE_DIM / 2;
00274     adjust<1>(index_attack, index_defense, result);
00275   }
00276 
00277   // old 0, new, 1
00278   PieceMask onboard_white = state.piecesOnBoard(WHITE);
00279   onboard_white.reset(KingTraits<WHITE>::index);
00280   PieceMask white_old = (~effected_mask[1]) & new_mask[1] & onboard_white;
00281   white_old.reset(p.number());
00282   while (white_old.any())
00283   {
00284     const Piece piece = state.pieceOf(white_old.takeOneBit());
00285     const int index_attack =
00286       index(WHITE, kings[BLACK], piece);
00287     const int index_defense =
00288       index(WHITE, kings[WHITE], piece) + ONE_DIM / 2;
00289     adjust<1>(index_attack, index_defense, result);
00290   }
00291   // old 1, new 0
00292   PieceMask white_new = effected_mask[1] & (~new_mask[1]) & onboard_white;
00293   white_new.reset(p.number());
00294   while (white_new.any())
00295   {
00296     const Piece piece = state.pieceOf(white_new.takeOneBit());
00297     const int index_attack =
00298       index(WHITE, kings[BLACK], piece);
00299     const int index_defense =
00300       index(WHITE, kings[WHITE], piece) + ONE_DIM / 2;
00301     adjust<-1>(index_attack, index_defense, result);
00302   }
00303 
00304   return result;
00305 }
00306 
00307 
00308 osl::misc::CArray<MultiInt, 2592> osl::eval::ml::PtypeYY::table;
00309 
00310 void osl::eval::ml::PtypeYY::setUp(const Weights &weights)
00311 {
00312   for (int i = 0; i < ONE_DIM; ++i)
00313   {
00314     for (int s=0; s<NStages; ++s)
00315       table[i][s] = weights.value(i + ONE_DIM*s);
00316   }
00317 }
00318 
00319 template <int Sign>
00320 inline
00321 void osl::eval::ml::
00322 PtypeYY::adjust(int black, int white, MultiInt &out)
00323 {
00324   if(Sign>0)
00325     out += table[black] - table[white];
00326   else
00327     out -= table[black] - table[white];
00328 }
00329 
00330 MultiInt osl::eval::ml::
00331 PtypeYY::eval(const NumEffectState &state)
00332 {
00333   MultiInt result;
00334   const CArray<Square,2> kings = {{ 
00335       state.kingSquare(BLACK),
00336       state.kingSquare(WHITE),
00337     }};
00338   for (int i = 0; i < Piece::SIZE; ++i)
00339   {
00340     const Piece p = state.pieceOf(i);
00341     if (!p.isOnBoard())
00342       continue;
00343     const int black_index = index<BLACK>(p, kings[BLACK]);
00344     const int white_index = index<WHITE>(p, kings[WHITE]);
00345     adjust<1>(black_index, white_index, result);
00346   }
00347 
00348   return result;
00349 }
00350 
00351 MultiInt osl::eval::ml::PtypeYY::evalWithUpdate(
00352   const NumEffectState& state,
00353   Move moved,
00354   const MultiInt &last_values)
00355 {
00356   if (moved.ptype() == KING && moved.to().y() != moved.from().y())
00357   {
00358     return eval(state);
00359   }
00360   MultiInt result(last_values);
00361   if (!moved.isDrop())
00362   {
00363     const int index_black = index<BLACK>(moved.oldPtypeO(), moved.from(),
00364                                          state.kingSquare<BLACK>());
00365     const int index_white = index<WHITE>(moved.oldPtypeO(), moved.from(),
00366                                          state.kingSquare<WHITE>());
00367     adjust<-1>(index_black, index_white, result);
00368   }
00369   Ptype captured = moved.capturePtype();
00370   if (captured != PTYPE_EMPTY)
00371   {
00372     const PtypeO ptypeO = newPtypeO(alt(moved.player()), captured);
00373     const int index_black = index<BLACK>(ptypeO, moved.to(),
00374                                          state.kingSquare<BLACK>());
00375     const int index_white = index<WHITE>(ptypeO, moved.to(),
00376                                          state.kingSquare<WHITE>());
00377     adjust<-1>(index_black, index_white, result);
00378   }
00379 
00380   {
00381     const int index_black = index<BLACK>(moved.ptypeO(), moved.to(),
00382                                          state.kingSquare<BLACK>());
00383     const int index_white = index<WHITE>(moved.ptypeO(), moved.to(),
00384                                          state.kingSquare<WHITE>());
00385     adjust<1>(index_black, index_white, result);
00386   }
00387   return result;
00388 }
00389 
00390 
00391 osl::misc::CArray<int, osl::eval::ml::King25Effect::DIM>
00392 osl::eval::ml::King25Effect::table;
00393 
00394 void osl::eval::ml::
00395 King25Effect::setUp(const Weights &weights)
00396 {
00397   table.fill(0);
00398   for (size_t i = 0; i < weights.dimension(); ++i)
00399   {
00400     table[i] = weights.value(i);
00401   }
00402 }
00403 
00404 void osl::eval::ml::King25Effect::countEffectAndPieces(
00405   const osl::state::NumEffectState &state,
00406   const osl::Player attack,
00407   int &effect,
00408   int &piece)
00409 {
00410   const Square king = state.kingSquare(alt(attack));
00411   const int min_x = std::max(1, king.x() - 2);
00412   const int max_x = std::min(9, king.x() + 2);
00413   const int min_y = std::max(1, king.y() - 2);
00414   const int max_y = std::min(9, king.y() + 2);
00415 
00416   PieceMask mask;
00417   int count = 0;
00418   for (int y = min_y; y <= max_y; ++y)
00419   {
00420     for (int x = min_x; x <= max_x; ++x)
00421     {
00422       const Square target(x, y);
00423       count += state.countEffect(attack, target);
00424       mask |= state.effectSetAt(target);
00425     }
00426   }
00427   effect = std::min(255, count);
00428   mask = mask & state.piecesOnBoard(attack);
00429   piece = std::min(16,  mask.countBit());
00430 }
00431 
00432 int osl::eval::ml::King25Effect::index(int effect, int piece_count)
00433 {
00434   return effect + 128 * piece_count;
00435 }
00436 
00437 int osl::eval::ml::King25Effect::eval(
00438   const osl::state::NumEffectState &state)
00439 {
00440   int black_effect, black_piece, white_effect, white_piece;
00441   countEffectAndPieces(state, osl::BLACK, black_effect, black_piece);
00442   countEffectAndPieces(state, osl::WHITE, white_effect, white_piece);
00443   return table[index(black_effect, black_piece)] - table[index(white_effect, white_piece)];
00444 }
00445 
00446 
00447 osl::misc::CArray<MultiInt, osl::eval::ml::King25Effect2::ONE_DIM>
00448 osl::eval::ml::King25Effect2::table;
00449 osl::misc::CArray<MultiInt, osl::eval::ml::King25EffectY2::ONE_DIM>
00450 osl::eval::ml::King25EffectY2::table;
00451 
00452 void osl::eval::ml::King25Effect2::setUp(const Weights &weights)
00453 {
00454   for (int i = 0; i < ONE_DIM; ++i)
00455   {
00456     for (int s=0; s<NStages; ++s)
00457       table[i][s] = weights.value(i + ONE_DIM*s);
00458   }
00459 }
00460 
00461 void osl::eval::ml::King25EffectY2::setUp(const Weights &weights)
00462 {
00463   for (int i = 0; i < ONE_DIM; ++i)
00464   {
00465     for (int s=0; s<NStages; ++s)
00466       table[i][s] = weights.value(i + ONE_DIM*s);
00467   }
00468 }
00469 
00470 
00471 osl::misc::CArray<MultiInt, osl::eval::ml::King25EffectSupported::ONE_DIM>
00472 osl::eval::ml::King25EffectSupported::table;
00473 osl::misc::CArray<MultiInt, osl::eval::ml::King25EffectSupportedY::ONE_DIM>
00474 osl::eval::ml::King25EffectSupportedY::table;
00475 
00476 void osl::eval::ml::King25EffectSupported::setUp(const Weights &weights)
00477 {
00478   for (int i = 0; i < ONE_DIM; ++i)
00479   {
00480     for (int s=0; s<NStages; ++s)
00481       table[i][s] = weights.value(i + ONE_DIM*s);
00482   }
00483 }
00484 
00485 void osl::eval::ml::King25EffectSupportedY::setUp(const Weights &weights)
00486 {
00487   for (int i = 0; i < ONE_DIM; ++i)
00488   {
00489     for (int s=0; s<NStages; ++s)
00490       table[i][s] = weights.value(i + ONE_DIM*s);
00491   }
00492 }
00493 
00494 
00495 osl::misc::CArray<int, osl::eval::ml::King25EffectBoth::DIM/2>
00496 osl::eval::ml::King25EffectBoth::attack_table;
00497 osl::misc::CArray<int, osl::eval::ml::King25EffectBoth::DIM/2>
00498 osl::eval::ml::King25EffectBoth::defense_table;
00499 
00500 void osl::eval::ml::
00501 King25EffectBoth::setUp(const Weights &weights)
00502 {
00503   attack_table.fill(0);
00504   defense_table.fill(0);
00505   for (size_t i = 0; i < DIM/2; ++i)
00506   {
00507     attack_table[i] = weights.value(i);
00508     defense_table[i] = weights.value(i+DIM/2);
00509   }
00510 }
00511 
00512 template <osl::Player Attack>
00513 void
00514  osl::eval::ml::King25EffectBoth::countEffectAndPiecesBoth(
00515   const osl::state::NumEffectState &state,
00516   PieceMask& mask,
00517   PieceMask& supported_mask,
00518   int &attack_effect,
00519   int &attack_piece,
00520   int &defense_effect,
00521   int &defense_piece,
00522   int &attack_piece_supported,
00523   CArray<int, 5> &verticals,
00524   CArray<int, 5> &king_verticals)
00525 {
00526   king_verticals.fill(0);
00527   const Player Defense = PlayerTraits<Attack>::opponent;
00528   const Square king = state.kingSquare(Defense);
00529   const int min_x = std::max(1, king.x() - 2);
00530   const int max_x = std::min(9, king.x() + 2);
00531   const int min_y = std::max(1, king.y() - 2);
00532   const int max_y = std::min(9, king.y() + 2);
00533   int mask_all=(1<<5)-1;
00534   verticals.fill(mask_all);
00535   const int y_mask_base=(1 << (Defense == BLACK ? (min_y-king.y()) + 2 : -(max_y-king.y()) + 2));
00536   if(Defense==BLACK)
00537     mask_all ^= ((1<<(max_y-king.y()+3))-y_mask_base);
00538   else
00539     mask_all ^= ((1<<(king.y()-min_y+3))-y_mask_base);
00540   mask.resetAll();
00541   int attack_count = 0;
00542   int defense_count = 0;
00543   for (int x = min_x; x <= max_x; ++x)
00544   {
00545     int vertical_x=mask_all;
00546     int king_vertical_x = 0;
00547     if(Defense==BLACK){
00548       int y_mask=y_mask_base;
00549       for (int y = min_y; y <= max_y; ++y, y_mask+=y_mask)
00550       {
00551         const Square target(x, y);
00552         const int count = state.countEffect(Attack, target);
00553         defense_count += state.countEffect(alt(Attack), target);
00554         mask |= state.effectSetAt(target);
00555         if(count>0){
00556           attack_count += count;
00557           vertical_x |= y_mask;
00558         }
00559         const Piece piece = state.pieceAt(target);
00560         if (count == 0 &&
00561             (piece.isEmpty() || piece.owner() == Attack))
00562         {
00563           king_vertical_x |= y_mask;
00564         }
00565       }
00566     }
00567     else{
00568       int y_mask=y_mask_base;
00569       for (int y = max_y; y >= min_y; --y, y_mask+=y_mask)
00570       {
00571         const Square target(x, y);
00572         const int count = state.countEffect(Attack, target);
00573         defense_count += state.countEffect(alt(Attack), target);
00574         mask |= state.effectSetAt(target);
00575         if(count>0){
00576           attack_count += count;
00577           vertical_x |= y_mask;
00578         }
00579         const Piece piece = state.pieceAt(target);
00580         if (count == 0 &&
00581             (piece.isEmpty() || piece.owner() == Attack))
00582         {
00583           king_vertical_x |= y_mask;
00584         }
00585       }
00586     }
00587     const int x_diff = king.x() - x;
00588     verticals[(Defense == BLACK ? 2 - x_diff : 2 + x_diff)] = vertical_x;
00589     king_verticals[(Defense == BLACK ? 2 - x_diff : 2 + x_diff)] =
00590       king_vertical_x;
00591   }
00592   attack_effect = std::min(127, attack_count);
00593   defense_effect = std::min(127, defense_count);
00594   PieceMask attack_mask = mask & state.piecesOnBoard(Attack);
00595   attack_piece = std::min(16,  attack_mask.countBit());
00596   PieceMask defense_mask = mask & state.piecesOnBoard(alt(Attack));
00597   defense_piece = std::min(16,  defense_mask.countBit());
00598   supported_mask = attack_mask & state.effectedMask(Attack);
00599   attack_piece_supported = std::min(16, supported_mask.countBit());
00600 }
00601 
00602 
00603 osl::misc::CArray<int, osl::eval::ml::King25EffectY::DIM/2>
00604 osl::eval::ml::King25EffectY::attack_table;
00605 osl::misc::CArray<int, osl::eval::ml::King25EffectY::DIM/2>
00606 osl::eval::ml::King25EffectY::defense_table;
00607 
00608 void osl::eval::ml::
00609 King25EffectY::setUp(const Weights &weights)
00610 {
00611   attack_table.fill(0);
00612   defense_table.fill(0);
00613   for (size_t i = 0; i < DIM/2; ++i)
00614   {
00615     attack_table[i] = weights.value(i);
00616     defense_table[i] = weights.value(i+DIM/2);
00617   }
00618 }
00619 
00620 
00621 
00622 void osl::eval::ml::
00623 King25EmptySquareNoEffect::setUpBase(const Weights &weights, CArray<int, 15>& table)
00624 {
00625   table.fill(0);
00626   for (size_t i = 0; i < weights.dimension(); ++i)
00627   {
00628     table[i] = weights.value(i);
00629   }
00630 }
00631 
00632 template <osl::Player defense>
00633 int osl::eval::ml::
00634 King25EmptySquareNoEffect::evalOne(const NumEffectState &state, const CArray<int, 15>& table)
00635 {
00636   int result = 0;
00637   const Piece king_piece = state.kingPiece<defense>();
00638   const Square king = king_piece.square();
00639   const int min_x = std::max(1, king.x() - 2);
00640   const int max_x = std::min(9, king.x() + 2);
00641   const int min_y = std::max(1, king.y() - 2);
00642   const int max_y = std::min(9, king.y() + 2);
00643 
00644   PieceMask pieces=state.piecesOnBoard(defense);
00645   pieces.reset(KingTraits<defense>::index);
00646 
00647   for (int x = min_x; x <= max_x; ++x)
00648   {
00649     for (int y = min_y; y <= max_y; ++y)
00650     {
00651       Square target(x, y);
00652       if (state.pieceAt(target).isEmpty()
00653           && ! /*state.hasEffectNotBy(defense, king_piece, target)*/
00654           (pieces & state.effectSetAt(target)).any())
00655       {
00656         if (defense == BLACK)
00657           result += table[index(x - king.x(), y - king.y())];
00658         else
00659           result -= table[index(king.x() - x, king.y() - y)];
00660       }
00661     }
00662   }
00663   return result;
00664 }
00665 
00666 template <osl::Player defense>
00667 std::pair<int,int> osl::eval::ml::
00668 King25EmptySquareNoEffect::evalOne(const NumEffectState &state, 
00669                                      const CArray<int, 15>& opening, const CArray<int, 15>& ending)
00670 {
00671   int result_o = 0, result_e = 0;
00672   const Piece king_piece = state.kingPiece<defense>();
00673   const Square king = king_piece.square();
00674   const int min_x = std::max(1, king.x() - 2);
00675   const int max_x = std::min(9, king.x() + 2);
00676   const int min_y = std::max(1, king.y() - 2);
00677   const int max_y = std::min(9, king.y() + 2);
00678 
00679   PieceMask pieces=state.piecesOnBoard(defense);
00680   pieces.reset(KingTraits<defense>::index);
00681 
00682   for (int x = min_x; x <= max_x; ++x)
00683   {
00684     for (int y = min_y; y <= max_y; ++y)
00685     {
00686       Square target(x, y);
00687       if (state.pieceAt(target).isEmpty()
00688           && ! /*state.hasEffectNotBy(defense, king_piece, target)*/
00689           (pieces & state.effectSetAt(target)).any())
00690       {
00691         if (defense == BLACK) 
00692         {
00693           result_o += opening[index(x - king.x(), y - king.y())];
00694           result_e += ending[index(x - king.x(), y - king.y())];
00695         }
00696         else
00697         {
00698           result_o -= opening[index(king.x() - x, king.y() - y)];
00699           result_e -= ending[index(king.x() - x, king.y() - y)];
00700         }
00701       }
00702     }
00703   }
00704   return std::make_pair(result_o, result_e);
00705 }
00706 
00707 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
00708 King25EmptySquareNoEffect::eval(const NumEffectState &state, 
00709                                   const CArray<int, 15>& opening, const CArray<int, 15>& ending)
00710 {
00711   std::pair<int,int> b = evalOne<BLACK>(state, opening, ending);
00712   std::pair<int,int> w = evalOne<WHITE>(state, opening, ending);
00713   CArray<int,2> result_o = {{ b.first, w.first }};
00714   CArray<int,2> result_e = {{ b.second, w.second }};
00715   return std::make_pair(result_o, result_e);
00716 }
00717 
00718 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
00719 King25EmptySquareNoEffect::evalWithUpdate(const NumEffectState &state, Move last_move,
00720                                             const CArray<int, 15>& opening, const CArray<int, 15>& ending,
00721                                             const CArray<int, 2>& last_opening_value, 
00722                                             const CArray<int, 2>& last_ending_value)
00723 {
00724   BoardMask mb = state.changedEffects(BLACK), mw = state.changedEffects(WHITE);
00725   mb.set(Square(last_move.to())); mb.set(Square(last_move.from()));
00726   mw.set(Square(last_move.to())); mw.set(Square(last_move.from()));
00727   const Square kb = state.kingSquare<BLACK>(), kw = state.kingSquare<WHITE>();
00728   const bool update_black = mb.anyInRange(Board_Mask_Table5x5.mask(kb));
00729   const bool update_white = mw.anyInRange(Board_Mask_Table5x5.mask(kw));
00730   std::pair<int,int> b = update_black 
00731     ? evalOne<BLACK>(state, opening, ending)
00732     : std::make_pair(last_opening_value[0], last_ending_value[0]);
00733   std::pair<int,int> w = update_white
00734     ? evalOne<WHITE>(state, opening, ending)
00735     : std::make_pair(last_opening_value[1], last_ending_value[1]);
00736   CArray<int,2> result_o = {{ b.first, w.first }};
00737   CArray<int,2> result_e = {{ b.second, w.second }};
00738   return std::make_pair(result_o, result_e);
00739 }
00740 
00741 
00742 osl::misc::CArray<int, 15>
00743 osl::eval::ml::King25EmptySquareNoEffectOpening::table;
00744 osl::misc::CArray<int, 15>
00745 osl::eval::ml::King25EmptySquareNoEffectEnding::table;
00746 
00747 const osl::CArray<int,2> osl::eval::ml::
00748 King25EmptySquareNoEffectOpening::eval(const NumEffectState &state)
00749 {
00750   CArray<int, 2> result = {{ evalOne<BLACK>(state, table), evalOne<WHITE>(state, table) }};
00751   return result;
00752 }
00753 
00754 const osl::CArray<int,2> osl::eval::ml::
00755 King25EmptySquareNoEffectEnding::eval(const NumEffectState &state)
00756 {
00757   CArray<int, 2> result = {{ evalOne<BLACK>(state, table), evalOne<WHITE>(state, table) }};
00758   return result;
00759 }
00760 
00761 
00762 
00763 template <int Stage>
00764 osl::misc::CArray<int, 5 * 3 * 8 * 3>
00765 osl::eval::ml::King25EffectEach<Stage>::table;
00766 
00767 template <int Stage>
00768 void osl::eval::ml::
00769 King25EffectEach<Stage>::setUp(const Weights &weights)
00770 {
00771   for (size_t i = 0; i < weights.dimension(); ++i)
00772   {
00773     table[i] = weights.value(i);
00774   }
00775 }
00776 
00777 template <int Stage>
00778 template <osl::Player Defense>
00779 osl::eval::ml::EffectState
00780 osl::eval::ml::King25EffectEach<Stage>::effectState(
00781   const NumEffectState &state,
00782   Square target)
00783 {
00784   if (!state.hasEffectAt(alt(Defense), target))
00785   {
00786     return static_cast<EffectState>(std::min(2, state.countEffect(Defense, target)));
00787   }
00788   const int diff = state.countEffect(Defense, target) -
00789     state.countEffect(alt(Defense), target);
00790   return static_cast<EffectState>(std::max(-2, std::min(2, diff)) + ATTACK_DIFF_0);
00791 }
00792 
00793 template <int Stage>
00794 template <osl::Player Defense>
00795 int osl::eval::ml::King25EffectEach<Stage>::index(
00796   const NumEffectState &state, Square king,
00797   Square target)
00798 {
00799   const Piece piece = state.pieceAt(target);
00800   // [0, 2]
00801   const int rel_x = std::abs(king.x() - target.x());
00802   // [-2, +2]
00803   const int rel_y = (target.y() - king.y()) * (Defense == BLACK ? 1 : -1);
00804   int piece_owner;
00805   if (piece.isEmpty())
00806     piece_owner = 0;
00807   else if (piece.owner() == Defense)
00808     piece_owner = 1;
00809   else
00810     piece_owner = 2;
00811 
00812   int val = rel_y + 2 + rel_x * 5 +
00813     effectState<Defense>(state, target) * 5 * 3 +
00814     piece_owner * 5 * 3 * 8;
00815   return val;
00816 }
00817 
00818 template <int Stage>
00819 template <osl::Player Defense>
00820 int osl::eval::ml::King25EffectEach<Stage>::evalOne(
00821   const NumEffectState &state)
00822 {
00823   int result = 0;
00824   const Square king = state.kingSquare<Defense>();
00825   const int min_x = std::max(1, king.x() - 2);
00826   const int max_x = std::min(9, king.x() + 2);
00827   const int min_y = std::max(1, king.y() - 2);
00828   const int max_y = std::min(9, king.y() + 2);
00829   for (int x = min_x; x <= max_x; ++x)
00830   {
00831     for (int y = min_y; y <= max_y; ++y)
00832     {
00833       Square target(x, y);
00834       result += table[index<Defense>(state, king, target)];
00835     }
00836   }
00837   if (Defense == BLACK)
00838     return result;
00839   else
00840     return -result;
00841 }
00842 
00843 template <int Stage>
00844 int osl::eval::ml::
00845 King25EffectEach<Stage>::eval(const NumEffectState &state)
00846 {
00847   return evalOne<BLACK>(state) + evalOne<WHITE>(state);
00848 }
00849 
00850 osl::misc::CArray<MultiInt, 5 * 3 * 8 * 3>
00851 osl::eval::ml::King25EffectEachBoth::table;
00852 osl::misc::CArray<MultiInt, 3000>
00853 osl::eval::ml::King25EffectEachBoth::x_table;
00854 osl::misc::CArray<MultiInt, 3240>
00855 osl::eval::ml::King25EffectEachBoth::y_table;
00856 osl::misc::CArray<MultiInt, 27000>
00857 osl::eval::ml::King25EffectEachBoth::xy_table;
00858 osl::misc::CArray<int, 256>
00859 osl::eval::ml::King25EffectEachBoth::effect_state_table;
00860 
00861 void osl::eval::ml::
00862 King25EffectEachBothOpening::setUp(const Weights &weights)
00863 {
00864   for (size_t i = 0; i < weights.dimension(); ++i)
00865   {
00866     King25EffectEachBoth::table[i][0] = weights.value(i);
00867   }
00868 }
00869 
00870 void osl::eval::ml::
00871 King25EffectEachBothMidgame::setUp(const Weights &weights)
00872 {
00873   for (size_t i = 0; i < weights.dimension(); ++i)
00874   {
00875     King25EffectEachBoth::table[i][1] = weights.value(i);
00876   }
00877 }
00878 
00879 void osl::eval::ml::
00880 King25EffectEachBothMidgame2::setUp(const Weights &weights)
00881 {
00882   for (size_t i = 0; i < weights.dimension(); ++i)
00883   {
00884     King25EffectEachBoth::table[i][2] = weights.value(i);
00885   }
00886 }
00887 
00888 void osl::eval::ml::
00889 King25EffectEachBothEnding::setUp(const Weights &weights)
00890 {
00891   for (size_t i = 0; i < weights.dimension(); ++i)
00892   {
00893     King25EffectEachBoth::table[i][EndgameIndex] = weights.value(i);
00894   }
00895 }
00896 void osl::eval::ml::
00897 King25EffectEachXY::setUp(const Weights &weights)
00898 {
00899   for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
00900     for(int x_diff_2=0;x_diff_2<5;x_diff_2++)
00901       for(int es=0;es<8;es++)
00902         for(int po=0;po<3;po++)
00903           for(int king_x_1=0;king_x_1<5;king_x_1++){
00904             int oldIndex=(rel_y_2+x_diff_2*5+es*5*5+po*5*5*8)*5+king_x_1;
00905             int newIndex=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*king_x_1)));
00906             for (int s=0; s<NStages; ++s)
00907               King25EffectEachBoth::x_table[newIndex][s] = weights.value(oldIndex + X_DIM*s);
00908           }
00909   for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
00910     for(int rel_x=0;rel_x<3;rel_x++)
00911       for(int es=0;es<8;es++)
00912         for(int po=0;po<3;po++)
00913           for(int king_y_1=0;king_y_1<9;king_y_1++){
00914             int oldIndex=(rel_y_2+rel_x*5+es*5*3+po*5*3*8)*9+king_y_1;
00915             int newIndex=po+3*(es+8*(rel_y_2+5*(rel_x+3*king_y_1)));
00916             for (int s=0; s<NStages; ++s)
00917               King25EffectEachBoth::y_table[newIndex][s] = weights.value(oldIndex+ X_DIM * EvalStages + Y_DIM*s)+King25EffectEachBoth::table[oldIndex/9][s];
00918           }
00919   for(int d_effect=0;d_effect<16;d_effect++){
00920     for(int a_effect=0;a_effect<16;a_effect++){
00921       if(a_effect==0){
00922         King25EffectEachBoth::effect_state_table[a_effect*16+d_effect]=3*(std::min(2, d_effect));
00923       }
00924       else{
00925         int diff=d_effect-a_effect;
00926         King25EffectEachBoth::effect_state_table[a_effect*16+d_effect]=
00927           3*(std::max(-2, std::min(2, diff)) + ATTACK_DIFF_0);
00928       }
00929     }
00930   }
00931 }
00932 
00933 void osl::eval::ml::
00934 King25EffectEachKXY::setUp(const Weights &weights)
00935 {
00936   for(int rel_y_2=0;rel_y_2<5;rel_y_2++)
00937     for(int x_diff_2=0;x_diff_2<5;x_diff_2++){
00938       int rel_x=std::abs(x_diff_2-2);
00939       for(int es=0;es<8;es++)
00940         for(int po=0;po<3;po++)
00941           for(int king_x_1=0;king_x_1<5;king_x_1++)
00942             for (int king_y_1=0;king_y_1<9;king_y_1++) {
00943               int oldIndex=((rel_y_2+x_diff_2*5+es*5*5+po*5*5*8)*9+king_y_1)*5 + king_x_1;
00944               int newIndexX=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*king_x_1)));
00945               int newIndexY=po+3*(es+8*(rel_y_2+5*(rel_x+3*king_y_1)));
00946               int newIndex=po+3*(es+8*(rel_y_2+5*(x_diff_2+5*(king_x_1+5*king_y_1))));
00947               for (int s=0; s<NStages; ++s)
00948                 King25EffectEachBoth::xy_table[newIndex][s] = weights.value(oldIndex + ONE_DIM*s)+King25EffectEachBoth::x_table[newIndexX][s]+King25EffectEachBoth::y_table[newIndexY][s];
00949           }
00950     }
00951 }
00952 
00953 template <osl::Player Defense>
00954 int
00955 osl::eval::ml::King25EffectEachBoth::effectStateIndex3(
00956   const NumEffectState &state, Square target)
00957 {
00958   NumBitmapEffect effect=state.effectSetAt(target);
00959   const int d_effect=effect.countEffect(Defense);
00960   const int a_effect=effect.countEffect(PlayerTraits<Defense>::opponent);
00961   return effect_state_table[a_effect*16+d_effect];
00962 }
00963 
00964 template <osl::Player Defense>
00965 void osl::eval::ml::King25EffectEachBoth::index(
00966   const NumEffectState &state, 
00967   Square target, int &index_xy,
00968   int rel_y, int king_x, int king_y, int x_diff)
00969 {
00970   const Piece piece = state.pieceAt(target);
00971   // piece_owner: 0 - empty, 1 - defense, 2 - attack
00972   int piece_owner;
00973   PtypeO ptypeO=piece.ptypeO();
00974   if(Defense==BLACK){
00975 #ifdef __INTEL_COMPILER
00976     piece_owner = (unsigned int)((int)(ptypeO)>>30);
00977     piece_owner &= 0x2;
00978     piece_owner |= (ptypeO+14)>>4;
00979 #else
00980     piece_owner=((ptypeO+14)>>4)|(((unsigned int)ptypeO>>30)&0x2);
00981 #endif
00982   }
00983   else{
00984     piece_owner=(((ptypeO+14)>>3)&0x2)|((unsigned int)ptypeO>>31);
00985   }
00986   assert(piece_owner >= 0 && piece_owner < 3);
00987   int effect_state_index = effectStateIndex3<Defense>(state, target);
00988 
00989   index_xy=piece_owner+effect_state_index+3*(8*((rel_y+2)+5*((x_diff+2)+5*(king_x-1+5*(king_y-1)))));
00990 }
00991 
00992 template <osl::Player Defense>
00993 void osl::eval::ml::King25EffectEachBoth::evalOne(
00994   const NumEffectState &state, MultiInt &out)
00995 {
00996   out.clear();
00997   const Square king = state.kingSquare<Defense>();
00998   const int min_dx = std::max(1, king.x() - 2)-king.x();
00999   const int max_dx = std::min(9, king.x() + 2)-king.x();
01000   const int min_dy = std::max(1, king.y() - 2)-king.y();
01001   const int max_dy = std::min(9, king.y() + 2)-king.y();
01002   const int king_x = (king.x() > 5 ? 10 - king.x() : king.x());
01003   const int king_y = (Defense == BLACK ? king.y() : 10 - king.y());
01004   if ((Defense == BLACK && king.x() >= 6) ||
01005       (Defense == WHITE && king.x() >= 5)){
01006     for (int dx = min_dx; dx <= max_dx; ++dx)
01007       {
01008         // [0, 2]
01009         // const int rel_x = std::abs(dx);
01010         // [-2, 2]
01011         int x_diff = dx;
01012         for (int dy = min_dy; dy <= max_dy; ++dy)
01013           {
01014             const Square target(king.x()+dx, king.y()+dy);
01015             // [-2, +2]
01016             const int rel_y = dy * (Defense == BLACK ? 1 : -1);
01017             int index_xy;
01018             index<Defense>(state, target, index_xy,
01019                            rel_y,king_x,king_y,x_diff);
01020             out += xy_table[index_xy];
01021           }
01022       }
01023   }
01024   else {
01025     for (int dx = min_dx; dx <= max_dx; ++dx)
01026       {
01027         // [0, 2]
01028         // const int rel_x = std::abs(dx);
01029         // [-2, 2]
01030         int x_diff = -dx;
01031         for (int dy = min_dy; dy <= max_dy; ++dy)
01032           {
01033             const Square target(king.x()+dx, king.y()+dy);
01034             // [-2, +2]
01035             const int rel_y = dy * (Defense == BLACK ? 1 : -1);
01036             int index_xy;
01037             index<Defense>(state, target, index_xy,
01038                            rel_y,king_x,king_y,x_diff);
01039             out +=  xy_table[index_xy];
01040           }
01041       }
01042   }
01043   if (Defense != BLACK)
01044     {
01045       out = -out;
01046     }
01047 }
01048 
01049 void osl::eval::ml::
01050 King25EffectEachBoth::eval(const NumEffectState &state,
01051                            MultiIntPair &out)
01052 {
01053   evalOne<BLACK>(state, out[BLACK]);
01054   evalOne<WHITE>(state, out[WHITE]);
01055 }
01056 
01057 void
01058 osl::eval::ml::King25EffectEachBoth::evalWithUpdate(
01059   const NumEffectState &state, Move last_move,
01060   MultiIntPair &values)
01061 {
01062   BoardMask mb = state.changedEffects(BLACK), mw = state.changedEffects(WHITE);
01063   mb.set(Square(last_move.to())); mb.set(Square(last_move.from()));
01064   mw.set(Square(last_move.to())); mw.set(Square(last_move.from()));
01065   const Square kb = state.kingSquare<BLACK>(), kw = state.kingSquare<WHITE>();
01066   const bool update_black = mb.anyInRange(Board_Mask_Table5x5.mask(kb)) ||
01067     mw.anyInRange(Board_Mask_Table5x5.mask(kb));
01068   const bool update_white = mw.anyInRange(Board_Mask_Table5x5.mask(kw)) ||
01069     mb.anyInRange(Board_Mask_Table5x5.mask(kw));
01070   if (update_black)
01071   {
01072     evalOne<BLACK>(state, values[BLACK]);
01073   }
01074   if (update_white)
01075   {
01076     evalOne<WHITE>(state, values[WHITE]);
01077   }
01078 }
01079 
01080 
01081 template <bool Opening>
01082 osl::misc::CArray<int, 1125> osl::eval::ml::King25EmptyAbs<Opening>::table;
01083 
01084 template <bool Opening>
01085 void osl::eval::ml::
01086 King25EmptyAbs<Opening>::setUp(const Weights &weights)
01087 {
01088   for (size_t i = 0; i < weights.dimension(); ++i)
01089   {
01090     table[i] = weights.value(i);
01091   }
01092 }
01093 
01094 template <bool Opening>
01095 template <osl::Player player>
01096 int osl::eval::ml::King25EmptyAbs<Opening>::index(Square king,
01097                                                             Square target)
01098 {
01099   int x, target_x;
01100   if ((player == BLACK && king.x() >= 6) ||
01101       (player == WHITE && king.x() >= 5))
01102   {
01103     x = 10 - king.x();
01104     target_x = 10 - target.x();
01105   }
01106   else
01107   {
01108     x = king.x();
01109     target_x = target.x();
01110   }
01111   const int y = (player == BLACK ? king.y() : 10 - king.y());
01112   const int target_y = (player == BLACK ? target.y() : 10 - target.y());
01113 
01114   return target_y - y + 2 + (target_x - x + 2 ) * 5 + (y - 1) * 5 * 5
01115     + (x - 1) * 5 * 5 * 9;
01116 }
01117 
01118 template <bool Opening>
01119 template <osl::Player Defense>
01120 int osl::eval::ml::King25EmptyAbs<Opening>::evalOne(
01121   const osl::state::NumEffectState &state)
01122 {
01123   int result = 0;
01124   const Square king = state.kingSquare<Defense>();
01125   const int min_x = std::max(1, king.x() - 2);
01126   const int max_x = std::min(9, king.x() + 2);
01127   const int min_y = std::max(1, king.y() - 2);
01128   const int max_y = std::min(9, king.y() + 2);
01129   for (int x = min_x; x <= max_x; ++x)
01130   {
01131     for (int y = min_y; y <= max_y; ++y)
01132     {
01133       Square target(x, y);
01134       if (target.isOnBoard() && state.pieceAt(target).isEmpty())
01135       {
01136         result += table[index<Defense>(king, target)];
01137       }
01138     }
01139   }
01140   if (Defense == BLACK)
01141     return result;
01142   else
01143     return -result;
01144 }
01145 
01146 template <bool Opening>
01147 int osl::eval::ml::King25EmptyAbs<Opening>::eval(
01148   const osl::state::NumEffectState &state)
01149 {
01150   return evalOne<BLACK>(state) + evalOne<WHITE>(state);
01151 }
01152 
01153 template <bool Opening>
01154 int osl::eval::ml::King25EmptyAbs<Opening>::evalWithUpdate(
01155   const osl::state::NumEffectState &state, osl::Move moved,
01156   int last_value)
01157 {
01158   if (moved.ptype() == osl::KING)
01159   {
01160     return eval(state);
01161   }
01162   const osl::Square self_king = state.kingSquare(moved.player());
01163   const osl::Square opp_king = state.kingSquare(alt(moved.player()));
01164   int result = last_value;
01165 
01166   if (!moved.isDrop())
01167   {
01168     const Square from = moved.from();
01169     if (std::abs(self_king.x() - from.x()) <= 2 &&
01170         std::abs(self_king.y() - from.y()) <= 2)
01171     {
01172       result += table[index(self_king, moved.from(), moved.player())] *
01173         (moved.player() == BLACK ? 1 : -1);
01174     }
01175 
01176     if (std::abs(opp_king.x() - from.x()) <= 2 &&
01177         std::abs(opp_king.y() - from.y()) <= 2)
01178     {
01179       result -= table[index(opp_king, from, alt(moved.player()))] *
01180         (moved.player() == BLACK ? 1 : -1);
01181     }
01182   }
01183 
01184   Ptype captured = moved.capturePtype();
01185   if (captured == PTYPE_EMPTY)
01186   {
01187     const Square to = moved.to();
01188     if (std::abs(self_king.x() - to.x()) <= 2 &&
01189         std::abs(self_king.y() - to.y()) <= 2)
01190     {
01191       result -= table[index(self_king, to, moved.player())] *
01192         (moved.player() == BLACK ? 1 : -1);
01193     }
01194     if (std::abs(opp_king.x() - to.x()) <= 2 &&
01195         std::abs(opp_king.y() - to.y()) <= 2)
01196     {
01197       result += table[index(opp_king, to, alt(moved.player()))] *
01198         (moved.player() == BLACK ? 1 : -1);
01199     }
01200   }
01201   return result;
01202 
01203 }
01204 
01205 osl::CArray<MultiInt, 3072> osl::eval::ml::King3Pieces::table;
01206 osl::CArray<MultiInt, 15360> osl::eval::ml::King3Pieces::x_table;
01207 osl::CArray<MultiInt, 27648> osl::eval::ml::King3Pieces::y_table;
01208 
01209 void osl::eval::ml::King3Pieces::setUp(const Weights &weights)
01210 {
01211   for (int i = 0; i < ONE_DIM; ++i)
01212   {
01213     for (int s=0; s<NStages; ++s)
01214       table[i][s] = weights.value(i + ONE_DIM*s);
01215   }
01216 }
01217 
01218 void osl::eval::ml::King3PiecesXY::setUp(const Weights &weights)
01219 {
01220   for (int i = 0; i < X_DIM; ++i)
01221   {
01222     for (int s=0; s<NStages; ++s)
01223       King3Pieces::x_table[i][s] = weights.value(i + ONE_DIM*s);
01224   }
01225   for (int i = 0; i < Y_DIM; ++i)
01226   {
01227     for (int s=0; s<NStages; ++s)
01228       King3Pieces::y_table[i][s] = weights.value(i + ONE_DIM*s + X_DIM);
01229   }
01230 }
01231 
01232 template <osl::Player King>
01233 void osl::eval::ml::King3Pieces::evalOne(const NumEffectState &state,
01234                                                    MultiInt &result)
01235 {
01236   const Square king = state.kingSquare<King>();
01237   const int vertical_index =
01238     index<King, VERTICAL>(
01239       state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
01240       state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
01241   const int vertical_index_x =
01242     indexX<King, VERTICAL>(
01243       king,
01244       state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
01245       state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
01246   const int vertical_index_y =
01247     indexY<King, VERTICAL>(
01248       king,
01249       state.pieceAt(king + DirectionPlayerTraits<U, King>::offset()).ptypeO(),
01250       state.pieceAt(king + DirectionPlayerTraits<D, King>::offset()).ptypeO());
01251   const int horizontal_index =
01252     index<King, HORIZONTAL>(
01253       state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
01254       state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
01255   const int horizontal_index_x =
01256     indexX<King, HORIZONTAL>(
01257       king,
01258       state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
01259       state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
01260   const int horizontal_index_y =
01261     indexY<King, HORIZONTAL>(
01262       king,
01263       state.pieceAt(king + DirectionPlayerTraits<L, King>::offset()).ptypeO(),
01264       state.pieceAt(king + DirectionPlayerTraits<R, King>::offset()).ptypeO());
01265   const int diagonal_index1 =
01266     index<King, DIAGONAL>(
01267       state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
01268       state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
01269   const int diagonal_index2 =
01270     index<King, DIAGONAL>(
01271       state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
01272       state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
01273   const int diagonal_index1_x =
01274     indexX<King, DIAGONAL>(
01275       king,
01276       state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
01277       state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
01278   const int diagonal_index2_x=
01279     indexX<King, DIAGONAL>(
01280       king,
01281       state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
01282       state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
01283   const int diagonal_index1_y =
01284     indexY<King, DIAGONAL>(
01285       king,
01286       state.pieceAt(king + DirectionPlayerTraits<UL, King>::offset()).ptypeO(),
01287       state.pieceAt(king + DirectionPlayerTraits<DR, King>::offset()).ptypeO());
01288   const int diagonal_index2_y =
01289     indexY<King, DIAGONAL>(
01290       king,
01291       state.pieceAt(king + DirectionPlayerTraits<UR, King>::offset()).ptypeO(),
01292       state.pieceAt(king + DirectionPlayerTraits<DL, King>::offset()).ptypeO());
01293   const MultiInt v = value(vertical_index, horizontal_index,
01294                             diagonal_index1, diagonal_index2,
01295                             vertical_index_x,  horizontal_index_x,
01296                             diagonal_index1_x, diagonal_index2_x,
01297                             vertical_index_y , horizontal_index_y,
01298                             diagonal_index1_y, diagonal_index2_y);
01299   if (King == BLACK)
01300   {
01301     result += v;
01302   }
01303   else
01304   {
01305     result -= v;
01306   }
01307 }
01308 
01309 MultiInt
01310 osl::eval::ml::King3Pieces::eval(const NumEffectState &state)
01311 {
01312   MultiInt result;
01313   evalOne<BLACK>(state, result);
01314   evalOne<WHITE>(state, result);
01315   return result;
01316 }
01317 
01318 MultiInt
01319 osl::eval::ml::King3Pieces::evalWithUpdate(
01320   const NumEffectState &state,
01321   Move last_move,
01322   MultiInt &last_value)
01323 {
01324   const CArray<Square,2> kings = {{ 
01325       state.kingSquare(BLACK),
01326       state.kingSquare(WHITE),
01327     }};
01328   if ((std::abs(last_move.to().x() - kings[0].x()) <= 1 &&
01329        std::abs(last_move.to().y() - kings[0].y()) <= 1) ||
01330       (std::abs(last_move.to().x() - kings[1].x()) <= 1 &&
01331        std::abs(last_move.to().y() - kings[1].y()) <= 1))
01332     return eval(state);
01333   if (!last_move.isDrop())
01334   {
01335     if ((std::abs(last_move.from().x() - kings[0].x()) <= 1 &&
01336          std::abs(last_move.from().y() - kings[0].y()) <= 1) ||
01337         (std::abs(last_move.from().x() - kings[1].x()) <= 1 &&
01338          std::abs(last_move.from().y() - kings[1].y()) <= 1))
01339       return eval(state);
01340   }
01341   return last_value;
01342 }
01343 
01344 
01345 
01346 osl::misc::CArray<int, 17 * 128> osl::eval::ml::King25EffectAttack::table;
01347 osl::misc::CArray<MultiInt, 17 * 128> osl::eval::ml::King25EffectDefense::table;
01348 
01349 osl::misc::CArray<int, 17 * 128 * 9> osl::eval::ml::King25EffectYAttack::table;
01350 osl::misc::CArray<MultiInt, 17 * 128 * 9> osl::eval::ml::King25EffectYDefense::table;
01351 
01352 
01353 osl::misc::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::table;
01354 osl::misc::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::rook_table;
01355 osl::misc::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::bishop_table;
01356 osl::misc::CArray<MultiInt, 3240> osl::eval::ml::KingMobility::rook_bishop_table;
01357 
01358 void osl::eval::ml::KingMobility::setUp(const Weights &weights)
01359 {
01360   static CArray<MultiInt, 3240> old_table;
01361   for (int i = 0; i < ONE_DIM; ++i)
01362   {
01363     for (int s=0; s<NStages; ++s)
01364       old_table[i][s] = weights.value(i + ONE_DIM*s);
01365   }
01366   for(int king_x=0;king_x<5;king_x++)
01367     for(int king_y=0;king_y<9;king_y++)
01368       for(int dir=0;dir<8;dir++)
01369         for(int mobility=0;mobility<9;mobility++){
01370           int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
01371           int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
01372           for (int s=0; s<NStages; ++s)
01373             table[newIndex][s]=old_table[oldIndex][s];
01374         }
01375 }
01376 
01377 void osl::eval::ml::
01378 KingMobilityWithRook::setUp(const Weights &weights)
01379 {
01380   static CArray<MultiInt, 3240> old_table;
01381   for (int i = 0; i < ONE_DIM; ++i)
01382   {
01383     for (int s=0; s<NStages; ++s)
01384       old_table[i][s] = weights.value(i + ONE_DIM*s);
01385   }
01386   for(int king_x=0;king_x<5;king_x++)
01387     for(int king_y=0;king_y<9;king_y++)
01388       for(int dir=0;dir<8;dir++)
01389         for(int mobility=0;mobility<9;mobility++){
01390           int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
01391           int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
01392           for (int s=0; s<NStages; ++s)
01393             KingMobility::rook_table[newIndex][s]=old_table[oldIndex][s];
01394         }
01395 }
01396 
01397 void osl::eval::ml::
01398 KingMobilityWithBishop::setUp(const Weights &weights)
01399 {
01400   static CArray<MultiInt, 3240> old_table;
01401   for (int i = 0; i < ONE_DIM; ++i)
01402   {
01403     for (int s=0; s<NStages; ++s)
01404       old_table[i][s] = weights.value(i + ONE_DIM*s);
01405   }
01406   for(int king_x=0;king_x<5;king_x++)
01407     for(int king_y=0;king_y<9;king_y++)
01408       for(int dir=0;dir<8;dir++)
01409         for(int mobility=0;mobility<9;mobility++){
01410           int oldIndex=king_x + 5 * (king_y + 9 * (dir + 8 * mobility));
01411           int newIndex=mobility+9*(dir+8*(king_y+9*king_x));
01412           for (int s=0; s<NStages; ++s)
01413             KingMobility::bishop_table[newIndex][s]=old_table[oldIndex][s];
01414         }
01415   for(int i=0;i<3240;i++){
01416     KingMobility::rook_bishop_table[i]=
01417       KingMobility::table[i]+KingMobility::rook_table[i]+KingMobility::bishop_table[i];
01418     KingMobility::rook_table[i]+=KingMobility::table[i];
01419     KingMobility::bishop_table[i]+=KingMobility::table[i];
01420   }
01421 }
01422 
01423 template <osl::Player P>
01424 osl::MultiInt osl::eval::ml::
01425 KingMobility::evalOne(const NumEffectState &state)
01426 {
01427   MultiInt result;
01428   const Square king = state.kingSquare<P>();
01429   const int king_x = (king.x() > 5 ? 10 - king.x() : king.x()) - 1;
01430   const int king_y = (P == BLACK ? king.y() : 10 - king.y()) - 1;
01431   int indexBase=9*8*(king_y+9*king_x);
01432   if(P==BLACK){
01433     if (state.hasPieceOnStand<ROOK>(alt(P)))
01434     {
01435       if(state.hasPieceOnStand<BISHOP>(alt(P))){
01436         result =
01437           rook_bishop_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01438           rook_bishop_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01439           rook_bishop_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01440           rook_bishop_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01441           rook_bishop_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01442           rook_bishop_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01443           rook_bishop_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01444           rook_bishop_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01445       }
01446       else{
01447         result =
01448           rook_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01449           rook_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01450           rook_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01451           rook_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01452           rook_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01453           rook_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01454           rook_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01455           rook_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01456       }
01457     }
01458     else if(state.hasPieceOnStand<BISHOP>(alt(P))){
01459       result = 
01460         bishop_table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01461         bishop_table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01462         bishop_table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01463         bishop_table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01464         bishop_table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01465         bishop_table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01466         bishop_table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01467         bishop_table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01468     }
01469     else{
01470       result = 
01471         table[indexBase+0*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01472         table[indexBase+1*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01473         table[indexBase+2*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01474         table[indexBase+3*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01475         table[indexBase+4*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01476         table[indexBase+5*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01477         table[indexBase+6*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01478         table[indexBase+7*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))];
01479     }
01480   }
01481   else{
01482     if (state.hasPieceOnStand<ROOK>(alt(P)))
01483     {
01484       if(state.hasPieceOnStand<BISHOP>(alt(P))){
01485         result = -(
01486           rook_bishop_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01487           rook_bishop_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01488           rook_bishop_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01489           rook_bishop_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01490           rook_bishop_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01491           rook_bishop_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01492           rook_bishop_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01493           rook_bishop_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01494       }
01495       else{
01496         result = -(
01497           rook_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01498           rook_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01499           rook_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01500           rook_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01501           rook_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01502           rook_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01503           rook_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01504           rook_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01505       }
01506     }
01507     else if(state.hasPieceOnStand<BISHOP>(alt(P))){
01508       result = -(
01509         bishop_table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01510         bishop_table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01511         bishop_table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01512         bishop_table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01513         bishop_table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01514         bishop_table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01515         bishop_table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01516         bishop_table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01517     }
01518     else{
01519       result = -(
01520         table[indexBase+7*9+mobilityDir<UL>(king,state.kingMobilityAbs(P, UL))]+
01521         table[indexBase+6*9+mobilityDir<U>(king,state.kingMobilityAbs(P, U))]+
01522         table[indexBase+5*9+mobilityDir<UR>(king,state.kingMobilityAbs(P, UR))]+
01523         table[indexBase+4*9+mobilityDir<L>(king,state.kingMobilityAbs(P, L))]+
01524         table[indexBase+3*9+mobilityDir<R>(king,state.kingMobilityAbs(P, R))]+
01525         table[indexBase+2*9+mobilityDir<DL>(king,state.kingMobilityAbs(P, DL))]+
01526         table[indexBase+1*9+mobilityDir<D>(king,state.kingMobilityAbs(P, D))]+
01527         table[indexBase+0*9+mobilityDir<DR>(king,state.kingMobilityAbs(P, DR))]);
01528     }
01529   }
01530   return result;
01531 }  
01532 
01533 osl::MultiInt osl::eval::ml::
01534 KingMobility::eval(const NumEffectState &state)
01535 {
01536   MultiInt result = evalOne<BLACK>(state) + evalOne<WHITE>(state);
01537   return result;
01538 }  
01539 
01540 
01541 osl::misc::CArray<MultiInt, 45*33> osl::eval::ml::KingMobilitySum::table;
01542 
01543 void osl::eval::ml::KingMobilitySum::setUp(const Weights &weights)
01544 {
01545   CArray<MultiInt, 2925> old_table;
01546   for (int i = 0; i < ONE_DIM; ++i)
01547   {
01548     for (int s=0; s<NStages; ++s)
01549       old_table[i][s] = weights.value(i + ONE_DIM*s);
01550   }
01551   for(int king_x=0;king_x<5;king_x++)
01552     for(int king_y=0;king_y<9;king_y++)
01553       for(int mobility=0;mobility<=32;mobility++){
01554         int oldIndex=king_x+5*(king_y+9*(mobility+8));
01555         int newIndex=mobility+33*(king_y+9*king_x);
01556         for (int s=0; s<NStages; ++s)
01557           table[newIndex]=old_table[oldIndex];
01558       }
01559 }
01560 
01561 template <osl::Player P>
01562 osl::MultiInt osl::eval::ml::
01563 KingMobilitySum::evalOne(const NumEffectState &state)
01564 {
01565   MultiInt result;
01566   const Square king = state.kingSquare<P>();
01567   int sum=state.kingMobilityAbs(P, UL).y()+state.kingMobilityAbs(P, U).y()+
01568     state.kingMobilityAbs(P, UR).y()+state.kingMobilityAbs(P, R).x()-
01569     state.kingMobilityAbs(P, DL).y()-state.kingMobilityAbs(P, D).y()-
01570     state.kingMobilityAbs(P, DR).y()-state.kingMobilityAbs(P, L).x();
01571   const int king_x = (king.x() > 5 ? 10 - king.x() : king.x()) - 1;
01572   const int king_y = (P == BLACK ? king.y() : 10 - king.y()) - 1;
01573   int mobility=sum-8;
01574   result = table[mobility+33*(king_y+9*king_x)];
01575   if (P == BLACK)
01576   {
01577     return result;
01578   }
01579   else
01580   {
01581     return -result;
01582   }
01583 }  
01584 
01585 osl::MultiInt osl::eval::ml::
01586 KingMobilitySum::eval(const NumEffectState &state)
01587 {
01588   MultiInt result = evalOne<BLACK>(state) + evalOne<WHITE>(state);
01589   return result;
01590 }  
01591 
01592 
01593 osl::misc::CArray<MultiInt, 8192>
01594 osl::eval::ml::King25BothSide::table;
01595 osl::misc::CArray<MultiInt, 40960>
01596 osl::eval::ml::King25BothSide::x_table;
01597 osl::misc::CArray<MultiInt, 73728>
01598 osl::eval::ml::King25BothSide::y_table;
01599 
01600 void osl::eval::ml::King25BothSide::setUp(const Weights &weights)
01601 {
01602   for (int i = 0; i < ONE_DIM; ++i)
01603   {
01604     for (int s=0; s<NStages; ++s)
01605       table[i][s] = weights.value(i + ONE_DIM*s);
01606   }
01607 }
01608 
01609 void osl::eval::ml::King25BothSideX::setUp(const Weights &weights)
01610 {
01611   for (int i = 0; i < ONE_DIM; ++i)
01612   {
01613     for (int s=0; s<NStages; ++s)
01614       King25BothSide::x_table[i][s] = weights.value(i + ONE_DIM*s);
01615   }
01616 }
01617 
01618 void osl::eval::ml::King25BothSideY::setUp(const Weights &weights)
01619 {
01620   for (int i = 0; i < ONE_DIM; ++i)
01621   {
01622     for (int s=0; s<NStages; ++s)
01623       King25BothSide::y_table[i][s] = weights.value(i + ONE_DIM*s);
01624   }
01625   for(int king_y=1;king_y<=9;king_y++)
01626     for(int effect1=0;effect1<32;effect1++)
01627       for(int effect2=0;effect2<32;effect2++)
01628         for(int i=0;i<8;i++){
01629           int index0=effect1 + 32 * (effect2 + 32 * i);
01630           int index1=king_y - 1 + 9 *(effect1 + 32 * (effect2 + 32 * i));
01631           King25BothSide::y_table[index1] += King25BothSide::table[index0];
01632         }
01633 }
01634 
01635 template<osl::Player P>
01636 osl::MultiInt osl::eval::ml::
01637 King25BothSide::evalOne(const NumEffectState &state,
01638                         const CArray<int, 5> &effects)
01639 {
01640   const Square king=state.kingSquare<P>();
01641   const int king_y = (P==BLACK ? king.y() : 10 - king.y());
01642   const int king_x = (king.x() >= 6 ? 10 - king.x() : king.x());
01643   if ((P== BLACK && king.x() > 5) || (P==WHITE && king.x() < 5)){
01644     return
01645       x_table[indexX(king_x,effects[2],effects[0],(2*3)+1)]+ // (0,2)
01646       y_table[indexY(king_y,effects[0],effects[2],(0*3)+0)]+
01647       x_table[indexX(king_x,effects[3],effects[0],(1*3)+2)]+ // (0,3)
01648       y_table[indexY(king_y,effects[0],effects[3],(0*3)+1)]+
01649       x_table[indexX(king_x,effects[4],effects[0],(0*3)+2)]+ // (0,4)
01650       y_table[indexY(king_y,effects[0],effects[4],(0*3)+2)]+
01651       x_table[indexX(king_x,effects[2],effects[1],(2*3)+0)]+ // (1,2)
01652       y_table[indexY(king_y,effects[1],effects[2],(1*3)+0)]+
01653       x_table[indexX(king_x,effects[3],effects[1],(1*3)+1)]+ // (1,3)
01654       y_table[indexY(king_y,effects[1],effects[3],(1*3)+1)]+
01655       x_table[indexX(king_x,effects[4],effects[1],(0*3)+1)]+ // (1,4)
01656       y_table[indexY(king_y,effects[1],effects[4],(1*3)+2)]+
01657       x_table[indexX(king_x,effects[3],effects[2],(1*3)+0)]+ // (2,3)
01658       y_table[indexY(king_y,effects[2],effects[3],(2*3)+0)]+
01659       x_table[indexX(king_x,effects[4],effects[2],(0*3)+0)]+ // (2,4)
01660       y_table[indexY(king_y,effects[2],effects[4],(2*3)+1)];
01661   }
01662   else{
01663     return
01664       x_table[indexX(king_x,effects[0],effects[2],(0*3)+0)]+ // (0,2)
01665       y_table[indexY(king_y,effects[0],effects[2],(0*3)+0)]+
01666       x_table[indexX(king_x,effects[0],effects[3],(0*3)+1)]+ // (0,3)
01667       y_table[indexY(king_y,effects[0],effects[3],(0*3)+1)]+
01668       x_table[indexX(king_x,effects[0],effects[4],(0*3)+2)]+ // (0,4)
01669       y_table[indexY(king_y,effects[0],effects[4],(0*3)+2)]+
01670       x_table[indexX(king_x,effects[1],effects[2],(1*3)+0)]+ // (1,2)
01671       y_table[indexY(king_y,effects[1],effects[2],(1*3)+0)]+
01672       x_table[indexX(king_x,effects[1],effects[3],(1*3)+1)]+ // (1,3)
01673       y_table[indexY(king_y,effects[1],effects[3],(1*3)+1)]+
01674       x_table[indexX(king_x,effects[1],effects[4],(1*3)+2)]+ // (1,4)
01675       y_table[indexY(king_y,effects[1],effects[4],(1*3)+2)]+
01676       x_table[indexX(king_x,effects[2],effects[3],(2*3)+0)]+ // (2,3)
01677       y_table[indexY(king_y,effects[2],effects[3],(2*3)+0)]+
01678       x_table[indexX(king_x,effects[2],effects[4],(2*3)+1)]+ // (2,4)
01679       y_table[indexY(king_y,effects[2],effects[4],(2*3)+1)];
01680   }
01681 }
01682 
01683 osl::MultiInt osl::eval::ml::
01684 King25BothSide::eval(const NumEffectState &state,
01685                      const CArray<int, 5> &black,
01686                      const CArray<int, 5> &white)
01687 {
01688   return evalOne<BLACK>(state,black)-evalOne<WHITE>(state,white);
01689 }
01690 
01691 osl::misc::CArray<MultiInt, 2400>
01692 osl::eval::ml::King25Effect3::table;
01693 osl::misc::CArray<MultiInt, 21600>
01694 osl::eval::ml::King25Effect3::y_table;
01695 
01696 void osl::eval::ml::King25Effect3::setUp(const Weights &weights)
01697 {
01698   for (int i = 0; i < ONE_DIM; ++i)
01699   {
01700     for (int s=0; s<NStages; ++s)
01701       table[i][s] = weights.value(i + ONE_DIM*s);
01702   }
01703 }
01704 
01705 void osl::eval::ml::King25Effect3Y::setUp(const Weights &weights)
01706 {
01707   for (int i = 0; i < ONE_DIM; ++i)
01708   {
01709     for (int s=0; s<NStages; ++s)
01710       King25Effect3::y_table[i][s] = weights.value(i + ONE_DIM*s);
01711   }
01712 }
01713 
01714 template <osl::Player Attack>
01715 osl::MultiInt osl::eval::ml::
01716 King25Effect3::evalOne(const NumEffectState &state,
01717                        PieceMask king25)
01718 {
01719   king25 = king25 & state.piecesOnBoard(Attack);
01720   const PieceMask promoted_mask = (king25 & state.promotedPieces());
01721   const bool with_knight =
01722     (king25 & ~state.promotedPieces()).template selectBit<KNIGHT>().any();
01723   king25.clearBit<KNIGHT>();
01724   king25.clearBit<LANCE>();
01725   king25.clearBit<PAWN>();
01726   king25 = king25 | promoted_mask;
01727   const int piece_count = std::min(9, king25.countBit());
01728   const int stand_count = std::min(9,
01729                                    state.countPiecesOnStand<ROOK>(Attack) +
01730                                    state.countPiecesOnStand<BISHOP>(Attack) +
01731                                    state.countPiecesOnStand<GOLD>(Attack) +
01732                                    state.countPiecesOnStand<SILVER>(Attack));
01733   const bool stand_with_knight = state.hasPieceOnStand<KNIGHT>(Attack);
01734   const Player Defense = PlayerTraits<Attack>::opponent;
01735   PieceMask attacked =
01736     state.effectedMask(Attack) & state.piecesOnBoard(Defense);
01737   attacked.clearBit<KNIGHT>();
01738   attacked.clearBit<LANCE>();
01739   attacked.clearBit<PAWN>();
01740   PieceMask attacking;
01741   while (attacked.any())
01742   {
01743     const Piece piece = state.pieceOf(attacked.takeOneBit());
01744     attacking = attacking | state.effectSetAt(piece.square());
01745   }
01746   attacking = (attacking & state.piecesOnBoard(Attack) & ~king25);
01747   const int attacked_count = std::min(5, attacking.countBit());
01748   if (Attack == BLACK)
01749   {
01750     return table[index(piece_count, with_knight,
01751                        stand_count, stand_with_knight, attacked_count)] +
01752       y_table[indexY(piece_count, with_knight,
01753                      stand_count, stand_with_knight, attacked_count,
01754                      state.kingSquare<WHITE>().y())];
01755   }
01756   else
01757   {
01758     return -(table[index(piece_count, with_knight,
01759                          stand_count, stand_with_knight, attacked_count)] +
01760              y_table[indexY(piece_count, with_knight,
01761                             stand_count, stand_with_knight, attacked_count,
01762                             10 - state.kingSquare<BLACK>().y())]);
01763   }
01764 }
01765 
01766 osl::MultiInt osl::eval::ml::
01767 King25Effect3::eval(const NumEffectState &state,
01768                     const CArray<PieceMask, 2> &king25_mask)
01769 {
01770   return evalOne<BLACK>(state, king25_mask[WHITE]) +
01771     evalOne<WHITE>(state, king25_mask[BLACK]);
01772 }
01773 
01774 
01775 osl::misc::CArray<MultiInt, 4096>
01776 osl::eval::ml::King25Mobility::table;
01777 osl::misc::CArray<MultiInt, 20480>
01778 osl::eval::ml::King25Mobility::x_table;
01779 osl::misc::CArray<MultiInt, 36864>
01780 osl::eval::ml::King25Mobility::y_table;
01781 
01782 void osl::eval::ml::King25Mobility::setUp(const Weights &weights)
01783 {
01784   for (int i = 0; i < ONE_DIM; ++i)
01785   {
01786     for (int s=0; s<NStages; ++s)
01787       table[i][s] = weights.value(i + ONE_DIM*s);
01788   }
01789 }
01790 
01791 void osl::eval::ml::King25MobilityX::setUp(const Weights &weights)
01792 {
01793   for (int i = 0; i < ONE_DIM; ++i)
01794   {
01795     for (int s=0; s<NStages; ++s)
01796       King25Mobility::x_table[i][s] = weights.value(i + ONE_DIM*s);
01797   }
01798 }
01799 
01800 void osl::eval::ml::King25MobilityY::setUp(const Weights &weights)
01801 {
01802   for (int i = 0; i < ONE_DIM; ++i)
01803   {
01804     for (int s=0; s<NStages; ++s)
01805       King25Mobility::y_table[i][s] = weights.value(i + ONE_DIM*s);
01806   }
01807 }
01808 
01809 osl::MultiInt osl::eval::ml::
01810 King25Mobility::eval(const NumEffectState &state,
01811                      const CArray<int, 5> &black,
01812                      const CArray<int, 5> &white)
01813 {
01814   const CArray<Square,2> kings = {{ 
01815       state.kingSquare<BLACK>(),
01816       state.kingSquare<WHITE>(),
01817     }};
01818   MultiInt result;
01819   for (size_t i = 1; i < black.size(); ++i)
01820   {
01821     result += (table[index(black[i - 1], black[i], i - 1)] +
01822                x_table[indexX<BLACK>(kings[BLACK],
01823                                      black[i - 1], black[i], i - 1)] +
01824                y_table[indexY<BLACK>(kings[BLACK],
01825                                      black[i - 1], black[i], i - 1)]);
01826     result -= (table[index(white[i - 1], white[i], i - 1)] +
01827                x_table[indexX<WHITE>(kings[WHITE],
01828                                      white[i - 1], white[i], i - 1)] +
01829                y_table[indexY<WHITE>(kings[WHITE],
01830                                      white[i - 1], white[i], i - 1)]);
01831   }
01832   return result;
01833 }
01834 
01835 
01836 osl::misc::CArray<MultiInt, 100>
01837 osl::eval::ml::King25EffectCountCombination::table;
01838 osl::misc::CArray<MultiInt, 900>
01839 osl::eval::ml::King25EffectCountCombination::y_table;
01840 
01841 void osl::eval::ml::King25EffectCountCombination::setUp(const Weights &weights)
01842 {
01843   for (int i = 0; i < ONE_DIM; ++i)
01844   {
01845     for (int s=0; s<NStages; ++s)
01846       table[i][s] = weights.value(i + ONE_DIM*s);
01847   }
01848 }
01849 
01850 void osl::eval::ml::King25EffectCountCombinationY::setUp(const Weights &weights)
01851 {
01852   for (int i = 0; i < ONE_DIM; ++i)
01853   {
01854     for (int s=0; s<NStages; ++s)
01855       King25EffectCountCombination::y_table[i][s] = weights.value(i + ONE_DIM*s);
01856   }
01857 }
01858 
01859 template <osl::Player Attack>
01860 osl::MultiInt osl::eval::ml::
01861 King25EffectCountCombination::evalOne(const NumEffectState &state,
01862                                       PieceMask king25)
01863 {
01864   const Player Defense = PlayerTraits<Attack>::opponent;
01865   PieceMask attack = king25 & state.piecesOnBoard(Attack);
01866   PieceMask defense =
01867     king25 & state.piecesOnBoard(Defense);
01868   const PieceMask attack_promoted_mask = (attack & state.promotedPieces());
01869   const PieceMask defense_promoted_mask = (defense & state.promotedPieces());
01870   attack.clearBit<KNIGHT>();
01871   attack.clearBit<LANCE>();
01872   attack.clearBit<PAWN>();
01873   attack = attack | attack_promoted_mask;
01874   defense.clearBit<KNIGHT>();
01875   defense.clearBit<LANCE>();
01876   defense.clearBit<PAWN>();
01877   defense = defense | defense_promoted_mask;
01878   const int attack_count = std::min(9,
01879                                     attack.countBit() +
01880                                     state.countPiecesOnStand<ROOK>(Attack) +
01881                                     state.countPiecesOnStand<BISHOP>(Attack) +
01882                                     state.countPiecesOnStand<GOLD>(Attack) +
01883                                     state.countPiecesOnStand<SILVER>(Attack));
01884   const int defense_count = std::min(9,
01885                                     defense.countBit() +
01886                                     state.countPiecesOnStand<ROOK>(Defense) +
01887                                     state.countPiecesOnStand<BISHOP>(Defense) +
01888                                     state.countPiecesOnStand<GOLD>(Defense) +
01889                                     state.countPiecesOnStand<SILVER>(Defense));
01890   const int y = (Attack == BLACK ? state.kingSquare<Defense>().y() :
01891                  10 - state.kingSquare<Defense>().y());
01892   MultiInt result = table[attack_count + 10 * defense_count] +
01893     y_table[y - 1 + 9 * (attack_count + 10 * defense_count)];
01894   if (Attack == BLACK)
01895     return result;
01896   else
01897     return -result;
01898 }
01899 
01900 osl::MultiInt osl::eval::ml::
01901 King25EffectCountCombination::eval(const NumEffectState &state,
01902                                    const CArray<PieceMask, 2> &king25_mask)
01903 {
01904   return evalOne<BLACK>(state, king25_mask[WHITE]) +
01905     evalOne<WHITE>(state, king25_mask[BLACK]);
01906 }
01907 
01908 
01909 osl::CArray<int, 18*81*(45*2)*3> osl::eval::ml::BishopExchangeSilverKing::table;
01910 void osl::eval::ml::
01911 BishopExchangeSilverKing::setUp(const Weights & weights)
01912 {
01913   for (size_t i=0; i<weights.dimension(); ++i)
01914     table[i] = weights.value(i);
01915 }
01916 
01917 int osl::eval::ml::
01918 BishopExchangeSilverKing::eval(const NumEffectState &state)
01919 {
01920   if (state.promotedPieces().any())
01921     return 0;
01922   PieceMask stand_all = state.standMask(BLACK) | state.standMask(WHITE);
01923   stand_all.clearBit<BISHOP>();
01924   stand_all.clearBit<PAWN>();
01925   if (stand_all.any())
01926     return 0;
01927   if (state.nth<BISHOP>(0).owner() == state.nth<BISHOP>(1).owner())
01928     return 0;
01929   if (state.nth<BISHOP>(0).isOnBoard() != state.nth<BISHOP>(1).isOnBoard())
01930     return 0;
01931   int offset = 0;
01932   if (state.nth<BISHOP>(0).isOnBoard()) {
01933     offset += BISHOP_ONE_DIM;
01934     if (state.hasEffectByPiece(state.nth<BISHOP>(0),
01935                                state.nth<BISHOP>(1).square()))
01936       offset += BISHOP_ONE_DIM;
01937   }
01938   return evalOne<BLACK>(state, offset) + evalOne<WHITE>(state, offset);
01939 }
01940 
01941 template <osl::Player KingOwner>
01942 int osl::eval::ml::
01943 BishopExchangeSilverKing::evalOne(const NumEffectState &state, int offset)
01944 {
01945   Square king = state.kingSquare(KingOwner);
01946   int king_index = indexKing(king.squareForBlack(alt(KingOwner))); // rotate if king is black
01947   if (king_index < 0)
01948     return 0;
01949   CArray<Piece,2> rook = {{
01950       state.nth<ROOK>(0), state.nth<ROOK>(1),
01951     }};
01952   if (rook[0].owner() == rook[1].owner())
01953     return 0;
01954   if (rook[0].owner() == KingOwner)
01955     std::swap(rook[0], rook[1]);
01956   int rook_index0 = indexKing(rook[0].square().squareForBlack(KingOwner)); // rotate if attaking rook is black
01957   if (rook_index0 < 0)
01958     return 0;
01959   int rook_index1 = indexKing(rook[1].square().squareForBlack(alt(KingOwner))); // rotate if defending rook is black
01960   if (rook_index1 < 0)
01961     return 0;  
01962   FixedCapacityVector<Square, 4> silver;
01963   for (int i=0; i<state.nthLimit<SILVER>(); ++i) {
01964     Piece p = state.nth<SILVER>(i);
01965     assert(p.isOnBoard());
01966     if (p.owner() == KingOwner)
01967       continue;
01968     silver.push_back(p.square().squareForBlack(KingOwner)); // rotate if silver is black
01969   }
01970   if (silver.size() != 2 || silver[0].x() == silver[1].x())
01971     return 0;
01972   int silver_index
01973     = indexSilver((silver[0].x() > silver[1].x()) ? silver[0] : silver[1]);
01974   int index = offset + (king_index*81+silver_index)*90;
01975   return table[index + rook_index0] * playerToMul(KingOwner)
01976     + table[index + 45 + rook_index1] * playerToMul(KingOwner);
01977 }
01978 
01979 
01980 
01981 
01982 template <osl::Player KingOwner>
01983 int osl::eval::ml::
01984 EnterKingDefense::evalOne(const NumEffectState &state)
01985 {
01986   Square king = state.kingSquare(KingOwner);
01987   if (king.y() < 4 || king.y() > 6) // target: [4,6]
01988     return 0;
01989   CArray2d<int, 2, 2> count = {{{ 0 }}};
01990   for (int x=std::max(1, king.x()-2); x<=std::min(9, king.x()+2); ++x) {
01991     for (int y=king.y()-2*playerToMul(KingOwner); 1; y-=playerToMul(KingOwner)) {
01992       const Piece p = state.pieceAt(Square(x, y));
01993       if (p.isEdge())
01994         break;
01995       if (p.isEmpty())
01996         continue;
01997       count[p.owner() == KingOwner][p.ptype() == PAWN]++;
01998     }
01999   }
02000   const int c = king.squareForBlack(KingOwner).y() - 4;
02001   return table[c*(std::min(7, count[0][0]))] * playerToMul(KingOwner)
02002     + table[c*(8 +std::min(7, count[0][1]))] * playerToMul(KingOwner)
02003     + table[c*(16+std::min(7, count[1][0]))] * playerToMul(KingOwner)
02004     + table[c*(24+std::min(7, count[1][1]))] * playerToMul(KingOwner);
02005 }
02006 
02007 int osl::eval::ml::
02008 EnterKingDefense::eval(const NumEffectState &state)
02009 {
02010   return evalOne<BLACK>(state) + evalOne<WHITE>(state);
02011 }
02012 
02013 osl::CArray<int, (8+8+8+8)*3> osl::eval::ml::EnterKingDefense::table;
02014 void osl::eval::ml::
02015 EnterKingDefense::setUp(const Weights & weights)
02016 {
02017   for (size_t i=0; i<weights.dimension(); ++i)
02018     table[i] = weights.value(i);
02019 }
02020 
02021 
02022 
02023 namespace osl
02024 {
02025   namespace eval
02026   {
02027     namespace ml
02028     {
02029       template MultiInt KingPieceRelative::
02030       evalWithUpdate<BLACK>(const NumEffectState &state,
02031                             Move moved, MultiInt const& last_value);
02032       template MultiInt KingPieceRelative::
02033       evalWithUpdate<WHITE>(const NumEffectState &state,
02034                             Move moved, MultiInt const& last_value);
02035 
02036       template class King25EffectEach<0>;
02037       template class King25EffectEach<1>;
02038       template class King25EffectEach<2>;
02039       template class King25EmptyAbs<true>;
02040       template class King25EmptyAbs<false>;
02041 
02042       template void King25EffectBoth::countEffectAndPiecesBoth<BLACK>(const NumEffectState&, PieceMask&, PieceMask&, int&, int&, int&, int&, int&, CArray<int, 5>&, CArray<int, 5>&);
02043       template void King25EffectBoth::countEffectAndPiecesBoth<WHITE>(const NumEffectState&, PieceMask&, PieceMask&, int&, int&, int&, int&, int&, CArray<int, 5>&, CArray<int, 5>&);
02044     }
02045   }
02046 }
02047 
02048 // ;;; Local Variables:
02049 // ;;; mode:c++
02050 // ;;; c-basic-offset:2
02051 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines