00001
00002
00003 #include "osl/category/escape.h"
00004 #include "osl/category/probTable.tcc"
00005 #include "osl/category/moveEvaluation.h"
00006 #include "osl/category/probTableDefine.h"
00007 #include "osl/move_action/store.h"
00008 #include "osl/move_generator/escape_.h"
00009 #include "osl/move_classifier/moveAdaptor.h"
00010 #include "osl/container/moveLogProbVector.h"
00011 #include "osl/state/simpleState.tcc"
00012 #include <string>
00013
00014
00015
00016 struct osl::category::EscapeCommon::Generator
00017 {
00018 const CategoryEnv::effect_state_t *state;
00019 const PtypeValueTable *table;
00020 int limit;
00021 MoveLogProbVector *out;
00022 int *indices;
00023 Generator(const CategoryEnv::effect_state_t *s, const PtypeValueTable *t,
00024 int l, MoveLogProbVector *o, int *io)
00025 : state(s), table(t), limit(l), out(o), indices(io)
00026 {
00027 }
00029 void
00030 #ifdef __GNUC__
00031 __attribute__ ((noinline))
00032 #endif
00033 operator()(Piece p)
00034 {
00035 const Player myself = state->getTurn();
00036 assert(p.owner() == myself);
00037 if (state->hasEffectBy(alt(myself),p.position()))
00038 {
00039 MoveVector moves;
00040 move_action::Store store(moves);
00041 const Player opponent = alt(myself);
00042 const Piece attacker =
00043 EffectUtil::cheapestPiece(opponent, *state, p.position());
00044 if(myself==BLACK)
00045 move_generator::Escape<BLACK,CategoryEnv::effect_state_t,move_action::Store>::
00046 generateMoves(*state, p, attacker, store);
00047 else
00048 move_generator::Escape<WHITE,CategoryEnv::effect_state_t,move_action::Store>::
00049 generateMoves(*state, p, attacker, store);
00050 for (size_t i=0; i<moves.size(); ++i)
00051 {
00052 const int diff = MoveEvaluation::evalLight(*state, moves[i]);
00053 const bool supported
00054 = state->hasEffectBy(myself, p.position());
00055 const size_t index =
00056 table->getIndex(supported, attacker.ptype(), diff);
00057 const int prob = (*table)[index];
00058 if (prob <= limit)
00059 {
00060 out->push_back(moves[i], prob);
00061 if (indices)
00062 *indices++ = index;
00063 }
00064 }
00065 }
00066 }
00067 };
00068
00069
00070
00071 template <osl::Ptype PTYPE>
00072 void osl::category::Escape<PTYPE>::
00073 generate(const CategoryEnv& env, MoveLogProbVector& out, int *indices)
00074 {
00075 EscapeCommon::Generator gen(env.state, &probTable, env.limit, &out, indices);
00076 if (env.state->getTurn() == BLACK)
00077 (*env.state).template forEachOnBoard<BLACK,PTYPE,EscapeCommon::Generator>
00078 (gen);
00079 else
00080 (*env.state).template forEachOnBoard<WHITE,PTYPE,EscapeCommon::Generator>
00081 (gen);
00082 }
00083
00084 template <osl::Ptype PTYPE>
00085 void osl::category::Escape<PTYPE>::
00086 generate(const CategoryEnv& env, MoveLogProbVector& out)
00087 {
00088 generate(env, out, 0);
00089 }
00090
00091 template <osl::Ptype PTYPE>
00092 const char * osl::category::Escape<PTYPE>::getName()
00093 {
00094 static std::string name = std::string("Escape-")
00095 + PtypeTraits<PTYPE>::name();
00096 return name.c_str();
00097 }
00098
00099
00100 struct osl::category::ImmediateEscape::PositionAction
00101 {
00102 const CategoryEnv::effect_state_t *state;
00103 Position attackFrom;
00104 int limit;
00105 MoveLogProbVector *out;
00106 int *indexOut;
00107 PositionAction(const CategoryEnv::effect_state_t *s, Position from,
00108 int l, MoveLogProbVector *o, int *iout)
00109 : state(s), attackFrom(from), limit(l), out(o), indexOut(iout)
00110 {
00111 }
00112 template<Player P>
00113 void doAction(Piece attacker, Position pos);
00114 };
00115
00116 template<osl::Player P>
00117 void osl::category::ImmediateEscape::PositionAction::
00118 doAction(Piece attacker, Position pos)
00119 {
00120 assert(P==alt(state->getTurn()));
00121 const Piece p = state->getPieceAt(pos);
00122 if (p.isPiece() && (p.owner() == state->getTurn()))
00123 {
00124 MoveVector moves;
00125 move_action::Store store(moves);
00126 move_generator::Escape<PlayerTraits<P>::opponent,CategoryEnv::effect_state_t,move_action::Store>::
00127 generateMoves(*state, p,state->getPieceAt(attackFrom), store);
00128 for (size_t i=0; i<moves.size(); ++i)
00129 {
00130 const int diff = MoveEvaluation::evalLight(*state, moves[i]);
00131 const bool supported
00132 = state->hasEffectBy(state->getTurn(), attackFrom);
00133 const size_t index =
00134 probTable.getIndex(p.ptype(), supported, attacker.ptype(), diff);
00135 const int prob = probTable[index];
00136 if (prob <= limit)
00137 {
00138 out->push_back(moves[i], prob);
00139 if (indexOut)
00140 *indexOut++ = index;
00141 }
00142 }
00143 }
00144 }
00145
00146 void osl::category::ImmediateEscape::
00147 generate(const CategoryEnv& env, MoveLogProbVector& out, int *indices)
00148 {
00149 const Move last_move=env.history->lastMove();
00150 if (! last_move.isNormal())
00151 return;
00152 const Position pos = last_move.to();
00153 const Piece attacker = env.state->getPieceOnBoard(pos);
00154 assert(attacker.isPiece());
00155 assert(attacker.owner() == alt(env.state->getTurn()));
00156
00157 PositionAction a(env.state, pos, env.limit, &out, indices);
00158 env.state->forEachEffectOfPiece(attacker,a);
00159 }
00160
00161 void osl::category::ImmediateEscape::
00162 generate(const CategoryEnv& env, MoveLogProbVector& out)
00163 {
00164 generate(env, out, 0);
00165 }
00166 namespace osl
00167 {
00168 namespace category
00169 {
00170 DEF_CATEGORY_TABLE_IP(PtypePtypeProbTable, ImmediateEscape);
00171 template <Ptype PTYPE>
00172 DEF_CATEGORY_TABLE_IP(PtypeValueTable, Escape<PTYPE>);
00173 }
00174 }
00175 template struct osl::category::Escape<osl::ROOK>;
00176 template struct osl::category::Escape<osl::BISHOP>;
00177 template struct osl::category::Escape<osl::GOLD>;
00178 template struct osl::category::Escape<osl::SILVER>;
00179 template struct osl::category::Escape<osl::KNIGHT>;
00180 template struct osl::category::Escape<osl::LANCE>;
00181 template struct osl::category::Escape<osl::PAWN>;
00182
00183
00184
00185
00186
00187