00001
00002
00003 #ifndef _PATTERNLONG2_H
00004 #define _PATTERNLONG2_H
00005
00006 #include "osl/rating/feature.h"
00007 #include "osl/rating/feature/countEffect2.h"
00008
00009 namespace osl
00010 {
00011 namespace rating
00012 {
00013 class Pattern : public Feature, CountEffect2
00014 {
00015 public:
00016 static const Direction INVALID = LONG_UL;
00017 private:
00018 Direction direction, direction2;
00019 Ptype self, target;
00020 bool same;
00021 static const std::string name(Direction d, Direction d2, Ptype self, Ptype target, bool same);
00022 public:
00023 Pattern(Direction d, Ptype s, Ptype t, bool ss, int attack, int defense)
00024 : Feature(name(d, INVALID, s, t, ss)+CountEffect2::name(attack, defense)), CountEffect2(attack, defense),
00025 direction(d), direction2(INVALID), self(s), target(t), same(ss)
00026 {
00027 }
00028 Pattern(Direction d, Direction d2, Ptype s, Ptype t, bool ss, int attack, int defense)
00029 : Feature(name(d, d2, s, t, ss)+CountEffect2::name(attack, defense)), CountEffect2(attack, defense),
00030 direction(d), direction2(d2), self(s), target(t), same(ss)
00031 {
00032 }
00033 static Square nextSquare(Player player, Square start, Direction direction, Direction direction2)
00034 {
00035 const Square p = Board_Table.nextSquare(player, start, direction);
00036 if (direction2 == INVALID || ! p.isOnBoard())
00037 return p;
00038 return Board_Table.nextSquare(player, p, direction2);
00039 }
00040 static Square nextSquare(Move move, Direction direction, Direction direction2)
00041 {
00042 return nextSquare(move.player(), move.to(), direction, direction2);
00043 }
00044 bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
00045 {
00046 if (move.ptype() != self)
00047 return false;
00048 const Square position = nextSquare(move, direction, direction2);
00049 const Piece p = (position == move.from()) ? Piece::EMPTY() : state.pieceAt(position);
00050 if (p.ptype() != target)
00051 return false;
00052 if (! CountEffect2::match(state, position, env))
00053 return false;
00054 if (!isPiece(target))
00055 return true;
00056 return same == (p.owner() == move.player());
00057 }
00058 };
00059
00060 typedef std::pair<Piece,Square> PieceSquare;
00061 struct LongTarget : CountEffect2
00062 {
00063 Ptype target;
00064 bool promotable, same;
00065 LongTarget(Ptype t, bool p, bool s, int attack, int defense)
00066 : CountEffect2(attack, defense), target(t), promotable(p), same(s)
00067 {
00068 }
00069 static bool isPromotable(Move move, Square position)
00070 {
00071 assert(position.isOnBoard());
00072 return position.canPromote(move.player()) || (! move.isDrop() && move.to().canPromote(move.player()));
00073 }
00074 bool match(const NumEffectState& state, Move move, PieceSquare p, const RatingEnv& env) const
00075 {
00076 if (p.first.ptype() != target)
00077 return false;
00078 if (target == PTYPE_EDGE)
00079 return true;
00080 if (isPromotable(move, p.second) != promotable)
00081 return false;
00082 if (! CountEffect2::match(state, p.second, env))
00083 return false;
00084 if (! p.first.isPiece())
00085 return true;
00086 return same == (p.first.owner() == move.player());
00087 }
00088 bool matchOtherThanPromotable(const NumEffectState& state, Move move, PieceSquare p, const RatingEnv& env) const
00089 {
00090 if (p.first.ptype() != target)
00091 return false;
00092 if (target == PTYPE_EDGE)
00093 return true;
00094 if (! CountEffect2::match(state, p.second, env))
00095 return false;
00096 if (! p.first.isPiece())
00097 return true;
00098 return same == (p.first.owner() == move.player());
00099 }
00100 const std::string name() const;
00101 };
00102
00103 struct LongTarget2
00104 {
00105 Ptype target;
00106 bool same;
00107 LongTarget2(Ptype t, bool s) : target(t), same(s)
00108 {
00109 }
00110 bool match(const NumEffectState&, Move move, Piece p) const
00111 {
00112 if (p.ptype() != target)
00113 return false;
00114 assert(! p.isEmpty());
00115 if (! isPiece(target))
00116 return true;
00117 return same == (p.owner() == move.player());
00118 }
00119 const std::string name() const;
00120 };
00121
00122 class PatternLong : public Feature
00123 {
00124 Direction direction;
00125 Ptype self;
00126 LongTarget target;
00127 static const std::string name(Direction d, Ptype self);
00128 public:
00129 PatternLong(Direction d, Ptype s, LongTarget t);
00137 static const PieceSquare nextPieceOrEnd(const SimpleState& state, Square start, Player player, Direction direction);
00138 static const PieceSquare nextPieceOrEnd(const SimpleState& state, Square start, Offset);
00139 static const PieceSquare find(const NumEffectState& state, Move move, Direction direction);
00140 bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
00141 {
00142 if (move.ptype() != self)
00143 return false;
00144 PieceSquare pp = find(state, move, direction);
00145 return target.match(state, move, pp, env);
00146 }
00147 };
00148
00149 class PatternLong2 : public Feature
00150 {
00151 Direction direction;
00152 Ptype self;
00153 LongTarget2 target2;
00154 static const std::string name(Direction d, Ptype self);
00155 public:
00156 PatternLong2(Direction d, Ptype s, LongTarget2 t2);
00157 static const Piece find(const NumEffectState& state, Move move, Direction direction)
00158 {
00159 Piece p = state.nextPiece(move.to(), Board_Table.getOffset(move.player(), direction));
00160 if (p.isPiece() && p.square() == move.from())
00161 p = state.nextPiece(move.to(), Board_Table.getOffset(move.player(), direction));
00162 return p;
00163 }
00164 bool match(const NumEffectState& state, Move move, const RatingEnv&) const
00165 {
00166 if (move.ptype() != self)
00167 return false;
00168 const Piece p = find(state, move, direction);
00169 return target2.match(state, move, p);
00170 }
00171 };
00172
00173 class PatternBlock : public Feature
00174 {
00175 Ptype self, attack;
00176 LongTarget target;
00177 public:
00178 PatternBlock(Ptype s, Ptype a, LongTarget t);
00179 static const PieceSquare find(const NumEffectState& state, Move move, Ptype attacker_ptype);
00180 bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
00181 {
00182 if (move.ptype() != self)
00183 return false;
00184 PieceSquare pp = find(state, move, attack);
00185 return ! pp.first.isEdge() && target.matchOtherThanPromotable(state, move, pp, env)
00186 && pp.second.canPromote(pp.first.isPiece() ? alt(pp.first.owner()) : alt(move.player()))
00187 == target.promotable;
00188 }
00189 };
00190 }
00191 }
00192
00193 #endif
00194
00195
00196
00197