00001
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
00097 Offset shortOffset=Board_Table.getShortOffsetNotKnight(Offset32(to,from));
00098
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
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
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
00201 return Ptype_Eval_Table.captureValue(newPtypeO(alt(P),PTYPE));
00202 }
00203 }
00204 }
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())
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
00263
00264
00265
00266