00001
00002
00003 #include "osl/eval/see.h"
00004 #include "osl/eval/pieceEval.h"
00005 #include "osl/effect_action/storePtypeOPosition.h"
00006
00007 struct osl::eval::See::FindEffectMore
00008 {
00009 PtypeOPositionVector *direct;
00010 PtypeOPositionVector *more;
00011 Position 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, Position) { 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.position()));
00025 findAdditionalPieces(*state, p.owner(), target, p.ptypeO(), p.position(), *more);
00026 }
00027
00028 template <osl::Player P>
00029 void osl::eval::
00030 See::findEffectPieces(const NumEffectState& state, Position effect_to,
00031 const PieceMask& , const PieceMask& op_pin,
00032 PtypeOPositionVector& my_pieces,
00033 PtypeOPositionVector& op_pieces)
00034 {
00035 typedef effect_action::StorePtypeOPosition 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);
00045 my_pieces.sort();
00046 return;
00047 }
00048 PtypeOPositionVector my_pieces_more;
00049 FindEffectMore action = { &my_pieces, &my_pieces_more, effect_to, &state };
00050 state.forEachEffect<P,FindEffectMore>(effect_to, action);
00051 my_pieces.sort();
00052
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
00059 for (size_t i=0; i<op_pieces.size(); ++i) {
00060 findAdditionalPieces(state, P, effect_to, op_pieces[i].first, 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& , const PieceMask& op_pin,
00069 PtypeOPositionVector& my_pieces,
00070 PtypeOPositionVector& op_pieces)
00071 {
00072 const Position from=move.from();
00073 const Position to=move.to();
00074
00075 typedef effect_action::StorePtypeOPosition 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.getPieceOnBoard(from);
00083 PieceMask ignore;
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 PtypeOPositionVector my_pieces_more;
00094 findAdditionalPieces(state, move.player(), to, moved.ptypeO(), moved.position(), 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
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
00106 for (size_t i=0; i<op_pieces.size(); ++i) {
00107 findAdditionalPieces(state, P, to, op_pieces[i].first, 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(Position target, PtypeO ptypeO,
00115 const PtypeOPositionVector& my_pieces,
00116 const PtypeOPositionVector& op_pieces)
00117 {
00118 int val = 0;
00119 CArray<int,Piece::SIZE> vals;
00120 const Player Opponent = PlayerTraits<P>::opponent;
00121 size_t i;
00122 for (i=0;i<op_pieces.size();i++)
00123 {
00124 vals[i*2]=val;
00125
00126 val+=Ptype_Eval_Table.captureValue(ptypeO);
00127 {
00128 ptypeO = op_pieces[i].first;
00129 const bool promotable = canPromote(ptypeO)
00130 && (target.canPromote<Opponent>()
00131 || op_pieces[i].second.canPromote<Opponent>());
00132 if (promotable)
00133 {
00134 ptypeO=promote(ptypeO);
00135 val+=Ptype_Eval_Table.promoteValue(ptypeO);
00136 }
00137 }
00138 vals[i*2+1]=val;
00139
00140 if (i>=my_pieces.size()){
00141 break;
00142 }
00143 val+=Ptype_Eval_Table.captureValue(ptypeO);
00144 {
00145 ptypeO=my_pieces[i].first;
00146 const bool promotable = canPromote(ptypeO)
00147 && (target.canPromote<P>()
00148 || my_pieces[i].second.canPromote<P>());
00149 if (promotable)
00150 {
00151 ptypeO=promote(ptypeO);
00152 val+=Ptype_Eval_Table.promoteValue(ptypeO);
00153 }
00154 }
00155 }
00156 for (int j=i-1;j>=0;j--)
00157 {
00158 val=EvalTraits<P>::max(val,vals[j*2+1]);
00159 val=EvalTraits<Opponent>::max(val,vals[j*2]);
00160 }
00161 return val;
00162 }
00163
00164 template <osl::Player P>
00165 int osl::eval::See::seeInteral(const NumEffectState& state, Move move,
00166 const PieceMask& my_pin, const PieceMask& op_pin)
00167 {
00168 assert(state.isAlmostValidMove(move));
00169
00170 const Position from=move.from();
00171 const Position to=move.to();
00172 PtypeOPositionVector my_pieces, op_pieces;
00173 int val=0;
00174 if (from.isPieceStand())
00175 {
00176 findEffectPieces<P>(state, to, my_pin, op_pin, my_pieces, op_pieces);
00177 }
00178 else
00179 {
00180 val = PieceEval::diffWithMove(state,move);
00181 findEffectPiecesAfterMove<P>(state, move, my_pin, op_pin, my_pieces, op_pieces);
00182 }
00183 if (op_pieces.empty())
00184 return val;
00185 return val + computeValue<P>(to, move.ptypeO(), my_pieces, op_pieces);
00186 }
00187
00188 int osl::eval::See::see(const NumEffectState& state, Move move,
00189 const PieceMask& my_pin, const PieceMask& op_pin)
00190 {
00191 if (move.player() == BLACK)
00192 return seeInteral<BLACK>(state, move, my_pin, op_pin);
00193 else
00194 return -seeInteral<WHITE>(state, move, my_pin, op_pin);
00195 }
00196
00197 void osl::eval::
00198 See::findAdditionalPieces(const NumEffectState& state, Player attack,
00199 Position target,
00200 PtypeO direct_attack, Position from,
00201 PtypeOPositionVector& out)
00202 {
00203 const Offset32 diff32 = Offset32(from, target);
00204 const Offset step = Board_Table.getShortOffsetNotKnight(diff32);
00205 if (step.zero())
00206 return;
00207
00208 Piece candidate=state.nextPiece(from, step);
00209 if (! candidate.isPiece())
00210 return;
00211 const Offset32 diff_reverse = Offset32(target,candidate.position());
00212 for (; candidate.isPiece();
00213 candidate=state.nextPiece(candidate.position(), step))
00214 {
00215 if (candidate.owner() != attack)
00216 return;
00217 const EffectContent effect
00218 = Ptype_Table.getEffect(candidate.ptypeO(), diff_reverse);
00219 if (! effect.hasEffect())
00220 return;
00221 out.push_back(std::make_pair(candidate.ptypeO(), candidate.position()));
00222 }
00223 }
00224
00225
00226
00227
00228
00229