king8.cc
Go to the documentation of this file.
00001 #include "osl/eval/ml/king8.h"
00002 #include "osl/checkmate/king8Info.h"
00003 using osl::MultiInt;
00004 using osl::MultiIntPair;
00005 
00006 template <bool Opening>
00007 osl::misc::CArray<int, 32> osl::eval::ml::King8EffectEmptySquare<Opening>::table;
00008 template <bool Opening>
00009 osl::misc::CArray<int, 32> osl::eval::ml::King8EffectDefenseSquare<Opening>::table;
00010 
00011 osl::misc::CArray<int, 32> osl::eval::ml::King8Effect::empty_table;
00012 osl::misc::CArray<int, 32> osl::eval::ml::King8Effect::defense_table;
00013 osl::misc::CArray<int, 288> osl::eval::ml::King8Effect::empty_y_table;
00014 osl::misc::CArray<int, 288> osl::eval::ml::King8Effect::defense_y_table;
00015 
00016 void osl::eval::ml::
00017 King8Effect::setUp(const Weights &weights)
00018 {
00019   for (size_t i = 0; i < empty_table.size(); ++i)
00020   {
00021     empty_table[i] = weights.value(i);
00022   }
00023   for (size_t i = 0; i < defense_table.size(); ++i)
00024   {
00025     defense_table[i] = weights.value(i + empty_table.size());
00026   }
00027   for (size_t i = 0; i < empty_y_table.size(); ++i)
00028   {
00029     empty_y_table[i] = weights.value(i + empty_table.size() +
00030                                      defense_table.size());
00031   }
00032   for (size_t i = 0; i < defense_y_table.size(); ++i)
00033   {
00034     defense_y_table[i] = weights.value(i + empty_table.size() +
00035                                        defense_table.size() +
00036                                        empty_y_table.size());
00037   }
00038 }
00039 
00040 int osl::eval::ml::King8Effect::eval(
00041   const osl::state::NumEffectState &state)
00042 {
00043   int result = 0;
00044   const Piece black_king = state.kingPiece<BLACK>();
00045   const Piece white_king = state.kingPiece<WHITE>();
00046   for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00047   {
00048     const Direction dir = static_cast<Direction>(i);
00049     {
00050       EffectState empty, defense;
00051       effectState(state, BLACK, dir, empty, defense);
00052       if (empty != NOT_EMPTY)
00053       {
00054         result -= empty_table[index(dir, empty)];
00055         result -= empty_y_table[indexY(black_king, dir, empty)];
00056       }
00057       if (defense != NOT_EMPTY)
00058       {
00059         result -= defense_table[index(dir, defense)];
00060         result -= defense_y_table[indexY(black_king, dir, defense)];
00061       }
00062     }
00063     {
00064       EffectState empty, defense;
00065       effectState(state, WHITE, dir, empty, defense);
00066       if (empty != NOT_EMPTY)
00067       {
00068         result += empty_table[index(dir, empty)];
00069         result += empty_y_table[indexY(white_king, dir, empty)];
00070       }
00071       if (defense != NOT_EMPTY)
00072       {
00073         result += defense_table[index(dir, defense)];
00074         result += defense_y_table[indexY(white_king, dir, defense)];
00075       }
00076     }
00077   }
00078   return result;
00079 }
00080 
00081 int osl::eval::ml::
00082 King8Effect::index(const Direction dir,
00083                    EffectState state)
00084 {
00085   return (dir * 4 + state);
00086 }
00087 
00088 int osl::eval::ml::
00089 King8Effect::indexY(Piece king,
00090                     const Direction dir,
00091                     EffectState state)
00092 {
00093   const int y = ((king.owner() == BLACK) ?
00094                  king.square().y() : 10 - king.square().y());
00095   return (dir * 4 + state) * 9 + y - 1;
00096 }
00097 
00098 
00099 
00100 void osl::eval::ml::
00101 King8Effect::effectState(const NumEffectState &state,
00102                          const Player defenseP,
00103                          const Direction dir,
00104                          EffectState &empty,
00105                          EffectState &defense)
00106 {
00107   const Square target =
00108     Board_Table.nextSquare(defenseP,
00109                              state.kingSquare(defenseP),
00110                              dir);
00111   if (!state.pieceAt(target).isEmpty())
00112   {
00113     empty = defense = NOT_EMPTY;
00114     return;
00115   }
00116   const int attack_count = state.countEffect(alt(defenseP), target);
00117   const int defense_count = state.countEffect(defenseP, target);
00118   if (attack_count == 0)
00119   {
00120     empty = NO_EFFECT;
00121     defense = NO_EFFECT;
00122   }
00123   else if (defense_count == 1)
00124   {
00125     empty = MORE_EFFECT_KING_ONLY;
00126   }
00127   else if (attack_count >= defense_count)
00128   {
00129     empty = MORE_EFFECT;
00130   }
00131   else
00132   {
00133     empty = LESS_EFFECT;
00134   }
00135   if (defense_count == 1 && attack_count > defense_count)
00136   {
00137     defense = MORE_EFFECT_KING_ONLY;
00138   }
00139   else if (attack_count > defense_count)
00140   {
00141     defense = MORE_EFFECT;
00142   }
00143   else
00144   {
00145     defense = LESS_EFFECT;
00146   }
00147 }
00148 
00149 
00150 
00151 struct osl::eval::ml::King8EffectBase::
00152     MakeEffectStateSimple
00153 {
00154   EffectState operator()(const NumEffectState &state,
00155                          const Player defense,
00156                          const Direction dir) const
00157   {
00158     const Square target =
00159       Board_Table.nextSquare(defense,
00160                                state.kingSquare(defense),
00161                                dir);
00162     if (!state.pieceAt(target).isEmpty())
00163       return NOT_EMPTY;
00164         
00165     const int attack_count = state.countEffect(alt(defense), target);
00166     if (attack_count == 0)
00167       return NO_EFFECT;
00168     const int defense_count = state.countEffect(defense, target);
00169     if (defense_count == 1)
00170       return MORE_EFFECT_KING_ONLY;
00171     else if (attack_count >= defense_count)
00172       return MORE_EFFECT;
00173     else
00174       return LESS_EFFECT;
00175   }
00176 };
00177 
00178 struct osl::eval::ml::King8EffectBase::
00179     MakeEffectStateDefense
00180 {
00181   EffectState operator()(const NumEffectState &state,
00182                          const Player defense,
00183                          const Direction dir) const
00184   {
00185     const Square target =
00186       Board_Table.nextSquare(defense,
00187                                state.kingSquare(defense),
00188                                dir);
00189     if (!state.pieceAt(target).isOnBoardByOwner(defense))
00190       return NOT_EMPTY;
00191 
00192     const int attack_count = state.countEffect(alt(defense), target);
00193     if (attack_count == 0)
00194       return NO_EFFECT;
00195 
00196     const int defense_count = state.countEffect(defense, target);
00197     if (defense_count == 1 && attack_count > defense_count)
00198       return MORE_EFFECT_KING_ONLY;
00199     else if (attack_count > defense_count)
00200       return MORE_EFFECT;
00201     else
00202       return LESS_EFFECT;
00203   }
00204 };
00205 
00206 template <class MakeEffectState>
00207 const osl::CArray<int,2>
00208 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00209 __attribute__ ((used))
00210 #endif
00211  osl::eval::ml::
00212 King8EffectBase::evalCommon(const osl::state::NumEffectState &state, const table_t& table)
00213 {
00214   MakeEffectState f;
00215   CArray<int,2> result = {{0, 0}};
00216   for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00217   {
00218     const Direction dir = static_cast<Direction>(i);
00219     const EffectState black_effect_state = f(state, BLACK, dir);
00220     if (black_effect_state != NOT_EMPTY)
00221     {
00222       result[0] -= table[index(dir, black_effect_state)];
00223     }
00224     const EffectState white_effect_state = f(state, WHITE, dir);
00225     if (white_effect_state != NOT_EMPTY)
00226     {
00227       result[1] += table[index(dir, white_effect_state)];
00228     }
00229   }
00230 
00231   return result;
00232 }
00233 
00234 template <class MakeEffectState>
00235 const osl::CArray<int,2>
00236 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00237 __attribute__ ((used))
00238 #endif
00239  osl::eval::ml::
00240 King8EffectBase::evalWithUpdateCommon(const osl::state::NumEffectState &new_state, Move last_move, 
00241                                       const CArray<int,2>& last_value, const table_t& table)
00242 {
00243   CArray<int,2> result = last_value;
00244   MakeEffectState f;
00245   BoardMask mask = new_state.changedEffects();
00246   mask.set(last_move.to()); mask.set(last_move.from());
00247   for (int z=0; z<2; ++z) 
00248   {
00249     const Player pl = indexToPlayer(z);
00250     const Square king = new_state.kingSquare(pl);
00251     bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
00252     if (! update) 
00253       continue;
00254     result[z] = 0;
00255     for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00256     {
00257       const Direction dir = static_cast<Direction>(i);
00258       const EffectState effect_state = f(new_state, pl, dir);
00259       if (effect_state != NOT_EMPTY)
00260       {
00261         result[z] -= table[index(dir, effect_state)];
00262       }
00263     }
00264     if (z == 1)
00265       result[1] = -result[1];
00266   }
00267   return result;
00268 }
00269 
00270 template <class MakeEffectState>
00271 inline
00272 std::pair<osl::CArray<int,2>, osl::CArray<int,2> > osl::eval::ml::
00273 King8EffectBase::evalWithUpdateCommon(const osl::state::NumEffectState &new_state, Move last_move, 
00274                                       const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e, 
00275                                       const table_t& table_o, const table_t& table_e)
00276 {
00277   CArray<int,2> result_o = last_value_o, result_e = last_value_e;
00278   MakeEffectState f;
00279   BoardMask mask = new_state.changedEffects();
00280   mask.set(last_move.to()); mask.set(last_move.from());
00281   for (int z=0; z<2; ++z) 
00282   {
00283     const Player pl = indexToPlayer(z);
00284     const Square king = new_state.kingSquare(pl);
00285     bool update = mask.anyInRange(Board_Mask_Table3x3.mask(king));
00286     if (! update) 
00287       continue;
00288     result_o[z] = result_e[z] = 0;
00289     for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00290     {
00291       const Direction dir = static_cast<Direction>(i);
00292       const EffectState effect_state = f(new_state, pl, dir);
00293       if (effect_state != NOT_EMPTY)
00294       {
00295         result_o[z] -= table_o[index(dir, effect_state)];
00296         result_e[z] -= table_e[index(dir, effect_state)];
00297       }
00298     }
00299     if (z == 1) 
00300     {
00301       result_o[1] = -result_o[1];
00302       result_e[1] = -result_e[1];
00303     }
00304   }
00305   return std::make_pair(result_o, result_e);
00306 }
00307 
00308 template <bool Opening>
00309 void osl::eval::ml::
00310 King8EffectEmptySquare<Opening>::setUp(const Weights &weights)
00311 {
00312   table.fill(0);
00313   for (size_t i = 0; i < weights.dimension(); ++i)
00314   {
00315     table[i] = weights.value(i);
00316   }
00317 }
00318 
00319 template <bool Opening>
00320 const osl::CArray<int,2> osl::eval::ml::
00321 King8EffectEmptySquare<Opening>::eval(const osl::state::NumEffectState &state)
00322 {
00323   return evalCommon<MakeEffectStateSimple>(state, table);
00324 }
00325 template <bool Opening>
00326 const osl::CArray<int,2> osl::eval::ml::
00327 King8EffectEmptySquare<Opening>::evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move, 
00328                                           const CArray<int,2>& last_value)
00329 {
00330   return evalWithUpdateCommon<MakeEffectStateSimple>
00331     (new_state, last_move, last_value, table);
00332 }
00333 
00334 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
00335 osl::eval::ml::King8EffectEmptySquareBoth::
00336 evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move, 
00337                const CArray<int,2>& last_value_opening,
00338                const CArray<int,2>& last_value_ending)
00339 {
00340   return evalWithUpdateCommon<MakeEffectStateSimple>
00341     (new_state, last_move, last_value_opening, last_value_ending, 
00342      King8EffectEmptySquare<true>::table, King8EffectEmptySquare<false>::table);
00343 }       
00344 
00345 
00346 template <bool Opening>
00347 void osl::eval::ml::
00348 King8EffectDefenseSquare<Opening>::setUp(const Weights &weights)
00349 {
00350   table.fill(0);
00351   for (size_t i = 0; i < weights.dimension(); ++i)
00352   {
00353     table[i] = weights.value(i);
00354   }
00355 }
00356 template <bool Opening>
00357 const osl::CArray<int,2> osl::eval::ml::
00358 King8EffectDefenseSquare<Opening>::eval(const osl::state::NumEffectState &state)
00359 {
00360   return evalCommon<MakeEffectStateDefense>(state, table);
00361 }
00362 template <bool Opening>
00363 const osl::CArray<int,2> osl::eval::ml::
00364 King8EffectDefenseSquare<Opening>::evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move, 
00365                                           const CArray<int,2>& last_value)
00366 {
00367   return evalWithUpdateCommon<MakeEffectStateDefense>
00368     (new_state, last_move, last_value, table);
00369 }
00370 
00371 
00372 std::pair<osl::CArray<int,2>, osl::CArray<int,2> >
00373 osl::eval::ml::King8EffectDefenseSquareBoth::
00374 evalWithUpdate(const osl::state::NumEffectState &new_state, Move last_move, 
00375                const CArray<int,2>& last_value_opening,
00376                const CArray<int,2>& last_value_ending)
00377 {
00378   return evalWithUpdateCommon<MakeEffectStateDefense>
00379     (new_state, last_move, last_value_opening, last_value_ending, 
00380      King8EffectDefenseSquare<true>::table, King8EffectDefenseSquare<false>::table);
00381 }       
00382 
00383 
00384 
00385 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00386 osl::eval::ml::King8EffectAll::base_table;
00387 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00388 osl::eval::ml::King8EffectAll::u_table;
00389 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00390 osl::eval::ml::King8EffectAll::d_table;
00391 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00392 osl::eval::ml::King8EffectAll::l_table;
00393 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00394 osl::eval::ml::King8EffectAll::r_table;
00395 
00396 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00397 osl::eval::ml::King8EffectAll::base_defense_piece_table;
00398 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00399 osl::eval::ml::King8EffectAll::u_defense_piece_table;
00400 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00401 osl::eval::ml::King8EffectAll::d_defense_piece_table;
00402 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00403 osl::eval::ml::King8EffectAll::l_defense_piece_table;
00404 osl::misc::CArray<int, osl::eval::ml::King8EffectAll::ONE_DIM>
00405 osl::eval::ml::King8EffectAll::r_defense_piece_table;
00406 
00407 void osl::eval::ml::
00408 King8EffectAll::setUp(const Weights &weights)
00409 {
00410   base_table.fill(0);
00411   u_table.fill(0);
00412   d_table.fill(0);
00413   l_table.fill(0);
00414   r_table.fill(0);
00415   base_defense_piece_table.fill(0);
00416   u_defense_piece_table.fill(0);
00417   d_defense_piece_table.fill(0);
00418   l_defense_piece_table.fill(0);
00419   r_defense_piece_table.fill(0);
00420   for (size_t i = 0; i < ONE_DIM; ++i)
00421   {
00422     base_table[i] = weights.value(i);
00423     u_table[i] = weights.value(i+ONE_DIM);
00424     d_table[i] = weights.value(i+ONE_DIM*2);
00425     l_table[i] = weights.value(i+ONE_DIM*3);
00426     r_table[i] = weights.value(i+ONE_DIM*4);
00427     base_defense_piece_table[i] = weights.value(i+ONE_DIM*5);
00428     u_defense_piece_table[i] = weights.value(i+ONE_DIM*6);
00429     d_defense_piece_table[i] = weights.value(i+ONE_DIM*7);
00430     l_defense_piece_table[i] = weights.value(i+ONE_DIM*8);
00431     r_defense_piece_table[i] = weights.value(i+ONE_DIM*9);
00432   }
00433 }
00434 
00435 void
00436 osl::eval::ml::King8EffectAll::effectState(
00437   const NumEffectState &state,
00438   const Player defense,
00439   const Direction dir,
00440   EffectState &empty, EffectState &defense_effect)
00441 {
00442   empty = NOT_EMPTY;
00443   defense_effect = NOT_EMPTY;
00444   const Square target =
00445     Board_Table.nextSquare(defense,
00446                              state.kingSquare(defense),
00447                              dir);
00448   const Piece piece = state.pieceAt(target);
00449   if (!target.isOnBoard() ||
00450       piece.isOnBoardByOwner(alt(defense)))
00451     return;
00452 
00453   const int attack_count = state.countEffect(alt(defense), target);
00454   const int defense_count = state.countEffect(defense, target);
00455 
00456   if (piece.isEmpty())
00457   {
00458     if (attack_count == 0)
00459       empty = NO_EFFECT;
00460     else if (defense_count == 1)
00461       empty = MORE_EFFECT_KING_ONLY;
00462     else if (attack_count >= defense_count)
00463       empty = MORE_EFFECT;
00464     else
00465       empty = LESS_EFFECT;
00466   }
00467   else
00468   {
00469     if (attack_count == 0)
00470       defense_effect = NO_EFFECT;
00471     else if (defense_count == 1 && attack_count > defense_count)
00472       defense_effect = MORE_EFFECT_KING_ONLY;
00473     else if (attack_count > defense_count)
00474       defense_effect = MORE_EFFECT;
00475     else
00476       defense_effect = LESS_EFFECT;
00477   }
00478 }
00479 
00480 int osl::eval::ml::
00481 King8EffectAll::index(const Direction dir, EffectState state)
00482 {
00483   return dir * 4 + state;
00484 }
00485 
00486 int osl::eval::ml::
00487 King8EffectAll::eval(const osl::state::NumEffectState &state,
00488                      PieceMask /*black_mask*/, PieceMask /*white_mask*/)
00489 {
00490   int result = 0;
00491   osl::checkmate::King8Info black_king(state.Iking8Info(BLACK));
00492   const int black_liberty = black_king.liberty();
00493   const bool black_u_blocked =
00494     (black_liberty & ((DirectionTraits<UL>::mask |
00495                        DirectionTraits<U>::mask |
00496                        DirectionTraits<UR>::mask))) == 0;
00497   const bool black_d_blocked =
00498     (black_liberty & ((DirectionTraits<DL>::mask |
00499                        DirectionTraits<D>::mask |
00500                        DirectionTraits<DR>::mask))) == 0;
00501   const bool black_l_blocked =
00502     (black_liberty & ((DirectionTraits<UL>::mask |
00503                        DirectionTraits<L>::mask |
00504                        DirectionTraits<DL>::mask))) == 0;
00505   const bool black_r_blocked =
00506     (black_liberty & ((DirectionTraits<UR>::mask |
00507                        DirectionTraits<R>::mask |
00508                        DirectionTraits<DR>::mask))) == 0;
00509   osl::checkmate::King8Info white_king(state.Iking8Info(WHITE));
00510   const int white_liberty = white_king.liberty();
00511   const bool white_u_blocked =
00512     (white_liberty & ((DirectionTraits<UL>::mask |
00513                        DirectionTraits<U>::mask |
00514                        DirectionTraits<UR>::mask))) == 0;
00515   const bool white_d_blocked =
00516     (white_liberty & ((DirectionTraits<DL>::mask |
00517                        DirectionTraits<D>::mask |
00518                        DirectionTraits<DR>::mask))) == 0;
00519   const bool white_l_blocked =
00520     (white_liberty & ((DirectionTraits<UL>::mask |
00521                        DirectionTraits<L>::mask |
00522                        DirectionTraits<DL>::mask))) == 0;
00523   const bool white_r_blocked =
00524     (white_liberty & ((DirectionTraits<UR>::mask |
00525                        DirectionTraits<R>::mask |
00526                        DirectionTraits<DR>::mask))) == 0;
00527 
00528   for (int i = SHORT8_DIRECTION_MIN; i <= SHORT8_DIRECTION_MAX; ++i)
00529   {
00530     const Direction dir = static_cast<Direction>(i);
00531     EffectState black_empty_effect_state,
00532       black_defense_effect_state;
00533     effectState(state, BLACK, dir,
00534                 black_empty_effect_state, black_defense_effect_state);
00535     if (black_empty_effect_state != NOT_EMPTY)
00536     {
00537       const int idx = index(dir, black_empty_effect_state);
00538       result -= base_table[idx];
00539       if (black_u_blocked)
00540         result -= u_table[idx];
00541       if (black_d_blocked)
00542         result -= d_table[idx];
00543       if (black_l_blocked)
00544         result -= l_table[idx];
00545       if (black_r_blocked)
00546         result -= r_table[idx];
00547     }
00548     if (black_defense_effect_state != NOT_EMPTY)
00549     {
00550       const int idx = index(dir, black_defense_effect_state);
00551       result -= base_defense_piece_table[idx];
00552       if (black_u_blocked)
00553         result -= u_defense_piece_table[idx];
00554       if (black_d_blocked)
00555         result -= d_defense_piece_table[idx];
00556       if (black_l_blocked)
00557         result -= l_defense_piece_table[idx];
00558       if (black_r_blocked)
00559         result -= r_defense_piece_table[idx];
00560     }
00561     EffectState white_empty_effect_state,
00562       white_defense_effect_state;
00563     effectState(state, WHITE, dir,
00564                 white_empty_effect_state, white_defense_effect_state);
00565     if (white_empty_effect_state != NOT_EMPTY)
00566     {
00567       const int idx = index(dir, white_empty_effect_state);
00568       result += base_table[idx];
00569       if (white_u_blocked)
00570         result += u_table[idx];
00571       if (white_d_blocked)
00572         result += d_table[idx];
00573       if (white_l_blocked)
00574         result += l_table[idx];
00575       if (white_r_blocked)
00576         result += r_table[idx];
00577     }
00578     if (white_defense_effect_state != NOT_EMPTY)
00579     {
00580       const int idx = index(dir, white_defense_effect_state);
00581       result += base_defense_piece_table[idx];
00582       if (white_u_blocked)
00583         result += u_defense_piece_table[idx];
00584       if (white_d_blocked)
00585         result += d_defense_piece_table[idx];
00586       if (white_l_blocked)
00587         result += l_defense_piece_table[idx];
00588       if (white_r_blocked)
00589         result += r_defense_piece_table[idx];
00590     }
00591   }
00592 
00593   return result;
00594 }
00595 
00596 
00597 osl::misc::CArray<MultiInt, osl::eval::ml::KingXBothBlocked::ONE_DIM>
00598 osl::eval::ml::KingXBothBlocked::table;
00599 osl::misc::CArray<MultiInt, osl::eval::ml::KingXBothBlockedY::ONE_DIM>
00600 osl::eval::ml::KingXBothBlockedY::table;
00601 
00602 void osl::eval::ml::
00603 KingXBothBlocked::setUp(const Weights &weights)
00604 {
00605   for (int i = 0; i < ONE_DIM; ++i)
00606   {
00607     for (int s=0; s<NStages; ++s)
00608       table[i][s] = weights.value(i + ONE_DIM*s);
00609   }
00610 }
00611 
00612 void osl::eval::ml::
00613 KingXBothBlockedY::setUp(const Weights &weights)
00614 {
00615   for (int i = 0; i < ONE_DIM; ++i)
00616   {
00617     for (int s=0; s<NStages; ++s)
00618       table[i][s] = weights.value(i + ONE_DIM*s);
00619   }
00620 }
00621 
00622 template <int Sign>
00623 inline
00624 void osl::eval::ml::
00625 KingXBothBlocked::adjust(int index, int index_y, MultiInt &out)
00626 {
00627   if(Sign>0)
00628     out += KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
00629   else
00630     out -= KingXBothBlocked::table[index] +KingXBothBlockedY::table[index_y];
00631 }
00632 
00633 MultiIntPair osl::eval::ml::
00634 KingXBothBlocked::eval(const NumEffectState &state)
00635 {
00636   MultiIntPair result;
00637   King8Info black(state.Iking8Info(BLACK));
00638   if ((black.liberty() & (DirectionTraits<UL>::mask |
00639                           DirectionTraits<L>::mask |
00640                           DirectionTraits<DL>::mask |
00641                           DirectionTraits<UR>::mask |
00642                           DirectionTraits<R>::mask |
00643                           DirectionTraits<DR>::mask)) == 0)
00644   {
00645     const Square black_king = state.kingSquare<BLACK>();
00646     adjust<1>(index(black_king),
00647               indexY<BLACK>(black_king),
00648               result[BLACK]);
00649   }
00650 
00651   King8Info white(state.Iking8Info(WHITE));
00652   if ((white.liberty() & (DirectionTraits<UL>::mask |
00653                           DirectionTraits<L>::mask |
00654                           DirectionTraits<DL>::mask |
00655                           DirectionTraits<UR>::mask |
00656                           DirectionTraits<R>::mask |
00657                           DirectionTraits<DR>::mask)) == 0)
00658   {
00659     const Square white_king = state.kingSquare<WHITE>();
00660     adjust<-1>(index(white_king),
00661                indexY<WHITE>(white_king),
00662                result[WHITE]);
00663   }
00664 
00665   return result;
00666 }
00667 
00668 template <osl::Player P>
00669 int osl::eval::ml::KingXBlockedBase::index(
00670   Square king, int diff)
00671 {
00672   const int king_x = king.x();
00673   if (P == BLACK)
00674   {
00675     const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00676     int x_diff = diff;
00677     if (king_x >= 6)
00678       x_diff = -x_diff;
00679     return target_x - 1 + ((x_diff == 1) ? 0 : 5);
00680   }
00681   else
00682   {
00683     const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00684     int x_diff = diff;
00685     if (king_x >= 5)
00686       x_diff = -x_diff;
00687     return target_x - 1 + ((x_diff == 1) ? 0 : 5);
00688   }
00689 }
00690 
00691 template <osl::Player P>
00692 bool osl::eval::ml::KingXBlockedBase::isBlocked(
00693   const NumEffectState &state,
00694   int diff)
00695 {
00696 #if 1
00697   const King8Info info(state.Iking8Info(P));
00698   if ((diff == 1) ^ (P == BLACK))
00699     return (info.liberty() & (DirectionTraits<UR>::mask 
00700                               | DirectionTraits<R>::mask 
00701                               | DirectionTraits<DR>::mask)) == 0;
00702   assert((diff == 1 && P == BLACK) || (diff == -1 && P == WHITE));
00703   return (info.liberty() & (DirectionTraits<UL>::mask 
00704                             | DirectionTraits<L>::mask 
00705                             | DirectionTraits<DL>::mask)) == 0;
00706 #else
00707   const Square pos = state.kingSquare<P>();
00708   const int target_x = pos.x() + diff;
00709   for (int y = pos.y() - 1; y <= pos.y() + 1; ++y)
00710   {
00711     Square target(target_x, y);
00712     Piece p(state.pieceAt(target));
00713     if ((!p.isEdge()) && ! p.isOnBoardByOwner<P>() &&
00714         !state.hasEffectAt<PlayerTraits<P>::opponent>(target))
00715     {
00716       return false;
00717     }
00718   }
00719   return true;
00720 #endif
00721 }
00722 
00723 const MultiIntPair osl::eval::ml::
00724 KingXBlockedBase::eval(const osl::state::NumEffectState &state, const table_t& table)
00725 {
00726   MultiIntPair val;
00727   const Square black_king = state.kingSquare<BLACK>();
00728   const Square white_king = state.kingSquare<WHITE>();
00729   const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
00730   if (isBlocked<BLACK>(state, 1))
00731     val[b] += table[index<BLACK>(black_king, 1)];
00732   if (isBlocked<BLACK>(state, -1))
00733     val[b] += table[index<BLACK>(black_king, -1)];
00734 
00735   if (isBlocked<WHITE>(state, 1))
00736     val[w] -= table[index<WHITE>(white_king, 1)];
00737   if (isBlocked<WHITE>(state, -1))
00738     val[w] -= table[index<WHITE>(white_king, -1)];
00739   return val;
00740 }
00741 
00742 const MultiIntPair osl::eval::ml::
00743 KingXBlockedYBase::eval(const osl::state::NumEffectState &state,
00744                         const table_t& table)
00745 {
00746   MultiIntPair val;
00747   const Square black_king = state.kingSquare<BLACK>();
00748   const Square white_king = state.kingSquare<WHITE>();
00749   const int b = playerToIndex(BLACK), w = playerToIndex(WHITE);
00750   const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(state, 1);
00751   const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(state, -1);
00752   if (black_r_blocked)
00753     val[b] += table[index<BLACK>(black_king, 1)];
00754   if (black_l_blocked)
00755     val[b] += table[index<BLACK>(black_king, -1)];
00756 
00757   const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(state, 1);
00758   const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(state, -1);
00759   if (white_r_blocked)
00760     val[w] -= table[index<WHITE>(white_king, 1)];
00761   if (white_l_blocked)
00762     val[w] -= table[index<WHITE>(white_king, -1)];
00763   return val;
00764 }
00765 
00766 #if 0
00767 inline
00768 std::pair<osl::CArray<int,2>,osl::CArray<int,2> > 
00769 osl::eval::ml::
00770 KingXBlockedBase::evalWithUpdate(const NumEffectState &new_state, Move last_move,
00771                                  const CArray<int,2>& last_value_o, const CArray<int,2>& last_value_e,
00772                                  const table_t& table_o, const table_t& table_e)
00773 {
00774   CArray<int,2> val_o = last_value_o;
00775   CArray<int,2> val_e = last_value_e;
00776   const Square black_king = new_state.kingSquare<BLACK>();
00777   const Square white_king = new_state.kingSquare<WHITE>();
00778   BoardMask mask = new_state.changedEffects();
00779   mask.set(last_move.from()); mask.set(last_move.to());
00780   if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king))) 
00781   {
00782     const int b = playerToIndex(BLACK);
00783     val_o[b] = val_e[b]= 0;
00784     if (isBlocked<BLACK>(new_state, 1)) {
00785       val_o[b] += table_o[index<BLACK>(black_king, 1)];
00786       val_e[b] += table_e[index<BLACK>(black_king, 1)];
00787     }
00788     if (isBlocked<BLACK>(new_state, -1)) {
00789       val_o[b] += table_o[index<BLACK>(black_king, -1)];
00790       val_e[b] += table_e[index<BLACK>(black_king, -1)];
00791     }
00792   }
00793   if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
00794   {
00795     const int w = playerToIndex(WHITE);
00796     val_o[w] = val_e[w]= 0;
00797     if (isBlocked<WHITE>(new_state, 1)) {
00798       val_o[w] -= table_o[index<WHITE>(white_king, 1)];
00799       val_e[w] -= table_e[index<WHITE>(white_king, 1)];
00800     }
00801     if (isBlocked<WHITE>(new_state, -1)) {
00802       val_o[w] -= table_o[index<WHITE>(white_king, -1)];
00803       val_e[w] -= table_e[index<WHITE>(white_king, -1)];
00804     }
00805   }
00806   return std::make_pair(val_o, val_e);
00807 }
00808 #endif
00809 
00810 template <int Sign>
00811 inline
00812 void osl::eval::ml::
00813 KingXBlockedYBase::adjust(int index, int index_y, MultiInt &out)
00814 {
00815   if(Sign>0)
00816     out += KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
00817   else
00818     out -= KingXBlocked::table[index]+ KingXBlockedY::table[index_y];
00819 }
00820 
00821 inline
00822 void
00823 osl::eval::ml::
00824 KingXBlockedYBase::evalWithUpdateBang(const NumEffectState &new_state,
00825                                       Move last_move,
00826                                       MultiIntPair& values)
00827 {
00828   const Square black_king = new_state.kingSquare<BLACK>();
00829   const Square white_king = new_state.kingSquare<WHITE>();
00830   BoardMask mask = new_state.changedEffects();
00831   mask.set(last_move.from()); mask.set(last_move.to());
00832   if (mask.anyInRange(Board_Mask_Table3x3.mask(black_king))) 
00833   {
00834     values[BLACK].clear();
00835     const bool black_r_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, 1);
00836     const bool black_l_blocked = KingXBlockedBase::isBlocked<BLACK>(new_state, -1);
00837     if (black_r_blocked) {
00838       adjust<1>(KingXBlockedBase::index<BLACK>(black_king, 1),
00839                 index<BLACK>(black_king, 1),
00840                 values[BLACK]);
00841     }
00842     if (black_l_blocked) {
00843       adjust<1>(KingXBlockedBase::index<BLACK>(black_king, -1),
00844                 index<BLACK>(black_king, -1),
00845                 values[BLACK]);
00846     }
00847     if (black_r_blocked && black_l_blocked)
00848     {
00849       KingXBothBlocked::adjust<1>(KingXBothBlocked::index(black_king),
00850                                   KingXBothBlocked::indexY<BLACK>(black_king),
00851                                   values[BLACK]);
00852     }
00853   }
00854   if (mask.anyInRange(Board_Mask_Table3x3.mask(white_king)))
00855   {
00856     values[WHITE].clear();
00857     const bool white_r_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, 1);
00858     const bool white_l_blocked = KingXBlockedBase::isBlocked<WHITE>(new_state, -1);
00859     if (white_r_blocked) {
00860       adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, 1),
00861                  index<WHITE>(white_king, 1),
00862                  values[WHITE]);
00863     }
00864     if (white_l_blocked) {
00865       adjust<-1>(KingXBlockedBase::index<WHITE>(white_king, -1),
00866                  index<WHITE>(white_king, -1),
00867                  values[WHITE]);
00868     }
00869     if (white_r_blocked && white_l_blocked)
00870     {
00871       KingXBothBlocked::adjust<-1>(KingXBothBlocked::index(white_king),
00872                                   KingXBothBlocked::indexY<WHITE>(white_king),
00873                                   values[WHITE]);
00874     }
00875   }
00876 }
00877 
00878 template <osl::Player P> inline
00879 int osl::eval::ml::KingXBlockedYBase::index(
00880   Square king, int diff)
00881 {
00882   const int king_x = king.x();
00883   if (P == BLACK)
00884   {
00885     const int king_y = king.y();
00886     const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00887     int x_diff = diff;
00888     if (king_x >= 6)
00889       x_diff = -x_diff;
00890     return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
00891   }
00892   else
00893   {
00894     const int king_y = 10 - king.y();
00895     const int target_x = (king_x > 5) ? 10 - king_x : king_x;
00896     int x_diff = diff;
00897     if (king_x >= 5)
00898       x_diff = -x_diff;
00899     return (target_x - 1 + ((x_diff == 1) ? 0 : 5)) * 9 + king_y - 1;
00900   }
00901 }
00902 
00903 osl::misc::CArray<MultiInt, 10> osl::eval::ml::KingXBlocked::table;
00904 osl::misc::CArray<MultiInt, 90> osl::eval::ml::KingXBlockedY::table;
00905 
00906 void osl::eval::ml::
00907 KingXBlocked::setUp(const Weights &weights,int stage)
00908 {
00909   for (size_t i = 0; i < table.size(); ++i)
00910   {
00911     table[i][stage] = weights.value(i);
00912   }
00913 }
00914 void
00915 osl::eval::ml::
00916 KingXBlockedBoth::evalWithUpdateBang(const NumEffectState &new_state, Move last_move,
00917                                      MultiIntPair& last_values)
00918 {
00919   KingXBlockedYBase::evalWithUpdateBang
00920     (new_state, last_move, last_values);
00921 }
00922 
00923 void osl::eval::ml::
00924 KingXBlockedY::setUp(const Weights &weights,int stage)
00925 {
00926   for (size_t i = 0; i < table.size(); ++i)
00927   {
00928     table[i][stage] = weights.value(i);
00929   }
00930 }
00931 
00932 
00933 osl::misc::CArray<MultiInt, 80> osl::eval::ml::KingXBlocked3::table;
00934 osl::misc::CArray<MultiInt, 720> osl::eval::ml::KingXBlocked3::y_table;
00935 
00936 void osl::eval::ml::KingXBlocked3::setUp(const Weights &weights)
00937 {
00938   for (int i = 0; i < ONE_DIM; ++i)
00939   {
00940     for (int s=0; s<NStages; ++s)
00941       table[i][s] = weights.value(i + ONE_DIM*s);
00942   }
00943 }
00944 
00945 void osl::eval::ml::KingXBlocked3Y::setUp(const Weights &weights)
00946 {
00947   for (int i = 0; i < ONE_DIM; ++i)
00948   {
00949     for (int s=0; s<NStages; ++s)
00950       KingXBlocked3::y_table[i][s] = weights.value(i + ONE_DIM*s);
00951   }
00952   for(int x=1;x<=5;x++)
00953     for(int y=1;y<=9;y++)
00954       for(int is_l=0;is_l<2;is_l++)
00955         for(int u_blocked=0;u_blocked<2;u_blocked++)
00956           for(int opp_u_blocked=0;opp_u_blocked<2;opp_u_blocked++)
00957             for(int opp_blocked=0;opp_blocked<2;opp_blocked++){
00958               int indexY=x - 1 + 5 * (y - 1 + 9 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1  : 0) + 2 * (opp_blocked ? 1 : 0)))));
00959               int index0=x - 1 + 5 * ((is_l ? 1 : 0) + 2 * ((u_blocked ? 1 : 0) + 2 * ((opp_u_blocked ? 1  : 0) + 2 * (opp_blocked ? 1 : 0))));
00960               KingXBlocked3::y_table[indexY]+=KingXBlocked3::table[index0];
00961             }
00962 }
00963 
00964 MultiInt osl::eval::ml::
00965 KingXBlocked3::eval(const NumEffectState &state)
00966 {
00967   MultiInt result;
00968   King8Info black(state.Iking8Info(BLACK));
00969   if ((black.liberty() & (DirectionTraits<UL>::mask |
00970                           DirectionTraits<L>::mask |
00971                           DirectionTraits<DL>::mask)) == 0) 
00972   {
00973     adjust<1>(
00974       indexY<BLACK>(state.kingSquare<BLACK>(),
00975                     true,
00976                     (black.liberty() & DirectionTraits<U>::mask) == 0,
00977                     (black.liberty() & DirectionTraits<UR>::mask) == 0,
00978                     (black.liberty() & DirectionTraits<R>::mask) == 0),
00979       result);
00980   }
00981   if ((black.liberty() & (DirectionTraits<UR>::mask |
00982                           DirectionTraits<R>::mask |
00983                           DirectionTraits<DR>::mask)) == 0)
00984   {
00985     adjust<1>(
00986       indexY<BLACK>(state.kingSquare<BLACK>(),
00987                     false,
00988                     (black.liberty() & DirectionTraits<U>::mask) == 0,
00989                     (black.liberty() & DirectionTraits<UL>::mask) == 0,
00990                     (black.liberty() & DirectionTraits<L>::mask) == 0),
00991       result);
00992   }
00993   King8Info white(state.Iking8Info(WHITE));
00994   if ((white.liberty() & (DirectionTraits<UL>::mask |
00995                           DirectionTraits<L>::mask |
00996                           DirectionTraits<DL>::mask)) == 0)
00997   {
00998     adjust<-1>(
00999       indexY<WHITE>(state.kingSquare<WHITE>(),
01000                     true,
01001                     (white.liberty() & DirectionTraits<U>::mask) == 0,
01002                     (white.liberty() & DirectionTraits<UR>::mask) == 0,
01003                     (white.liberty() & DirectionTraits<R>::mask) == 0),
01004       result);
01005   }
01006   if ((white.liberty() & (DirectionTraits<UR>::mask |
01007                           DirectionTraits<R>::mask |
01008                           DirectionTraits<DR>::mask)) == 0)
01009   {
01010     adjust<-1>(
01011       indexY<WHITE>(state.kingSquare<WHITE>(),
01012                     false,
01013                     (white.liberty() & DirectionTraits<U>::mask) == 0,
01014                     (white.liberty() & DirectionTraits<UL>::mask) == 0,
01015                     (white.liberty() & DirectionTraits<L>::mask) == 0),
01016       result);
01017   }
01018   return result;
01019 }
01020 
01021 
01022 
01023 osl::misc::CArray<MultiInt, 4> osl::eval::ml::AnagumaEmpty::table;
01024 
01025 
01026 void osl::eval::ml::
01027 AnagumaEmpty::setUp(const Weights &weights,int stage)
01028 {
01029   for (size_t i = 0; i < table.size(); ++i)
01030   {
01031     table[i][stage] = weights.value(i);
01032   }
01033 }
01034 
01035 
01036 int osl::eval::ml::AnagumaEmpty::index(
01037   Square king, Square target)
01038 {
01039   return std::abs(king.x() - target.x()) + std::abs(king.y() - target.y()) * 2;
01040 }
01041 
01042 template <osl::Player Defense>
01043 MultiInt osl::eval::ml::AnagumaEmpty::evalOne(const NumEffectState &state)
01044 {
01045   MultiInt result;
01046   const Square king = state.kingSquare<Defense>();
01047   if ((king.x() == 1 || king.x() == 9) &&
01048       ((Defense == BLACK && king.y() == 9) ||
01049        (Defense == WHITE && king.y() == 1))){
01050     const int x = (king.x() == 1 ? 2 : 8);
01051     const int y = (Defense == BLACK ? 8 : 2);
01052     if(Defense==BLACK){
01053       if (state.pieceAt(Square(king.x(), y)).isEmpty())
01054         result +=table[index(king, Square(king.x(), y))];
01055       if (state.pieceAt(Square(x, y)).isEmpty())
01056         result +=table[index(king, Square(x, y))];
01057       if (state.pieceAt(Square(x, king.y())).isEmpty())
01058         result +=table[index(king, Square(x, king.y()))];
01059     }
01060     else{
01061       if (state.pieceAt(Square(king.x(), y)).isEmpty())
01062         result -=table[index(king, Square(king.x(), y))];
01063       if (state.pieceAt(Square(x, y)).isEmpty())
01064         result -=table[index(king, Square(x, y))];
01065       if (state.pieceAt(Square(x, king.y())).isEmpty())
01066         result -=table[index(king, Square(x, king.y()))];
01067     }
01068   }
01069   return result;
01070 }
01071 
01072 MultiInt osl::eval::ml::
01073 AnagumaEmpty::eval(const osl::state::NumEffectState &state)
01074 {
01075   return evalOne<BLACK>(state) + evalOne<WHITE>(state);
01076 }
01077 
01078 
01079 
01080 namespace osl
01081 {
01082   namespace eval
01083   {
01084     namespace ml
01085     {
01086       template class King8EffectEmptySquare<true>;
01087       template class King8EffectEmptySquare<false>;
01088       template class King8EffectDefenseSquare<true>;
01089       template class King8EffectDefenseSquare<false>;
01090     }
01091   }
01092 }
01093 // ;;; Local Variables:
01094 // ;;; mode:c++
01095 // ;;; c-basic-offset:2
01096 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines