00001
00002
00003 #ifndef _PIECEEVAL_TCC
00004 #define _PIECEEVAL_TCC
00005 #include "osl/effect_action/storePtypeOPosition.h"
00006 #include "osl/move_classifier/kingOpenMove.h"
00007 #include "osl/eval/pieceEval.h"
00008 #include "osl/container/pieceVector.h"
00009 #include "osl/apply_move/applyMove.h"
00010 namespace osl
00011 {
00012 namespace eval
00013 {
00014 using container::PtypeOPositionVector;
00020 template <Player P>
00021 struct SelectSafePieces
00022 {
00023 template <class State>
00024 static void select(const State& state, Position target,
00025 const PtypeOPositionVector& src,
00026 PtypeOPositionVector& out)
00027 {
00028 for (size_t i=0; i<src.size(); ++i)
00029 {
00030 assert(P == getOwner(src[i].first));
00031 const Ptype ptype = getPtype(src[i].first);
00032 const Position from = src[i].second;
00033 if ((ptype == KING)
00034 || (! move_classifier::KingOpenMove<P>::
00035 isMember(state,ptype,from,target)))
00036 {
00037 out.push_back(src[i]);
00038 }
00039 }
00040 }
00044 template <class State>
00045 static void select(const State& state, Position target,
00046 const PtypeOPositionVector& src,
00047 PtypeOPositionVector& out, Position except_for)
00048 {
00049 for (size_t i=0; i<src.size(); ++i)
00050 {
00051 assert(P == getOwner(src[i].first));
00052 const Ptype ptype = getPtype(src[i].first);
00053 const Position from = src[i].second;
00054 if ((ptype == KING)
00055 || (! move_classifier::KingOpenMove<P>::
00056 isMember(state,ptype,from,target,except_for)))
00057 {
00058 out.push_back(src[i]);
00059 }
00060 }
00061 }
00062 };
00063
00064 struct TakeBackValue
00065 {
00067 template <class State, Player P>
00068 static void findEffectPieces(const State& state, Position effect_to,
00069 PtypeOPositionVector& my_pieces,
00070 PtypeOPositionVector& op_pieces)
00071 {
00072 typedef effect_action::StorePtypeOPosition store_t;
00073 store_t op_pieces_store(&op_pieces, effect_to);
00074 state.template forEachEffect<PlayerTraits<P>::opponent,store_t>
00075 (effect_to, op_pieces_store);
00076 if (! op_pieces.empty())
00077 {
00078 store_t my_pieces_store(&my_pieces, effect_to);
00079 state.template forEachEffect<P,store_t>(effect_to, my_pieces_store);
00080 }
00081 }
00083 template <class State, Player P>
00084 static void findEffectPiecesAfterMove(const State& state, Move move,
00085 PtypeOPositionVector& my_pieces,
00086 PtypeOPositionVector& op_pieces)
00087 {
00088 using namespace effect_action;
00089
00090 const Position from=move.from();
00091 const Position to=move.to();
00092 const Player Opponent = PlayerTraits<P>::opponent;
00093 StorePtypeOPosition my_pieces_store(&my_pieces, to);
00094 StorePtypeOPosition op_pieces_store(&op_pieces, to);
00095 {
00096
00100 Offset shortOffset=Board_Table.getShortOffsetNotKnight(Offset32(to,from));
00101
00102 if (! shortOffset.zero()){
00103 Piece p;
00104 for (Position pos=from-shortOffset; (p=state.getPieceAt(pos)).isEmpty();
00105 pos-=shortOffset)
00106 ;
00107 if (p.isOnBoardByOwner<P>()){
00108
00109 const int moveMask=Ptype_Table.getMoveMask(p.ptype());
00110 Direction dir=Board_Table.getLongDirection<P>(Offset32(to,from));
00111 if ((moveMask&dirToMask(dir))!=0){
00112 my_pieces_store.store(p);
00113 }
00114 }
00115 else if (p.isOnBoardByOwner<Opponent>()){
00116
00117 const int moveMask=Ptype_Table.getMoveMask(p.ptype());
00118 Direction dir=Board_Table.getLongDirection<P>(Offset32(from,to));
00119 if ((moveMask&dirToMask(dir))!=0){
00120 op_pieces_store.store(p);
00121 }
00122 }
00123 }
00124 }
00125 state.template forEachEffect<PlayerTraits<P>::opponent,StorePtypeOPosition>
00126 (to, op_pieces_store);
00127 if (! op_pieces.empty())
00128 {
00129 const Piece movePiece=state.getPieceAt(from);
00130 state.template forEachEffectNotBy<P,StorePtypeOPosition>
00131 (to, movePiece,my_pieces_store);
00132 }
00133 }
00134
00148 template <Player P>
00149 static int computeValue(Position target, PtypeO ptypeO,
00150 const PtypeOPositionVector& my_pieces,
00151 const PtypeOPositionVector& op_pieces)
00152 {
00153 int val = 0;
00154 CArray<int,Piece::SIZE> vals;
00155 const Player Opponent = PlayerTraits<P>::opponent;
00156 size_t i;
00157 for (i=0;i<op_pieces.size();i++)
00158 {
00159 vals[i*2]=val;
00160
00161 val+=Ptype_Eval_Table.captureValue(ptypeO);
00162 {
00163 ptypeO = op_pieces[i].first;
00164 const bool promotable = canPromote(ptypeO)
00165 && (target.canPromote<Opponent>()
00166 || op_pieces[i].second.canPromote<Opponent>());
00167 if (promotable)
00168 {
00169 ptypeO=promote(ptypeO);
00170 val+=Ptype_Eval_Table.promoteValue(ptypeO);
00171 }
00172 }
00173 vals[i*2+1]=val;
00174
00175 if (i>=my_pieces.size()){
00176 break;
00177 }
00178 val+=Ptype_Eval_Table.captureValue(ptypeO);
00179 {
00180 ptypeO=my_pieces[i].first;
00181 const bool promotable = canPromote(ptypeO)
00182 && (target.canPromote<P>()
00183 || my_pieces[i].second.canPromote<P>());
00184 if (promotable)
00185 {
00186 ptypeO=promote(ptypeO);
00187 val+=Ptype_Eval_Table.promoteValue(ptypeO);
00188 }
00189 }
00190 }
00191 for (int j=i-1;j>=0;j--)
00192 {
00193 val=EvalTraits<P>::max(val,vals[j*2+1]);
00194 val=EvalTraits<Opponent>::max(val,vals[j*2]);
00195 }
00196 return val;
00197 }
00198 };
00199
00201 template <Ptype PTYPE> inline int captureVal(Player P)
00202 {
00203
00204 return Ptype_Eval_Table.captureValue(newPtypeO(alt(P),PTYPE));
00205 }
00206 }
00207 }
00208
00209 template<class State, osl::Player P>
00210 int osl::PieceEval::
00211 computeDiffAfterMove(const State& state, Move move)
00212 {
00213 assert(P == state.getTurn());
00214 assert(state.isAlmostValidMove(move));
00215
00217 PtypeOPositionVector my_pieces,op_pieces;
00221 const Position from=move.from();
00222 const Position to=move.to();
00223 int val=0;
00227 if (from.isPieceStand())
00228 {
00229 TakeBackValue::findEffectPieces<State,P>(state, to,
00230 my_pieces, op_pieces);
00231 }
00232 else
00233 {
00234 val+=diffWithMove(state,move);
00235 TakeBackValue::
00236 findEffectPiecesAfterMove<State,P>(state, move, my_pieces, op_pieces);
00237 }
00238
00239 if (op_pieces.empty())
00240 return val;
00241
00242 PtypeOPositionVector my_safe_pieces, op_safe_pieces;
00243 if (from.isPieceStand())
00244 {
00245 SelectSafePieces<P>::
00246 select(state, to, my_pieces, my_safe_pieces);
00247 SelectSafePieces<PlayerTraits<P>::opponent>::
00248 select(state, to, op_pieces, op_safe_pieces);
00249 }
00250 else
00251 {
00252 SelectSafePieces<P>::
00253 select(state, to, my_pieces, my_safe_pieces, from);
00254 SelectSafePieces<PlayerTraits<P>::opponent>::
00255 select(state, to, op_pieces, op_safe_pieces, from);
00256 }
00257
00258 my_safe_pieces.sort();
00259 op_safe_pieces.sort();
00260
00261 return val + TakeBackValue::
00262 computeValue<P>(to, move.ptypeO(), my_safe_pieces, op_safe_pieces);
00263 }
00264
00265 #endif
00266
00267
00268
00269