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