All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rating/feature.h
Go to the documentation of this file.
1 /* feature.h
2  */
3 #ifndef _FEATURE_H
4 #define _FEATURE_H
5 
6 #include "osl/rating/ratingEnv.h"
11 #include <string>
12 
13 namespace osl
14 {
15  namespace rating
16  {
17  class Feature
18  {
19  std::string my_name;
20  public:
21  Feature(const std::string& name) : my_name(name)
22  {
23  }
24  virtual ~Feature();
25  virtual bool match(const NumEffectState& state, Move, const RatingEnv&) const =0;
26  virtual bool effectiveInCheck() const { return false; }
27  const std::string& name() const { return my_name; }
28  };
29 
30  class TakeBack : public Feature
31  {
32  public:
33  TakeBack() : Feature("TakeBack")
34  {
35  }
36  bool match(const NumEffectState&, Move move, const RatingEnv& env) const
37  {
38  return env.history.hasLastMove() && move.to() == env.history.lastMove().to();
39  }
40  virtual bool effectiveInCheck() const { return true; }
41  };
42 
43  class TakeBack2 : public Feature
44  {
45  public:
46  TakeBack2() : Feature("TakeBack2")
47  {
48  }
49  bool match(const NumEffectState&, Move move, const RatingEnv& env) const
50  {
51  return env.history.hasLastMove(2)
52  && move.to() == env.history.lastMove().to()
53  && move.to() == env.history.lastMove(2).to();
54  }
55  bool effectiveInCheck() const { return true; }
56  };
57 
58 
59  class Check : public Feature
60  {
61  int property;
62  public:
63  Check(int p);
64  static bool openLong(const NumEffectState& state, Move move)
65  {
66  if (move.isDrop())
67  return false;
68  return state.hasEffectByPtype<LANCE>(move.player(), move.from())
69  || state.hasEffectByPtype<BISHOP>(move.player(), move.from())
70  || state.hasEffectByPtype<ROOK>(move.player(), move.from());
71  }
72  bool match(const NumEffectState& state, Move move, const RatingEnv&) const;
73  static const CArray<const char*,4> check_property;
74  bool effectiveInCheck() const { return true; }
75  };
76 
77  class SendOff : public Feature
78  {
79  bool capture;
80  public:
81  SendOff(bool c) : Feature("SO"), capture(c) {}
82  bool match(const NumEffectState&, Move move, const RatingEnv& env) const
83  {
84  return env.sendoffs.isMember(move.to()) && (move.capturePtype() !=PTYPE_EMPTY) == capture;
85  }
86  };
87 
88  class Block : public Feature
89  {
90  int self, opponent;
91  public:
92  static const std::string name(int self, int opponent);
93  Block(int s, int o) : Feature(name(s, o)), self(s), opponent(o) {}
94  static int count(const NumEffectState& state, Square position, Player player)
95  {
96  return (state.findAttackAt<LANCE>(player, position).ptype() == LANCE)
97  + state.hasEffectByPtype<BISHOP>(player, position)
98  + state.hasEffectByPtype<ROOK>(player, position);
99  }
100  bool match(const NumEffectState& state, Move move, const RatingEnv&) const
101  {
102  return count(state, move.to(), state.turn()) == self
103  && count(state, move.to(), alt(state.turn())) == opponent;
104  }
105  bool effectiveInCheck() const { return true; }
106  };
107 
108  // { none, tate, naname, both }
109  struct CountOpen
110  {
111  static int index(const NumEffectState& state, Player player, Square from)
112  {
113  if (from.isPieceStand())
114  return -1;
115  const bool vertical = state.hasEffectByPtype<LANCE>(player, from)
116  || state.hasEffectByPtype<ROOK>(player, from);
117  const bool diagonal = state.hasEffectByPtype<BISHOP>(player, from);
118  return diagonal*2+vertical;
119  }
120  };
121  // { none, tate, naname, both } * { none, tate, naname, both }
122  class Open : public Feature
123  {
124  int property;
125  public:
126  Open(int p) : Feature(name(p)), property(p) {}
127  static int index(const NumEffectState& state, Move move)
128  {
129  if (move.isDrop())
130  return -1;
131  return CountOpen::index(state, move.player(), move.from())*4
132  + CountOpen::index(state, alt(move.player()), move.from());
133  }
134  bool match(const NumEffectState& state, Move move, const RatingEnv&) const
135  {
136  return index(state, move) == property;
137  }
138  static const std::string name(int property);
139  bool effectiveInCheck() const { return true; }
140  };
141 
142  class Chase : public Feature
143  {
144  public:
146  private:
147  Ptype self, target;
148  bool drop;
150  public:
151  Chase(Ptype s, Ptype t, bool d, OpponentType o)
152  : Feature(name(s,t,d,o)), self(s), target(t), drop(d), opponent_type(o) {}
153  bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
154  {
155  const Move last_move = env.history.lastMove();
156  if (! last_move.isNormal())
157  return false;
158  if (! (move.ptype() == self && last_move.ptype() == target
159  && drop == move.isDrop()))
160  return false;
161  switch (opponent_type) {
162  case CAPTURE:
163  if (last_move.capturePtype() == PTYPE_EMPTY)
164  return false;
165  break;
166  case DROP:
167  if (! last_move.isDrop())
168  return false;
169  break;
170  case ESCAPE:
171  if (last_move.isDrop() || last_move.capturePtype() != PTYPE_EMPTY
172  || ! state.hasEffectAt(state.turn(), last_move.from()))
173  return false;
174  break;
175  case OTHER:
176  if (last_move.isDrop() || last_move.capturePtype() != PTYPE_EMPTY)
177  return false;
178  break;
179  }
180  return state.hasEffectIf
181 (move.ptypeO(), move.to(), last_move.to());
182  }
183  static const std::string name(Ptype, Ptype, bool, OpponentType);
184  };
185 
187  {
188  struct Test;
189  Ptype self, attack;
190  public:
192  bool match(const NumEffectState& state, Move move, const RatingEnv& env) const;
193  bool effectiveInCheck() const { return true; }
194  static int index(const NumEffectState& state, Move move, const RatingEnv& env);
195  };
196 
197  class RookDefense : public Feature
198  {
199  public:
200  RookDefense() : Feature("RookDefense")
201  {
202  }
203  bool match(const NumEffectState& state, Move move, const RatingEnv& env) const
204  {
205  if (move.isDrop() || env.progress.value() > 8)
206  return false;
207  Piece rook1 = state.pieceOf(PtypeTraits<ROOK>::indexMin);
208  Piece rook2 = state.pieceOf(PtypeTraits<ROOK>::indexMin + 1);
209  if (move.from() == rook2.square())
210  std::swap(rook1, rook2);
211  if (move.from() != rook1.square()
212  || rook2.square().isPieceStand()
213  || rook2.owner() == move.player()
214  || rook2.square().x() != move.to().x())
215  return false;
216  return (move.to().y() - rook2.square().y())*playerToMul(move.player()) > 0;
217  }
218  };
219 
220  class BadLance : public Feature
221  {
223  public:
224  explicit BadLance(bool h) : Feature(h ? "StrongBadLance" : "WeakBadLance"), has_effect(h)
225  {
226  }
227  static bool basicMatch(const NumEffectState& state, Move move, Square front)
228  {
229  if (! (move.isDrop() && move.ptype() == LANCE))
230  return false;
231  return state.pieceOnBoard(front).isEmpty()
232  && state.hasPieceOnStand<PAWN>(alt(move.player()))
233  && !state.isPawnMaskSet(alt(move.player()), front.x());
234  }
235  bool match(const NumEffectState& state, Move move, const RatingEnv&) const
236  {
237  const Square front = Board_Table.nextSquare(move.player(), move.to(), U);
238  return basicMatch(state, move, front)
239  && ((!has_effect) ^ state.hasEffectAt(alt(move.player()), front));
240  }
241  };
242 
243  class PawnAttack : public Feature
244  {
245  public:
246  PawnAttack() : Feature("PA")
247  {
248  }
249  bool match(const NumEffectState&, Move move, const RatingEnv& env) const
250  {
251  if (! (move.isDrop() && move.ptype() == PAWN))
252  return false;
253  const Move last_move = env.history.lastMove();
254  if (! last_move.isNormal() || last_move.capturePtype() == PTYPE_EMPTY)
255  return false;
256  return last_move.capturePtype() == PAWN && last_move.to().x() == move.to().x();
257  }
258  };
259 
260  }
261 }
262 
263 
264 #endif /* _FEATURE_H */
265 // ;;; Local Variables:
266 // ;;; mode:c++
267 // ;;; c-basic-offset:2
268 // ;;; End: