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