see.cc
Go to the documentation of this file.
00001 /* see.cc
00002  */
00003 #include "osl/eval/see.h"
00004 #include "osl/eval/pieceEval.h"
00005 #include "osl/effect_action/storePtypeOSquare.h"
00006 
00007 struct osl::eval::See::FindEffectMore
00008 {
00009   PtypeOSquareVector *direct;
00010   PtypeOSquareVector *more;
00011   Square target;
00012   const NumEffectState *state;
00013   
00014   template<Player P,Ptype Type>
00015   void doActionPtype(Piece p) { store(p); }
00016   template<Player P>
00017   void doAction(Piece p, Square) { store(p);}
00018   void store(Piece p);  
00019 };
00020 
00021 void osl::eval::See::
00022 FindEffectMore::store(Piece p)
00023 {
00024   direct->push_back(std::make_pair(p.ptypeO(), p.square()));
00025   findAdditionalPieces(*state, p.owner(), target, p.square(), *more);
00026 }
00027 
00028 template <osl::Player P>
00029 void osl::eval::
00030 See::findEffectPieces(const NumEffectState& state, Square effect_to,
00031                       const PieceMask& /*my_pin*/, const PieceMask& op_pin,
00032                       PtypeOSquareVector& my_pieces, 
00033                       PtypeOSquareVector& op_pieces)
00034 {
00035   typedef effect_action::StorePtypeOSquare store_t;
00036   store_t op_pieces_store(&op_pieces, effect_to);
00037   state.forEachEffect<PlayerTraits<P>::opponent,store_t>(effect_to, op_pieces_store, op_pin);
00038   if (op_pieces.empty())
00039     return;
00040   op_pieces.sort();
00041   if ((int)op_pieces.size() <= state.countEffect(P, effect_to))
00042   {
00043     store_t my_pieces_store(&my_pieces, effect_to);
00044     state.forEachEffect<P,store_t>(effect_to, my_pieces_store); // ignore my_pin
00045     my_pieces.sort();
00046     return;
00047   }
00048   PtypeOSquareVector my_pieces_more;
00049   FindEffectMore action = { &my_pieces, &my_pieces_more, effect_to, &state };
00050   state.forEachEffect<P,FindEffectMore>(effect_to, action); // ignore my_pin
00051   my_pieces.sort();
00052   // sort my_pieces_more ?
00053   my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
00054 
00055   if (op_pieces.size() <= my_pieces.size())
00056     return;
00057   my_pieces_more.clear();
00058   // gather shadow efect
00059   for (size_t i=0; i<op_pieces.size(); ++i) {
00060     findAdditionalPieces(state, P, effect_to, op_pieces[i].second, my_pieces_more);
00061   }
00062   my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
00063 }
00064 
00065 template <osl::Player P>
00066 void osl::eval::
00067 See::findEffectPiecesAfterMove(const NumEffectState& state, Move move,
00068                                const PieceMask& /*my_pin*/, const PieceMask& op_pin,
00069                                PtypeOSquareVector& my_pieces, 
00070                                PtypeOSquareVector& op_pieces)
00071 {
00072   const Square from=move.from();
00073   const Square to=move.to();
00074 
00075   typedef effect_action::StorePtypeOSquare store_t;
00076   store_t op_pieces_store(&op_pieces, to);
00077   state.forEachEffect<PlayerTraits<P>::opponent,store_t>(to, op_pieces_store, op_pin);
00078   if (op_pieces.empty())
00079     return;
00080   op_pieces.sort();
00081 
00082   const Piece moved = state.pieceOnBoard(from);
00083   PieceMask ignore;             // here do not use my_pin to get optimistic result
00084   ignore.set(moved.number());
00085   if ((int)op_pieces.size() < state.countEffect(P, to))
00086   {
00087     store_t my_pieces_store(&my_pieces, to);
00088     state.forEachEffect<P,store_t>(to, my_pieces_store, ignore);
00089     my_pieces.sort();
00090     return;
00091   }
00092 
00093   PtypeOSquareVector my_pieces_more;
00094   findAdditionalPieces(state, move.player(), to, moved.square(), my_pieces_more);
00095 
00096   FindEffectMore action = { &my_pieces, &my_pieces_more, to, &state };
00097   state.forEachEffect<P,FindEffectMore>(to, action, ignore);
00098   my_pieces.sort();
00099   // sort my_pieces_more ?
00100   my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
00101 
00102   if (op_pieces.size() < my_pieces.size())
00103     return;
00104   my_pieces_more.clear();
00105   // gather shadow efect
00106   for (size_t i=0; i<op_pieces.size(); ++i) {
00107     findAdditionalPieces(state, P, to, op_pieces[i].second, my_pieces_more);
00108   }
00109   my_pieces.push_back(my_pieces_more.begin(), my_pieces_more.end());
00110 }
00111 
00112 template <osl::Player P>
00113 int osl::eval::
00114 See::computeValue(Square target, PtypeO ptypeO, 
00115                   const PtypeOSquareVector& my_pieces, 
00116                   const PtypeOSquareVector& op_pieces,
00117                   const eval::PtypeEvalTable& table)
00118 {
00119   int val = 0;
00120   CArray<int,Piece::SIZE> vals;
00121   const Player Opponent = PlayerTraits<P>::opponent;
00122   size_t i;
00123   for (i=0;i<op_pieces.size();i++)
00124   {
00125     vals[i*2]=val;
00126     // opponent moves
00127     val+=table.captureValue(ptypeO);
00128     {
00129       ptypeO = op_pieces[i].first;
00130       const bool promotable = canPromote(ptypeO) 
00131         && (target.canPromote<Opponent>() 
00132             || op_pieces[i].second.canPromote<Opponent>());
00133       if (promotable)
00134       {
00135         ptypeO=promote(ptypeO);
00136         val+=table.promoteValue(ptypeO);
00137       }
00138     }
00139     vals[i*2+1]=val;
00140     // my moves
00141     if (i>=my_pieces.size()){
00142       break;
00143     }
00144     val+=table.captureValue(ptypeO);
00145     {
00146       ptypeO=my_pieces[i].first;
00147       const bool promotable = canPromote(ptypeO) 
00148         && (target.canPromote<P>() 
00149             || my_pieces[i].second.canPromote<P>());
00150       if (promotable)
00151       {
00152         ptypeO=promote(ptypeO);
00153         val+=table.promoteValue(ptypeO);
00154       }
00155     }
00156   }
00157   for (int j=i-1;j>=0;j--)
00158   {
00159     val=EvalTraits<P>::max(val,vals[j*2+1]);
00160     val=EvalTraits<Opponent>::max(val,vals[j*2]);
00161   }
00162   return val;
00163 }
00164 
00165 template <osl::Player P>
00166 int osl::eval::See::seeInternal(const NumEffectState& state, Move move,
00167                                 const PieceMask& my_pin, const PieceMask& op_pin,
00168                                 const eval::PtypeEvalTable& table)
00169 {
00170   assert(state.isAlmostValidMove(move));
00171   
00172   const Square from=move.from();
00173   const Square to=move.to();
00174   PtypeOSquareVector my_pieces, op_pieces;
00175   int val=0; 
00176   if (from.isPieceStand())
00177   {
00178     findEffectPieces<P>(state, to, my_pin, op_pin, my_pieces, op_pieces);
00179   }
00180   else
00181   {
00182     val = PieceEval::diffWithMove(state,move);
00183     findEffectPiecesAfterMove<P>(state, move, my_pin, op_pin, my_pieces, op_pieces);
00184   }
00185   if (op_pieces.empty())
00186     return val;
00187   return val + computeValue<P>(to, move.ptypeO(), my_pieces, op_pieces, table);
00188 }
00189 
00190 int osl::eval::See::see(const NumEffectState& state, Move move,
00191                         const PieceMask& my_pin, const PieceMask& op_pin,
00192                         const eval::PtypeEvalTable *table)
00193 {
00194   if (! table)
00195     table = &Ptype_Eval_Table;
00196   if (move.player() == BLACK)
00197     return seeInternal<BLACK>(state, move, my_pin, op_pin, *table);
00198   else
00199     return -seeInternal<WHITE>(state, move, my_pin, op_pin, *table);
00200 }
00201 
00202 void osl::eval::
00203 See::findAdditionalPieces(const NumEffectState& state, Player attack, 
00204                           Square target,
00205                           Square from,
00206                           PtypeOSquareVector& out)
00207 {
00208   const Offset32 diff32 = Offset32(from, target);
00209   const Offset step = Board_Table.getShortOffsetNotKnight(diff32);
00210   if (step.zero())
00211     return;
00212   // 利きが8方向の場合
00213   Piece candidate=state.nextPiece(from, step);
00214   if (! candidate.isPiece())
00215     return;
00216   const Offset32 diff_reverse = Offset32(target,candidate.square());
00217   for (; candidate.isPiece(); 
00218        candidate=state.nextPiece(candidate.square(), step))
00219   {
00220     if (candidate.owner() != attack)
00221       return;
00222     const EffectContent effect 
00223       = Ptype_Table.getEffect(candidate.ptypeO(), diff_reverse);
00224     if (! effect.hasEffect())
00225       return;
00226     out.push_back(std::make_pair(candidate.ptypeO(), candidate.square()));
00227   } 
00228 }
00229 
00230 /* ------------------------------------------------------------------------- */
00231 // ;;; Local Variables:
00232 // ;;; mode:c++
00233 // ;;; c-basic-offset:2
00234 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines