feature.h
Go to the documentation of this file.
00001 /* feature.h
00002  */
00003 #ifndef _FEATURE_H
00004 #define _FEATURE_H
00005 
00006 #include "osl/rating/ratingEnv.h"
00007 #include "osl/state/numEffectState.h"
00008 #include "osl/effect_util/effectUtil.h"
00009 #include "osl/move_classifier/check_.h"
00010 #include "osl/move_classifier/moveAdaptor.h"
00011 #include <string>
00012 
00013 namespace osl
00014 {
00015   namespace rating
00016   {
00017     class Feature
00018     {
00019       std::string my_name;
00020     public:
00021       Feature(const std::string& name) : my_name(name)
00022       {
00023       }
00024       virtual ~Feature();
00025       virtual bool match(const NumEffectState& state, Move, const RatingEnv&) const =0;
00026       virtual bool effectiveInCheck() const { return false; }
00027       const std::string& name() const { return my_name; }
00028     };
00029 
00030     class TakeBack : public Feature
00031     {
00032     public:
00033       TakeBack() : Feature("TakeBack")
00034       {
00035       }
00036       bool match(const NumEffectState&, Move move, const RatingEnv& env) const
00037       {
00038         return env.history.hasLastMove() && move.to() == env.history.lastMove().to();
00039       }
00040       virtual bool effectiveInCheck() const { return true; }
00041     };
00042 
00043     class TakeBack2 : public Feature
00044     {
00045     public:
00046       TakeBack2() : Feature("TakeBack2")
00047       {
00048       }
00049       bool match(const NumEffectState&, Move move, const RatingEnv& env) const
00050       {
00051         return env.history.hasLastMove(2)
00052           && move.to() == env.history.lastMove().to()
00053           && move.to() == env.history.lastMove(2).to();
00054       }
00055       bool effectiveInCheck() const { return true; }
00056     };
00057 
00058 
00059     class Check : public Feature
00060     {
00061       int property;
00062     public:
00063       Check(int p);
00064       static bool openLong(const NumEffectState& state, Move move) 
00065       {
00066         if (move.isDrop())
00067           return false;
00068         return state.hasEffectByPtype<LANCE>(move.player(), move.from())
00069           || state.hasEffectByPtype<BISHOP>(move.player(), move.from())
00070           || state.hasEffectByPtype<ROOK>(move.player(), move.from());
00071       }
00072       bool match(const NumEffectState& state, Move move, const RatingEnv&) const;
00073       static const CArray<const char*,4> check_property;
00074       bool effectiveInCheck() const { return true; }
00075     };
00076 
00077     class SendOff : public Feature
00078     {
00079       bool capture;
00080     public:
00081       SendOff(bool c) : Feature("SO"), capture(c) {}
00082       bool match(const NumEffectState&, Move move, const RatingEnv& env) const
00083       {
00084         return env.sendoffs.isMember(move.to()) && (move.capturePtype() !=PTYPE_EMPTY) == capture;
00085       }
00086     };
00087 
00088     class Block : public Feature
00089     {
00090       int self, opponent;
00091     public:
00092       static const std::string name(int self, int opponent);
00093       Block(int s, int o) : Feature(name(s, o)), self(s), opponent(o) {}
00094       static int count(const NumEffectState& state, Square position, Player player) 
00095       {
00096         return (state.findAttackAt<LANCE>(player, position).ptype() == LANCE)
00097           + state.hasEffectByPtype<BISHOP>(player, position)
00098           + state.hasEffectByPtype<ROOK>(player, position);
00099       }
00100       bool match(const NumEffectState& state, Move move, const RatingEnv&) const
00101       {
00102         return count(state, move.to(), state.turn()) == self
00103           && count(state, move.to(), alt(state.turn())) == opponent;
00104       }
00105       bool effectiveInCheck() const { return true; }
00106     };
00107 
00108     // { none, tate, naname, both }
00109     struct CountOpen
00110     {
00111       static int index(const NumEffectState& state, Player player, Square from) 
00112       {
00113         if (from.isPieceStand())
00114           return -1;
00115         const bool vertical = state.hasEffectByPtype<LANCE>(player, from)
00116           || state.hasEffectByPtype<ROOK>(player, from);
00117         const bool diagonal = state.hasEffectByPtype<BISHOP>(player, from);
00118         return diagonal*2+vertical;
00119       }
00120     };
00121     // { none, tate, naname, both } * { none, tate, naname, both }
00122     class Open : public Feature
00123     {
00124       int property;
00125     public:
00126       Open(int p) : Feature(name(p)), property(p) {}
00127       static int index(const NumEffectState& state, Move move)
00128       {
00129         if (move.isDrop())
00130           return -1;
00131         return CountOpen::index(state, move.player(), move.from())*4
00132           + CountOpen::index(state, alt(move.player()), move.from());
00133       }
00134       bool match(const NumEffectState& state, Move move, const RatingEnv&) const
00135       {
00136         return index(state, move) == property;
00137       }
00138       static const std::string name(int property);
00139       bool effectiveInCheck() const { return true; }
00140     };
00141 
00142     class Chase : public Feature
00143     {
00144     public:
00145       enum OpponentType { CAPTURE, DROP, ESCAPE, OTHER, };
00146     private:
00147       Ptype self, target;
00148       bool drop;
00149       OpponentType opponent_type;
00150     public:
00151       Chase(Ptype s, Ptype t, bool d, OpponentType o) 
00152         : Feature(name(s,t,d,o)), self(s), target(t), drop(d), opponent_type(o) {}
00153       bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
00154       {
00155         const Move last_move = env.history.lastMove();
00156         if (! last_move.isNormal())
00157           return false;
00158         if (! (move.ptype() == self && last_move.ptype() == target
00159                && drop == move.isDrop()))
00160           return false;
00161         switch (opponent_type) {
00162         case CAPTURE:
00163           if (last_move.capturePtype() == PTYPE_EMPTY)
00164             return false;
00165           break;
00166         case DROP:
00167           if (! last_move.isDrop())
00168             return false;
00169           break;
00170         case ESCAPE:
00171           if (last_move.isDrop() || last_move.capturePtype() != PTYPE_EMPTY
00172               || ! state.hasEffectAt(state.turn(), last_move.from()))
00173             return false;
00174           break;
00175         case OTHER:
00176           if (last_move.isDrop() || last_move.capturePtype() != PTYPE_EMPTY)
00177             return false;
00178           break;
00179         }
00180         return state.hasEffectIf
00181 (move.ptypeO(), move.to(), last_move.to());
00182       }
00183       static const std::string name(Ptype, Ptype, bool, OpponentType);
00184     };
00185 
00186     class ImmediateAddSupport : public Feature
00187     {
00188       struct Test;
00189       Ptype self, attack;
00190     public:
00191       ImmediateAddSupport(Ptype self, Ptype attack);
00192       bool match(const NumEffectState& state, Move move, const RatingEnv& env) const;
00193       bool effectiveInCheck() const { return true; }
00194       static int index(const NumEffectState& state, Move move, const RatingEnv& env);
00195     };
00196 
00197     class RookDefense : public Feature
00198     {
00199     public:
00200       RookDefense() : Feature("RookDefense") 
00201       {
00202       }
00203       bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
00204       {
00205         if (move.isDrop() || env.progress.value() > 8)
00206           return false;
00207         Piece rook1 = state.pieceOf(PtypeTraits<ROOK>::indexMin);
00208         Piece rook2 = state.pieceOf(PtypeTraits<ROOK>::indexMin + 1);
00209         if (move.from() == rook2.square()) 
00210           std::swap(rook1, rook2);
00211         if (move.from() != rook1.square() 
00212             || rook2.square().isPieceStand()
00213             || rook2.owner() == move.player()
00214             || rook2.square().x() != move.to().x())
00215           return false;
00216         return (move.to().y() - rook2.square().y())*playerToMul(move.player()) > 0;
00217       }
00218     };
00219 
00220     class BadLance : public Feature
00221     {
00222       bool has_effect;
00223     public:
00224       explicit BadLance(bool h) : Feature(h ? "StrongBadLance" : "WeakBadLance"), has_effect(h)
00225       {
00226       }
00227       static bool basicMatch(const NumEffectState& state, Move move, Square front) 
00228       {
00229         if (! (move.isDrop() && move.ptype() == LANCE))
00230           return false;
00231         return state.pieceOnBoard(front).isEmpty()
00232           && state.hasPieceOnStand<PAWN>(alt(move.player()))
00233           && !state.isPawnMaskSet(alt(move.player()), front.x());
00234       }
00235       bool match(const NumEffectState& state, Move move, const RatingEnv&) const
00236       {
00237         const Square front = Board_Table.nextSquare(move.player(), move.to(), U);
00238         return basicMatch(state, move, front)
00239           && ((!has_effect) ^ state.hasEffectAt(alt(move.player()), front));
00240       }
00241     };
00242 
00243     class PawnAttack : public Feature
00244     {
00245     public:
00246       PawnAttack() : Feature("PA") 
00247       {
00248       }
00249       bool match(const NumEffectState&, Move move, const RatingEnv& env) const
00250       {
00251         if (! (move.isDrop() && move.ptype() == PAWN))
00252           return false;
00253         const Move last_move = env.history.lastMove();
00254         if (! last_move.isNormal() || last_move.capturePtype() == PTYPE_EMPTY)
00255           return false;
00256         return last_move.capturePtype() == PAWN && last_move.to().x() == move.to().x();
00257       }
00258     };
00259     
00260   }
00261 }
00262 
00263 
00264 #endif /* _FEATURE_H */
00265 // ;;; Local Variables:
00266 // ;;; mode:c++
00267 // ;;; c-basic-offset:2
00268 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines