00001
00002
00003 #include "osl/category/defense.h"
00004 #include "osl/category/categoryEnv.h"
00005 #include "osl/category/probTableDefine.h"
00006 #include "osl/eval/pieceEval.h"
00007 #include "osl/effect_util/effectUtil.h"
00008 #include "osl/effect_util/effectUtil.tcc"
00009 #include "osl/container/moveStack.h"
00010 #include "osl/state/simpleState.tcc"
00011
00012 namespace osl
00013 {
00014 namespace category
00015 {
00016 DEF_CATEGORY_TABLE_IP(PtypePtypeProbTable, AddSupport);
00017 DEF_CATEGORY_TABLE_IP(PieceValueTable, AntiPromotion);
00018 DEF_CATEGORY_TABLE_IP(PieceValueTable, AddEffectToLastEffect);
00019 DEF_CATEGORY_TABLE_IP(PieceValueTable, BlockLong);
00020 }
00021 }
00022
00023 struct osl::category::AddSupport::Test
00024 {
00025 const CategoryEnv::effect_state_t *state;
00026 Player turn;
00027
00028 Piece result;
00029 bool supported;
00030 int value;
00031 Test(const CategoryEnv::effect_state_t *s, Player t)
00032 : state(s), turn(t),
00033 result(Piece::EMPTY()), supported(1), value(0)
00034 {
00035 }
00039 void operator()(Position pos)
00040 {
00041 const Piece target = state->getPieceAt(pos);
00042 assert(target.isPiece());
00043 if ((target.owner() == turn)
00044 && state->hasEffectBy(alt(turn), pos))
00045 {
00046 update(pos, target);
00047 }
00048 }
00054 void update(Position pos, Piece target)
00055 {
00056 const bool supported = state->hasEffectBy(turn, pos);
00057 if ((! this->supported) && supported)
00058 return;
00059 const int targetVal = eval::Ptype_Eval_Table.value(target.ptype());
00060 if (((! supported) && this->supported)
00061 || (targetVal > value))
00062 {
00063 result = target;
00064 this->supported = supported;
00065 value = targetVal;
00066 }
00067 }
00068 };
00069
00074 std::pair<bool,size_t> osl::category::
00075 AddSupport::getIndexIf(const CategoryEnv& env, Move move, int pieceValue)
00076 {
00077 const Player turn = move.player();
00078 assert(env.state->getTurn() == turn);
00079 Test selector(env.state, turn);
00080 EffectUtil::forEachEffectPieceOfMove(*env.state, move, selector);
00081 if (! selector.result.isPiece())
00082 return std::make_pair(false,0u);
00083
00084 const Piece attacker
00085 = EffectUtil::cheapestPiece(alt(turn), *env.state,
00086 selector.result.position());
00087 const size_t index
00088 = probTable.getIndex(selector.result.ptype(), selector.supported,
00089 attacker.ptype(), pieceValue);
00090 return std::make_pair(true, index);
00091 }
00092
00093 struct osl::category::AddEffectToLastEffect::CheckEffect
00094 {
00095 bool *result;
00096 const PawnMaskState& state;
00097 Move move;
00098 CheckEffect(bool *r, const PawnMaskState& s, Move m)
00099 : result(r), state(s), move(m)
00100 {
00101 }
00102 template <Player P>
00103 void
00104 #ifdef __GNUC__
00105 __attribute__ ((noinline))
00106 #endif
00107 doAction(Piece , Position lastAttack)
00108 {
00109 if (! lastAttack.isOnBoard())
00110 return;
00111 const Piece attacked = state.getPieceOnBoard(lastAttack);
00112 if (((attacked == Piece::EMPTY())
00113 || (attacked.owner() == state.getTurn()))
00114 && state.hasEffectFromTo(move.ptypeO(), move.to(), lastAttack))
00115 *result = true;
00116 }
00117 };
00118 bool osl::category::AddEffectToLastEffect::
00119 isInCategory(const CategoryEnv& env, Move move)
00120 {
00121 const Move last_move=env.history->lastMove();
00122 if (! last_move.isNormal())
00123 return false;
00124 const Position lastTo = last_move.to();
00125 if (lastTo==move.to())
00126 return false;
00127 bool result = false;
00128 CheckEffect action(&result, *env.state, move);
00129 env.state->forEachEffectOfPiece(env.state->getPieceOnBoard(lastTo), action);
00130 return result;
00131 }
00132
00133 struct osl::category::AntiPromotion::Test
00134 {
00135 const CategoryEnv::effect_state_t& state;
00136 const Player opponent;
00137 bool result;
00138
00139 Test(const CategoryEnv::effect_state_t& s, Player o)
00140 : state(s), opponent(o), result(false)
00141 {
00142 }
00143 void operator()(Position focus)
00144 {
00145
00146 if (! focus.canPromote(opponent))
00147 return;
00148
00149 if ((state.getPieceOnBoard(focus) == Piece::EMPTY())
00150 && (! state.hasEffectBy(alt(opponent), focus)))
00151 {
00152 const Piece promoter =
00153 EffectUtil::promotablePiece(opponent, state, focus);
00154 if (promoter.isPiece())
00155 {
00156 assert(canPromote(promoter.ptype()));
00157 result = true;
00158 }
00159 }
00160 }
00161 };
00162
00163 bool osl::category::AntiPromotion::
00164 isInCategory(const CategoryEnv& env, Move move)
00165 {
00166 const Player opponent = alt(env.state->getTurn());
00167 int ymin, ymax;
00168 if (opponent == BLACK)
00169 {
00170 ymin = 1;
00171 ymax = 4;
00172 }
00173 else
00174 {
00175 ymin = 7;
00176 ymax = 10;
00177 }
00178 const Ptype ptype = unpromote(move.ptype());
00179 const Position to = move.to();
00180 if ((ptype != BISHOP) && (ptype != ROOK))
00181 {
00182 const int toY = to.y();
00183 if (opponent == BLACK)
00184 {
00185 if (toY > ymax)
00186 return false;
00187 }
00188 else
00189 {
00190 if (toY < ymin-1)
00191 return false;
00192 }
00193 }
00194
00195 Test checker(*env.state, opponent);
00196 EffectUtil::forEachEffectPositionOfMove(*env.state, move, checker);
00197 return false;
00198 };
00199
00200
00201
00202
00203
00204