00001
00002
00003 #ifndef RATING_KING8_H
00004 #define RATING_KING8_H
00005
00006 #include "osl/rating/feature.h"
00007 #include "osl/rating/feature/countEffect2.h"
00008 #include "osl/effect_util/neighboring8Direct.h"
00009
00010 namespace osl
00011 {
00012 namespace rating
00013 {
00014 class AttackKing8 : public Feature, CountEffect2
00015 {
00016 Ptype self, target;
00017 bool same;
00018 static const std::string name(Ptype self, Ptype target, bool same);
00019 public:
00020 AttackKing8(Ptype s, Ptype t, bool ss, int attack, int defense)
00021 : Feature(name(s, t, ss)+CountEffect2::name(attack, defense)), CountEffect2(attack, defense),
00022 self(s), target(t), same(ss)
00023 {
00024 }
00025 bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
00026 {
00027 if (move.ptype() != self)
00028 return false;
00029 const Square position
00030 = Neighboring8Direct::findNearest(state, move.ptypeO(), move.to(), state.kingSquare(alt(state.turn())));
00031 if (position.isPieceStand() || position == move.from())
00032 return false;
00033 if (! move.isDrop() && state.hasEffectByPiece(state.pieceOnBoard(move.from()), position))
00034 return false;
00035 const Piece p = state.pieceAt(position);
00036 if (p.ptype() != target)
00037 return false;
00038 if (! CountEffect2::match(state, position, env))
00039 return false;
00040 if (!isPiece(target))
00041 return true;
00042 return same == (p.owner() == move.player());
00043 }
00044 };
00045
00046 class DefenseKing8 : public Feature
00047 {
00048 Ptype self;
00049 bool drop;
00050 int danger;
00051 public:
00052 static const std::string name(Ptype self, bool drop, int danger);
00053 DefenseKing8(Ptype s, bool d, int dan)
00054 : Feature(name(s,d,dan)), self(s), drop(d), danger(dan)
00055 {
00056 }
00057 static int count(const NumEffectState& state)
00058 {
00059 const Player attack = alt(state.turn());
00060 const Square king = state.kingSquare(alt(attack));
00061 int count = 0;
00062 for (int dx=-1; dx<=1; ++dx) {
00063 for (int dy=-1; dy<=1; ++dy) {
00064 if (dx == 0 && dy ==0)
00065 continue;
00066 Square p = king + Offset(dx,dy);
00067 if (! state.pieceAt(p).isEdge()
00068 && state.hasEffectAt(attack, p))
00069 ++count;
00070 }
00071 }
00072 if (king.x() == 1 || king.x() == 9)
00073 ++count;
00074 return std::min(3, count);
00075 }
00076 static bool blocking(const NumEffectState& state, Square king, Square to)
00077 {
00078 const Player attacker = alt(state.turn());
00079 Piece attack = state.findAttackAt<BISHOP>(attacker, to);
00080 if (attack.isPiece()
00081 && Neighboring8Direct::hasEffect(state, newPtypeO(attacker, BISHOP), attack.square(), king))
00082 return true;
00083 attack = state.findAttackAt<ROOK>(attacker, to);
00084 if (attack.isPiece()
00085 && Neighboring8Direct::hasEffect(state, newPtypeO(attacker, ROOK), attack.square(), king))
00086 return true;
00087 attack = state.findAttackAt<LANCE>(attacker, to);
00088 return attack.isPiece() && attack.ptype() == LANCE
00089 && Neighboring8Direct::hasEffect(state, newPtypeO(attacker, LANCE), attack.square(), king);
00090 }
00091 static bool matchDrop(const NumEffectState& state, Move move)
00092 {
00093 if (! move.isDrop())
00094 return false;
00095 const Square king = state.kingSquare(state.turn());
00096 if (king.isNeighboring8(move.to())
00097 || Neighboring8Direct::hasEffect(state, move.ptypeO(), move.to(), king))
00098 return true;
00099 return blocking(state, king, move.to());
00100 }
00101 static bool matchMove(const NumEffectState& state, Move move)
00102 {
00103 if (move.isDrop())
00104 return false;
00105 if (move.ptype() == KING)
00106 return true;
00107 const Square king = state.kingSquare(state.turn());
00108 if (king.isNeighboring8(move.to())
00109 || king.isNeighboring8(move.from())
00110 || Neighboring8Direct::hasEffect(state, move.ptypeO(), move.to(), king))
00111 return true;
00112 return blocking(state, king, move.to());
00113 }
00114 bool match(const NumEffectState& state, Move move, const RatingEnv&) const
00115 {
00116 if (move.ptype() != self)
00117 return false;
00118 if (count(state) != danger)
00119 return false;
00120 if (drop)
00121 return matchDrop(state, move);
00122 return matchMove(state, move);
00123 }
00124 };
00125 }
00126 }
00127
00128 #endif
00129
00130
00131
00132