All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
minorPieceBonus.h
Go to the documentation of this file.
1 /* minorPieceBonus.h
2  */
3 #ifndef EVAL_MINORPIECEBONUS_H
4 #define EVAL_MINORPIECEBONUS_H
5 
6 #include "osl/eval/pieceEval.h"
9 #include <boost/static_assert.hpp>
10 
11 namespace osl
12 {
13  namespace eval
14  {
16  {
18  };
23  {
24  CArray<int,2> pawn_on_stand;
25  CArray<int,2> lance_on_stand;
26  CArray<int,2> knight_on_stand;
27  CArray<int,2> pawns;
28  CArray<int,2> golds;
29  private:
30  int pawnBonus(Progress16 progress16) const
31  {
32  const int black_pawn = pawn_on_stand[BLACK];
33  const int white_pawn = pawn_on_stand[WHITE];
34  const int black_pawn_total = pawns[BLACK];
35  const int white_pawn_total = pawns[WHITE];
36  int result = 0;
37  if (black_pawn > 1)
38  {
39  result -= (black_pawn - 1) * progress16.value() *
41  }
42  else if (black_pawn == 0 && black_pawn_total < white_pawn_total)
43  {
44  result -= PtypeEvalTraits<PAWN>::val / 2;
45  }
46  if (black_pawn >= 9)
47  {
48  result -= (black_pawn - 8) * progress16.value() *
50  }
51  if (white_pawn > 1)
52  {
53  result += (white_pawn - 1) * progress16.value() *
55  }
56  else if (white_pawn == 0 && white_pawn_total < black_pawn_total)
57  {
58  result += PtypeEvalTraits<PAWN>::val / 2;
59  }
60  if (white_pawn >= 9)
61  {
62  result += (white_pawn - 8) * progress16.value() *
64  }
65  return result;
66  }
67  int lanceBonus(Progress16 progress16) const
68  {
69  const int black_lance = lance_on_stand[BLACK];
70  const int white_lance = lance_on_stand[WHITE];
71  int result = 0;
72  if (black_lance > 1)
73  {
74  result -= (black_lance - 1) * progress16.value() * PtypeEvalTraits<LANCE>::val / 32;
75  }
76  if (black_lance > 2)
77  {
78  result -= (black_lance - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 24;
79  }
80  if (white_lance > 1)
81  {
82  result += (white_lance - 1) * progress16.value() * PtypeEvalTraits<LANCE>::val / 32;
83  }
84  if (white_lance > 2)
85  {
86  result += (white_lance - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 24;
87  }
88  return result;
89  }
90  int knightBonus(Progress16 progress16) const
91  {
92  const int black_knight = knight_on_stand[BLACK];
93  const int white_knight = knight_on_stand[WHITE];
94  int result = 0;
95  if (black_knight > 1)
96  {
97  result -= (black_knight - 1) * progress16.value() * PtypeEvalTraits<KNIGHT>::val / 32;
98  }
99  if (black_knight > 2)
100  {
101  result -= (black_knight - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 8;
102  }
103  if (white_knight > 1)
104  {
105  result += (white_knight - 1) * progress16.value() * PtypeEvalTraits<KNIGHT>::val / 32;
106  }
107  if (white_knight > 2)
108  {
109  result += (white_knight - 2) * progress16.value() * PtypeEvalTraits<PAWN>::val / 8;
110  }
111  return result;
112  }
113  int goldBonus(Progress16 black, Progress16 white) const
114  {
115  const int black_gold = golds[BLACK];
116  const int white_gold = golds[WHITE];
117  if (black_gold >= 3)
118  {
119  return white.value() * PtypeEvalTraits<GOLD>::val
120  * (black_gold - 2);
121  }
122  else if (white_gold >= 3)
123  {
124  return -black.value() * PtypeEvalTraits<GOLD>::val
125  * (white_gold - 2);
126  }
127 
128  return 0;
129  }
130 
131  public:
132  MinorPieceBonus(const SimpleState& state)
133  {
134  pawn_on_stand[BLACK] = state.countPiecesOnStand(BLACK, PAWN);
135  pawn_on_stand[WHITE] = state.countPiecesOnStand(WHITE, PAWN);
136  lance_on_stand[BLACK] = state.countPiecesOnStand(BLACK, LANCE);
137  lance_on_stand[WHITE] = state.countPiecesOnStand(WHITE, LANCE);
138  knight_on_stand[BLACK] = state.countPiecesOnStand(BLACK, KNIGHT);
139  knight_on_stand[WHITE] = state.countPiecesOnStand(WHITE, KNIGHT);
140  pawns[BLACK] = 0;
141  pawns[WHITE] = 0;
142  golds[BLACK] = 0;
143  golds[WHITE] = 0;
144  for (int i = PtypeTraits<PAWN>::indexMin;
145  i < PtypeTraits<PAWN>::indexLimit; i++)
146  {
147  const Piece pawn = state.pieceOf(i);
148  if (pawn.owner() == BLACK)
149  pawns[BLACK]++;
150  else
151  pawns[WHITE]++;
152  }
153 
154  for (int i = PtypeTraits<GOLD>::indexMin;
155  i < PtypeTraits<GOLD>::indexLimit; i++)
156  {
157  const Piece gold = state.pieceOf(i);
158  golds[gold.owner()]++;
159  }
160  }
161 
162  int value(Progress16 progress16,
163  Progress16 black,
164  Progress16 white) const
165  {
166  return pawnBonus(progress16) + lanceBonus(progress16) +
167  knightBonus(progress16) + goldBonus(black, white);
168  }
169 
170  void update(const SimpleState& /*new_state*/, Move last_move)
171  {
172  const Player player = last_move.player();
173  const Ptype ptype = last_move.ptype();
174  if (last_move.isDrop()) {
175  if (ptype == PAWN) {
176  pawn_on_stand[player]--;
177  assert(pawn_on_stand[BLACK] >= 0);
178  assert(pawn_on_stand[WHITE] >= 0);
179  }
180  if (ptype == LANCE) {
181  lance_on_stand[player]--;
182  }
183  if (ptype == KNIGHT) {
184  knight_on_stand[player]--;
185  }
186  return;
187  }
188  const Ptype captured = last_move.capturePtype();
189  if (captured != PTYPE_EMPTY) {
190  switch (unpromote(captured)) {
191  case PAWN:
192  pawn_on_stand[player]++;
193  pawns[player]++;
194  pawns[alt(player)]--;
195  assert(pawns[BLACK] + pawns[WHITE] == 18);
196  assert(pawn_on_stand[BLACK] >= 0);
197  assert(pawn_on_stand[WHITE] >= 0);
198  break;
199  case LANCE:
200  lance_on_stand[player]++;
201  break;
202  case KNIGHT:
203  knight_on_stand[player]++;
204  break;
205  case GOLD:
206  golds[player]++;
207  golds[alt(player)]--;
208  assert(golds[BLACK] + golds[WHITE] == 4);
209  break;
210  default:
211  ;
212  }
213  }
214  }
215 
216  int expect(const SimpleState& state, Move move, Progress16 progress16,
217  Progress16 black,
218  Progress16 white) const
219  {
220  MinorPieceBonus new_eval = *this;
221  if (move.isDrop()){
222  const Ptype ptype = move.ptype();
223  if (ptype == PAWN) {
224  new_eval.pawn_on_stand[state.turn()]--;
225  assert(new_eval.pawn_on_stand[BLACK] >= 0);
226  assert(new_eval.pawn_on_stand[WHITE] >= 0);
227  }
228  else if (ptype == LANCE) {
229  new_eval.lance_on_stand[state.turn()]--;
230  }
231  else if (ptype == KNIGHT) {
232  new_eval.knight_on_stand[state.turn()]--;
233  }
234  return new_eval.value(progress16, black, white);
235  }
236  Ptype ptype = move.capturePtype();
237  if (ptype != PTYPE_EMPTY) {
238  if (unpromote(ptype) == PAWN) {
239  new_eval.pawn_on_stand[state.turn()]++;
240  new_eval.pawns[state.turn()]++;
241  new_eval.pawns[alt(state.turn())]--;
242  assert(new_eval.pawns[BLACK] + new_eval.pawns[WHITE] == 18);
243  assert(new_eval.pawn_on_stand[BLACK] >= 0);
244  assert(new_eval.pawn_on_stand[WHITE] >= 0);
245  }
246  else if (unpromote(ptype) == LANCE) {
247  new_eval.lance_on_stand[state.turn()]++;
248  }
249  else if (unpromote(ptype) == KNIGHT) {
250  new_eval.knight_on_stand[state.turn()]++;
251  }
252  else if (unpromote(ptype) == GOLD) {
253  new_eval.golds[state.turn()]++;
254  new_eval.golds[alt(state.turn())]--;
255  assert(new_eval.golds[BLACK] + new_eval.golds[WHITE] == 4);
256  }
257  }
258  return new_eval.value(progress16, black, white);
259  }
260 
261  MinorPieceDebugInfo debugInfo(Progress16 progress16,
262  Progress16 black, Progress16 white) const
263  {
264  MinorPieceDebugInfo debug_info;
265  debug_info.pawn_bonus = pawnBonus(progress16);
266  debug_info.lance_bonus = lanceBonus(progress16);
267  debug_info.knight_bonus = knightBonus(progress16);
268  debug_info.gold_bonus = goldBonus(black, white);
269 
270  return debug_info;
271  }
272  };
273  } // namespace eval
274 } // namespace osl
275 
276 #endif /* EVAL_MINORPIECEBONUS_H */
277 // ;;; Local Variables:
278 // ;;; mode:c++
279 // ;;; c-basic-offset:2
280 // ;;; coding:utf-8
281 // ;;; End: