pieceEval.tcc
Go to the documentation of this file.
00001 /* pieceEval.tcc
00002  */
00003 #ifndef OSL_PIECEEVAL_TCC
00004 #define OSL_PIECEEVAL_TCC
00005 #include "osl/effect_action/storePtypeOSquare.h"
00006 #include "osl/move_classifier/kingOpenMove.h"
00007 #include "osl/eval/pieceEval.h"
00008 #include "osl/container/pieceVector.h"
00009 namespace osl 
00010 {
00011   namespace eval
00012   {
00013     using container::PtypeOSquareVector;
00019   template <Player P>
00020   struct SelectSafePieces
00021   {
00022     static void select(const NumEffectState& state, Square target,
00023                        const PtypeOSquareVector& src,
00024                        PtypeOSquareVector& out)
00025     {
00026       for (size_t i=0; i<src.size(); ++i)
00027       {
00028         assert(P == getOwner(src[i].first));
00029         const Ptype ptype = getPtype(src[i].first);
00030         const Square from = src[i].second;
00031         if ((ptype == KING)     // 王は無条件でいれておく
00032             || (! move_classifier::KingOpenMove<P>::
00033                 isMember(state,ptype,from,target)))
00034         {
00035           out.push_back(src[i]);
00036         }
00037       }
00038     }
00042     static void select(const NumEffectState& state, Square target,
00043                        const PtypeOSquareVector& src,
00044                        PtypeOSquareVector& out, Square except_for)
00045     {
00046       for (size_t i=0; i<src.size(); ++i)
00047       {
00048         assert(P == getOwner(src[i].first));
00049         const Ptype ptype = getPtype(src[i].first);
00050         const Square from = src[i].second;
00051         if ((ptype == KING)     // 王は無条件でいれておく
00052             || (! move_classifier::KingOpenMove<P>::
00053                 isMember(state,ptype,from,target,except_for)))
00054         {
00055           out.push_back(src[i]);
00056         }
00057       }
00058     }
00059   };
00060   
00061   struct TakeBackValue
00062   {
00064     template <Player P>
00065     static void findEffectPieces(const NumEffectState& state, Square effect_to,
00066                                  PtypeOSquareVector& my_pieces, 
00067                                  PtypeOSquareVector& op_pieces)
00068     {
00069       typedef effect_action::StorePtypeOSquare store_t;
00070       store_t op_pieces_store(&op_pieces, effect_to);
00071       state.template forEachEffect<PlayerTraits<P>::opponent,store_t>
00072         (effect_to, op_pieces_store);
00073       if (! op_pieces.empty())
00074       {
00075         store_t my_pieces_store(&my_pieces, effect_to);
00076         state.template forEachEffect<P,store_t>(effect_to, my_pieces_store);
00077       }
00078     }
00080     template <Player P>
00081     static void findEffectPiecesAfterMove(const NumEffectState& state, Move move, 
00082                                           PtypeOSquareVector& my_pieces, 
00083                                           PtypeOSquareVector& op_pieces)
00084     {
00085       using namespace effect_action;
00086       
00087       const Square from=move.from();
00088       const Square to=move.to();
00089       const Player Opponent = PlayerTraits<P>::opponent;
00090       StorePtypeOSquare my_pieces_store(&my_pieces, to);
00091       StorePtypeOSquare op_pieces_store(&op_pieces, to);
00092       {
00093         // moveの結果目的のマスの利きが変わるのを調節
00097         Offset shortOffset=Board_Table.getShortOffsetNotKnight(Offset32(to,from));
00098         // knightの場合は変わらない
00099         if (! shortOffset.zero()){
00100           Piece p;
00101           for (Square pos=from-shortOffset; (p=state.pieceAt(pos)).isEmpty();
00102                pos-=shortOffset)
00103             ;
00104           if (p.isOnBoardByOwner<P>()){
00105             // 利きあり
00106             const int moveMask=Ptype_Table.getMoveMask(p.ptype());
00107             Direction dir=Board_Table.getLongDirection<P>(Offset32(to,from));
00108             if ((moveMask&dirToMask(dir))!=0){
00109               my_pieces_store.store(p);
00110             }
00111           }
00112           else if (p.isOnBoardByOwner<Opponent>()){
00113             // 利きあり
00114             const int moveMask=Ptype_Table.getMoveMask(p.ptype());
00115             Direction dir=Board_Table.getLongDirection<P>(Offset32(from,to));
00116             if ((moveMask&dirToMask(dir))!=0){
00117               op_pieces_store.store(p);
00118             }
00119           }
00120         }
00121       }
00122       state.template forEachEffect<PlayerTraits<P>::opponent,StorePtypeOSquare>
00123         (to, op_pieces_store);
00124       if (! op_pieces.empty())
00125       {
00126         const Piece movePiece=state.pieceAt(from);
00127         state.template forEachEffectNotBy<P,StorePtypeOSquare>
00128           (to, movePiece,my_pieces_store);
00129       }
00130     }
00131     
00145     template <Player P>
00146     static int computeValue(Square target, PtypeO ptypeO, 
00147                             const PtypeOSquareVector& my_pieces, 
00148                             const PtypeOSquareVector& op_pieces)
00149     {
00150       int val = 0;
00151       CArray<int,Piece::SIZE> vals;
00152       const Player Opponent = PlayerTraits<P>::opponent;
00153       size_t i;
00154       for (i=0;i<op_pieces.size();i++)
00155       {
00156         vals[i*2]=val;
00157         // opponentMove
00158         val+=Ptype_Eval_Table.captureValue(ptypeO);
00159         {
00160           ptypeO = op_pieces[i].first;
00161           const bool promotable = canPromote(ptypeO) 
00162             && (target.canPromote<Opponent>() 
00163                 || op_pieces[i].second.canPromote<Opponent>());
00164           if (promotable)
00165           {
00166             ptypeO=promote(ptypeO);
00167             val+=Ptype_Eval_Table.promoteValue(ptypeO);
00168           }
00169         }
00170         vals[i*2+1]=val;
00171         // myMove
00172         if (i>=my_pieces.size()){
00173           break;
00174         }
00175         val+=Ptype_Eval_Table.captureValue(ptypeO);
00176         {
00177           ptypeO=my_pieces[i].first;
00178           const bool promotable = canPromote(ptypeO) 
00179             && (target.canPromote<P>() 
00180                 || my_pieces[i].second.canPromote<P>());
00181           if (promotable)
00182           {
00183             ptypeO=promote(ptypeO);
00184             val+=Ptype_Eval_Table.promoteValue(ptypeO);
00185           }
00186         }
00187       }
00188       for (int j=i-1;j>=0;j--)
00189       {
00190         val=EvalTraits<P>::max(val,vals[j*2+1]);
00191         val=EvalTraits<Opponent>::max(val,vals[j*2]);
00192       }
00193       return val;
00194     }
00195   };
00196 
00198   template <Ptype PTYPE> inline int captureVal(Player P)
00199   {
00200     // unpromote(PTYPE) を定数で求められれば即値に出来る
00201     return Ptype_Eval_Table.captureValue(newPtypeO(alt(P),PTYPE));
00202   }
00203 } // namespace eval
00204 } // namespace osl
00205 
00206 template<osl::Player P>
00207 int osl::PieceEval::
00208 computeDiffAfterMove(const NumEffectState& state, Move move)
00209 {
00210   assert(P == state.turn());
00211   assert(state.isAlmostValidMove(move));
00212 
00214   PtypeOSquareVector my_pieces,op_pieces;
00218   const Square from=move.from();
00219   const Square to=move.to();
00220   int val=0; 
00224   if (from.isPieceStand()) // drop moveは簡単
00225   {
00226     TakeBackValue::findEffectPieces<P>(state, to, 
00227                                        my_pieces, op_pieces);
00228   }
00229   else
00230   {
00231     val+=diffWithMove(state,move);
00232     TakeBackValue::
00233       findEffectPiecesAfterMove<P>(state, move, my_pieces, op_pieces);
00234   }
00235 
00236   if (op_pieces.empty())
00237     return val;
00238 
00239   PtypeOSquareVector my_safe_pieces, op_safe_pieces;
00240   if (from.isPieceStand())
00241   {
00242     SelectSafePieces<P>::
00243       select(state, to, my_pieces, my_safe_pieces);
00244     SelectSafePieces<PlayerTraits<P>::opponent>::
00245       select(state, to, op_pieces, op_safe_pieces);
00246   }
00247   else
00248   {
00249     SelectSafePieces<P>::
00250       select(state, to, my_pieces, my_safe_pieces, from);
00251     SelectSafePieces<PlayerTraits<P>::opponent>::
00252       select(state, to, op_pieces, op_safe_pieces, from);
00253   }
00254   
00255   my_safe_pieces.sort();
00256   op_safe_pieces.sort();
00257 
00258   return val + TakeBackValue::
00259     computeValue<P>(to, move.ptypeO(), my_safe_pieces, op_safe_pieces);
00260 }
00261 
00262 #endif /* OSL_PIECEEVAL_TCC */
00263 // ;;; Local Variables:
00264 // ;;; mode:c++
00265 // ;;; c-basic-offset:2
00266 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines