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