piecePair.cc
Go to the documentation of this file.
1 /* piecePair.cc
2  */
3 #include "osl/eval/piecePair.h"
4 
9  // positive offset [0,5]
10  DirectionPlayerTraits<UUL, BLACK>::offset(),
11  DirectionPlayerTraits<UL, BLACK>::offset(),
12  DirectionPlayerTraits<L, BLACK>::offset(),
13  DirectionPlayerTraits<DL, BLACK>::offset(),
14  DirectionPlayerTraits<UUR, WHITE>::offset(),
15  DirectionPlayerTraits<D, BLACK>::offset(),
16  // negative offset [6,11]
17  DirectionPlayerTraits<UUL, WHITE>::offset(),
18  DirectionPlayerTraits<DR, BLACK>::offset(),
19  DirectionPlayerTraits<R, BLACK>::offset(),
20  DirectionPlayerTraits<UR, BLACK>::offset(),
21  DirectionPlayerTraits<UUR, BLACK>::offset(),
22  DirectionPlayerTraits<U, BLACK>::offset(),
23  };
24 
25 namespace osl
26 {
27  namespace eval
28  {
29  namespace ml
30  {
31  namespace ppair
32  {
37 
39  {
40  offset_index.fill(-1);
41  for (size_t i=0; i<PiecePair::offsets.size(); ++i) {
42  offset_index[PiecePair::offsets[i].index()] = i;
43  }
44  }
45  inline int inv(int offset_id)
46  {
47  assert(offset_id >= 0 && offset_id < 12);
48  return (offset_id + 6) % 12;
49  }
50  inline int swaplr(int offset_id)
51  {
52  assert(offset_id >= 0 && offset_id < 12);
53  if (offset_id == 11)
54  return 11;
55  return 10 - offset_id;
56  }
57  inline int swapud(int offset_id)
58  {
59  assert(offset_id >= 0 && offset_id < 12);
60  return swaplr(inv(offset_id));
61  }
62  int pindex(Player player, Ptype ptype) { return PiecePair::IndexTable::pindex(player, ptype); }
63  void makeTable()
64  {
65  int index = 0;
66  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
67  for (int ip1=ip0; ip1<=PTYPE_MAX; ++ip1) {
68  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
69  // same player
70  {
71 #ifndef NDEBUG
72  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
73  assert(plain_table[0][pi0][pi1] == 0);
74 #endif
75  ++index;
76  plain_table.fillSame(index, 0, p0, p1); // UUL
77  plain_table.fillSame(index, 10, p0, p1); // UUR
78  if (p0 != p1) {
79  ++index;
80  plain_table.fillSame(index, 0, p1, p0); // UUL
81  plain_table.fillSame(index, 10, p1, p0); // UUR
82  }
83 
84  ++index;
85  plain_table.fillSame(index, 1, p0, p1); // UL
86  plain_table.fillSame(index, 9, p0, p1); // UR
87  if (p0 != p1) {
88  ++index;
89  plain_table.fillSame(index, 1, p1, p0); // UR
90  plain_table.fillSame(index, 9, p1, p0); // UL
91  }
92 
93  ++index;
94  plain_table.fillSame(index, 2, p0, p1); // L
95  plain_table.fillSame(index, 8, p0, p1); // R
96  if (p0 != p1) { // use the same index as L
97  plain_table.fillSame(index, 2, p1, p0); // L
98  plain_table.fillSame(index, 8, p1, p0); // R
99  }
100 
101  ++index;
102  plain_table.fillSame(index, 11, p0, p1); // U
103  if (p0 != p1) {
104  plain_table.fillSame(index, 11, p1, p0); // U
105  }
106  }
107  // different player
108  {
109  // UUL, UUR
110  ++index;
111  plain_table.fillDiffer(index, 0, p0, p1); // UUL
112  plain_table.fillDiffer(index, 10, p0, p1); // UUR
113  ++index;
114  plain_table.fillDiffer(index, inv(0), p0, p1); // UUL^-1
115  plain_table.fillDiffer(index, inv(10), p0, p1); // UUR^-1
116 
117  // UL, UR
118  ++index;
119  plain_table.fillDiffer(index, 1, p0, p1); // UL
120  plain_table.fillDiffer(index, 9, p0, p1); // UR
121  ++index;
122  // DR, DL
123  plain_table.fillDiffer(index, inv(1), p0, p1); // DR
124  plain_table.fillDiffer(index, inv(9), p0, p1); // DL
125 
126  // LR
127  ++index;
128  plain_table.fillDiffer(index, 2, p0, p1); // L
129  plain_table.fillDiffer(index, inv(2), p0, p1); // R, use the same index as L
130 
131  // UD
132  ++index;
133  plain_table.fillDiffer(index, 11, p0, p1); // U
134 
135  ++index;
136  plain_table.fillDiffer(index, inv(11), p0, p1); // D
137  }
138  }
139  }
140  assert(index+1 == PiecePair::plain_table_size);
141  }
142  void makeTableX()
143  {
144  // currently only for same player
145  int index = 0;
146  // make leftside
147  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
148  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
149  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
150  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
151  for (int x=1; x<=5; ++x) {
152  // (UUL, DDL), (UL, DL)
153  for (int d=0; d<2; ++d) {
154  ++index;
155  x_table[x][d][pi0][pi1] = index;
156  x_table[x][swapud(d)][pi0][pi1] = index;
157  }
158  // L
159  ++index;
160  x_table[x][2][pi0][pi1] = index;
161  // U, D
162  ++index;
163  x_table[x][11][pi0][pi1] = index;
164  x_table[x][inv(11)][pi1][pi0] = index;
165  ++index;
166  x_table[x][5][pi0][pi1] = index;
167  x_table[x][inv(5)][pi1][pi0] = index;
168  } // x
169  }
170  }
171  // make rightside
172  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
173  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
174  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
175  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
176  for (int x=2; x<=5; ++x) {
177  // (UUL, DDL), (UL, DL) => (DDR, UUR), (DR, UR)
178  for (int d=0; d<2; ++d) {
179  x_table[x-1][inv(d)][pi1][pi0] = x_table[x][d][pi0][pi1];
180  x_table[x-1][inv(swapud(d))][pi1][pi0] = x_table[x][swapud(d)][pi0][pi1];
181  }
182  // L => R
183  x_table[x-1][swaplr(2)][pi1][pi0] = x_table[x][2][pi0][pi1];
184  }
185  // flip col 5
186  for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
187  if (swaplr(d) == (int)d || x_table[5][d][pi0][pi1] == 0)
188  continue;
189  x_table[5][swaplr(d)][pi0][pi1] = x_table[5][d][pi0][pi1];
190  }
191  }
192  }
193  // mirror to [6,9]
194  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
195  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
196  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
197  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
198  for (int x=6; x<=9; ++x) {
199  for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
200  x_table[x][d][pi0][pi1] = x_table[10-x][swaplr(d)][pi0][pi1];
201  }
202  } // x
203  }
204  }
205  // make white player
206  for (int x=1; x<=9; ++x) {
207  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
208  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
209  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
210  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
211  const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
212  for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
213  assert(x_table[x][d][pi0][pi1]);
214  x_table[10-x][inv(d)][pi0w][pi1w] = -x_table[x][d][pi0][pi1];
215  }
216  }
217  }
218  }
219  assert(PiecePair::x_table_size == index+1);
220  for (int x=1; x<=9; ++x)
221  x_table[x].amplify(PiecePair::plain_table_size);
222  }
223  int wrap9(int y)
224  {
225  return (y-1)%9 + 1;
226  }
227  void makeTableY()
228  {
229  // only for same player
230  int index = 0;
231  // for upside direction
232  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
233  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
234  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
235  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
236  // same player
237  for (int y=1; y<=9; ++y) {
238  for (int d=0; d<2; ++d) { // (UUL, UUR), (UL, UR)
239  ++index;
240  y_table[y][d][pi0][pi1] = index;
241  y_table[y][swaplr(d)][pi0][pi1] = index;
242  }
243  // (L, R)
244  ++index;
245  y_table[y][2][pi0][pi1] = index;
246  y_table[y][2][pi1][pi0] = index;
247  y_table[y][swaplr(2)][pi0][pi1] = index;
248  y_table[y][swaplr(2)][pi1][pi0] = index;
249  // U
250  ++index;
251  y_table[y][11][pi0][pi1] = index;
252  } // y
253  }
254  }
255  // flip for downside direction
256  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
257  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
258  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
259  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
260  for (int y=1; y<=9; ++y) {
261  // (UUL, UUR),
262  y_table[wrap9(y+2)][inv(0)][pi1][pi0] = y_table[y][0][pi0][pi1];
263  y_table[wrap9(y+2)][inv(swaplr(0))][pi1][pi0] = y_table[y][swaplr(0)][pi0][pi1];
264  // (UL, UR)
265  y_table[wrap9(y+1)][inv(1)][pi1][pi0] = y_table[y][1][pi0][pi1];
266  y_table[wrap9(y+1)][inv(swaplr(1))][pi1][pi0] = y_table[y][swaplr(1)][pi0][pi1];
267  // U
268  y_table[wrap9(y+1)][inv(11)][pi1][pi0] = y_table[y][11][pi0][pi1];
269  } // y
270  }
271  }
272  // make white player
273  for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
274  for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
275  const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
276  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
277  const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
278  for (int y=1; y<=9; ++y) {
279  for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
280  y_table[10-y][inv(d)][pi0w][pi1w] = -y_table[y][d][pi0][pi1];
281  }
282  }
283  }
284  }
285  assert(PiecePair::y_table_size == index+1);
286  for (int y=1; y<=9; ++y)
288  }
289 
290  CArray3d<int, PTYPEO_SIZE, 12, PTYPEO_SIZE> x_values[10], y_values[10]; // plain_values は xに折込
291  }
292  using namespace ppair;
293  }
294  }
295 }
296 
297 /* ------------------------------------------------------------------------- */
300 {
301  fill(0);
302 }
303 
304 void osl::eval::ml::
306 {
307  for (size_t d=0; d<offsets.size(); ++d) {
308  for (int ip0=0; ip0<PTYPEO_SIZE; ++ip0) {
309  for (int ip1=0; ip1<PTYPEO_SIZE; ++ip1) {
310  signed short& target = (*this)[d][ip0][ip1];
311  if (target > 0) {
312  target += base;
313  }
314  else if (target < 0)
315  {
316  target -= base;
317  }
318  }
319  }
320  }
321 }
322 void osl::eval::ml::
323 PiecePair::IndexTable::fillBW(int index, int dir, Ptype p0, Ptype p1)
324 {
325  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
326  const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
327 
328  (*this)[dir][pi0][pi1] = index; // normal
329  (*this)[inv(dir)][pi0w][pi1w] = -index; // white
330 }
331 void osl::eval::ml::
332 PiecePair::IndexTable::fillSame(int index, int dir, Ptype p0, Ptype p1)
333 {
334  fillBW(index, dir, p0, p1);
335  fillBW(index, inv(dir), p1, p0); // swapped order
336 }
337 void osl::eval::ml::
338 PiecePair::IndexTable::fillDiffer(int index, int dir, Ptype p0, Ptype p1)
339 {
340  const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
341  const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
342 
343  (*this)[inv(dir)][pi0][pi1w] = index;
344  (*this)[dir][pi1w][pi0] = index; // swapped piece
345  (*this)[inv(dir)][pi1][pi0w] = -index; // swapped player
346  (*this)[dir][pi0w][pi1] = -index; // swapped player, swapped piece
347 }
348 /* ------------------------------------------------------------------------- */
349 
350 
351 void osl::eval::ml::
353 {
354  static bool initialized = false;
355  if (initialized)
356  return;
357  initialized = true;
358  makeOffsetIndex();
359  makeTable();
360  makeTableX();
361  makeTableY();
362 }
363 
364 void osl::eval::ml::
366 {
367  for (int i=1; i<=9; ++i) {
368  x_values[i].fill(0);
369  y_values[i].fill(0);
370  }
371  for (size_t d=0; d<offsets.size(); ++d) {
372  for (int ip0=0; ip0<PTYPEO_SIZE; ++ip0) {
373  for (int ip1=0; ip1<PTYPEO_SIZE; ++ip1) {
374  int plain = 0;
375  if (plain_table[d][ip0][ip1] > 0)
376  plain = weights.value(plain_table[d][ip0][ip1]);
377  else if (plain_table[d][ip0][ip1] < 0)
378  plain = -weights.value(-plain_table[d][ip0][ip1]);
379  for (int i=1; i<=9; ++i) {
380  x_values[i][ip0][d][ip1] = plain;
381  if (x_table[i][d][ip0][ip1] > 0)
382  x_values[i][ip0][d][ip1] += weights.value(x_table[i][d][ip0][ip1]);
383  else if (x_table[i][d][ip0][ip1] < 0)
384  x_values[i][ip0][d][ip1] += -weights.value(-x_table[i][d][ip0][ip1]);
385  if (y_table[i][d][ip0][ip1] > 0)
386  y_values[i][ip0][d][ip1] = weights.value(y_table[i][d][ip0][ip1]);
387  else if (y_table[i][d][ip0][ip1] < 0)
388  y_values[i][ip0][d][ip1] = -weights.value(-y_table[i][d][ip0][ip1]);
389  }
390  }
391  }
392  }
393 }
394 
395 void osl::eval::ml::
397 {
398  values.setValue(0,0);
399  for (int x=1; x<=9; ++x) {
400  for (int y=1; y<=9; ++y) {
401  const Square pos1(x,y);
402  for (size_t i=0; i<offsets.size(); ++i) {
403  const Square pos0 = pos1+offsets[i];
404  if (! pos0.isOnBoard())
405  continue;
406  for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p) {
407  const Ptype ptype = static_cast<Ptype>(p);
408  assert(isPiece(ptype));
409  index_t idx = index(i, pos0, newPtypeO(BLACK, ptype), pos1, newPtypeO(WHITE, ptype));
410  values.setValue(abs(idx[0]), 0);
411  idx = index(i, pos0, newPtypeO(WHITE, ptype), pos1, newPtypeO(BLACK, ptype));
412  values.setValue(abs(idx[0]), 0);
413  }
414  }
415  }
416  }
417 }
418 
420 PiecePair::index(int offset_id, Square pos0, PtypeO p0, Square pos1, PtypeO p1)
421 {
422  assert(pos0 != pos1);
423  assert(! pos0.isPieceStand() && ! pos1.isPieceStand());
424 
425  assert(pos0 - pos1 == offsets[offset_id]);
426  index_t ret = {
427  plain_table[offset_id][ptypeOIndex(p0)][ptypeOIndex(p1)],
428  x_table[pos0.x()][offset_id][ptypeOIndex(p0)][ptypeOIndex(p1)],
429  y_table[pos0.y()][offset_id][ptypeOIndex(p0)][ptypeOIndex(p1)],
430  };
431  assert(abs(ret[0]) < plain_table_size);
432  assert(abs(ret[1]) < plain_table_size + x_table_size);
433  assert(abs(ret[2]) < plain_table_size + x_table_size + y_table_size);
434  assert(ret[1] == 0 || abs(ret[1]) > plain_table_size);
435  assert(ret[2] == 0 || abs(ret[2]) > plain_table_size + x_table_size);
436  return ret;
437 }
438 
440 PiecePair::index(int offset_id, Piece p, Piece q)
441 {
442  assert(p.isPiece());
443  assert(q.isPiece());
444  assert(p != q);
445  assert(p.isOnBoard() && q.isOnBoard());
446  return index(offset_id, p.square(), p.ptypeO(), q.square(), q.ptypeO());
447 }
448 
449 int osl::eval::ml::
450 PiecePair::eval(const NumEffectState& state, const Weights& values)
451 {
452  int ret = 0;
453  for (int i=0; i<Piece::SIZE; i++) {
454  const Piece p = state.pieceOf(i);
455  ret += pieceValueDouble(state, p, values);
456  }
457  return ret/2;
458 }
459 
460 int osl::eval::ml::
461 PiecePair::evalWithUpdate(const NumEffectState& state, Move moved, int last_value, const Weights& values)
462 {
463  if (moved.isPass())
464  return last_value;
465 
466  int ret = last_value;
467  const Square from = moved.from();
468  const Square to = moved.to();
469 
470  // adjust from
471  if (! from.isPieceStand()) {
472  for (size_t i=0; i<offsets.size(); ++i) {
473  const Square target = from + offsets[i];
474  const Piece p = state.pieceAt(target);
475  if (! p.isPiece() || p.square() == to)
476  continue;
477  assert(!target.isPieceStand());
478  ret -= value(i, p, from, moved.oldPtypeO(), values);
479  }
480  }
481 
482  // adjust to
483  if (! moved.isCapture())
484  {
485  for (size_t i=0; i<offsets.size(); ++i) {
486  const Square target = to + offsets[i];
487  const Piece p = state.pieceAt(target);
488  if (! p.isPiece())
489  continue;
490  assert(!target.isPieceStand());
491  ret += value(i, p, to, moved.ptypeO(), values);
492  }
493  return ret;
494  }
495 
496  // adjust with capture
497  for (size_t i=0; i<offsets.size(); ++i) {
498  const Square target = to + offsets[i];
499  const Piece p = state.pieceAt(target);
500  if (! p.isPiece())
501  continue;
502  assert(!target.isPieceStand());
503  ret += value(i, p, to, moved.ptypeO(), values);
504  if (p.square() == to)
505  continue;
506  ret -= value(i, p, to, moved.capturePtypeO(), values);
507  }
508  const Offset diff = to - from;
509  int capture_i = offset_index[diff.index()];
510  if (capture_i >= 0)
511  ret -= value(capture_i, to, moved.capturePtypeO(), from, moved.oldPtypeO(), values);
512 
513  return ret;
514 }
515 
516 int osl::eval::ml::
517 PiecePair::valueCompiled(int offset_id, Square pos0, PtypeO p0, Square pos1, PtypeO p1)
518 {
519  assert(pos0 != pos1);
520  assert(! pos0.isPieceStand() && ! pos1.isPieceStand());
521  assert(pos0 - pos1 == offsets[offset_id]);
522 
523  return x_values[pos0.x()][ptypeOIndex(p0)][offset_id][ptypeOIndex(p1)]
524  + y_values[pos0.y()][ptypeOIndex(p0)][offset_id][ptypeOIndex(p1)];
525 }
526 
527 template <int Direction, int Offset>
528 inline int osl::eval::ml::
529 PiecePair::sum12One(const Piece *base_ptr,const int *xbase,const int *ybase)
530 {
531  const Piece p = *(base_ptr-Offset);
532  PtypeO p1=p.ptypeO();
533  return
534  *(xbase+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*Direction+p1)
535  + *(ybase+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*Direction+p1);
536 }
537 inline int osl::eval::ml::
538 PiecePair::sum12(NumEffectState const& state,Square base,PtypeO ptypeO)
539 {
540  const int *xbase= &x_values[base.x()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
541  const int *ybase= &y_values[base.y()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
542  const Piece* base_ptr= state.getPiecePtr(base);
543  return
544  sum12One<4,18>(base_ptr,xbase,ybase)+
545  + sum12One<3,17>(base_ptr,xbase,ybase)
546  + sum12One<2,16>(base_ptr,xbase,ybase)
547  + sum12One<1,15>(base_ptr,xbase,ybase)
548  + sum12One<0,14>(base_ptr,xbase,ybase)
549  + sum12One<5,1>(base_ptr,xbase,ybase)
550  + sum12One<11,-1>(base_ptr,xbase,ybase)
551  + sum12One<6,-14>(base_ptr,xbase,ybase)
552  + sum12One<7,-15>(base_ptr,xbase,ybase)
553  + sum12One<8,-16>(base_ptr,xbase,ybase)
554  + sum12One<9,-17>(base_ptr,xbase,ybase)
555  + sum12One<10,-18>(base_ptr,xbase,ybase);
556 }
557 
558 template<int Direction, int Offset>
559 inline int osl::eval::ml::
560 PiecePair::adjust12One(const Piece *base_ptr,const int *xbase1,const int *ybase1,const int *xbase2,const int *ybase2)
561 {
562  const Piece p = *(base_ptr-Offset);
563  PtypeO p1=p.ptypeO();
564  return
565  *(xbase1+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*Direction+p1)
566  + *(ybase1+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*Direction+p1)
567  - *(xbase2+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*Direction+p1)
568  - *(ybase2+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*Direction+p1);
569 }
570 
571 inline int osl::eval::ml::
573 {
574  const int *xbase1= &x_values[base.x()][ptypeOIndex(pos)][0][ptypeOIndex((PtypeO)0)];
575  const int *xbase2= &x_values[base.x()][ptypeOIndex(neg)][0][ptypeOIndex((PtypeO)0)];
576  const int *ybase1= &y_values[base.y()][ptypeOIndex(pos)][0][ptypeOIndex((PtypeO)0)];
577  const int *ybase2= &y_values[base.y()][ptypeOIndex(neg)][0][ptypeOIndex((PtypeO)0)];
578  const Piece* base_ptr= state.getPiecePtr(base);
579  return
580  adjust12One<4,18>(base_ptr,xbase1,ybase1,xbase2,ybase2)
581  + adjust12One<3,17>(base_ptr,xbase1,ybase1,xbase2,ybase2)
582  + adjust12One<2,16>(base_ptr,xbase1,ybase1,xbase2,ybase2)
583  + adjust12One<1,15>(base_ptr,xbase1,ybase1,xbase2,ybase2)
584  + adjust12One<0,14>(base_ptr,xbase1,ybase1,xbase2,ybase2)
585  + adjust12One<5,1>(base_ptr,xbase1,ybase1,xbase2,ybase2)
586  + adjust12One<11,-1>(base_ptr,xbase1,ybase1,xbase2,ybase2)
587  + adjust12One<6,-14>(base_ptr,xbase1,ybase1,xbase2,ybase2)
588  + adjust12One<7,-15>(base_ptr,xbase1,ybase1,xbase2,ybase2)
589  + adjust12One<8,-16>(base_ptr,xbase1,ybase1,xbase2,ybase2)
590  + adjust12One<9,-17>(base_ptr,xbase1,ybase1,xbase2,ybase2)
591  + adjust12One<10,-18>(base_ptr,xbase1,ybase1,xbase2,ybase2);
592 }
593 
594 int osl::eval::ml::
595 PiecePair::evalWithUpdateCompiled(const NumEffectState& state, Move moved, int last_value)
596 {
597  int ret = last_value;
598  const Square from = moved.from();
599  const Square to = moved.to();
600 
601  // adjust from
602  if (from.isPieceStand()) {
603  ret+=sum12(state,to,moved.ptypeO());
604  return ret;
605  }
606  else{
607  ret-=sum12(state,from,moved.oldPtypeO());
608  // adjust to
609  if (! moved.isCapture()) {
610  ret+=sum12(state,to,moved.ptypeO());
611  const Offset diff = to-from;
612  int capture_i = offset_index[diff.index()];
613  if (capture_i >= 0){
614  PtypeO ptypeO=moved.ptypeO();
615  const int *xbase= &x_values[to.x()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
616  const int *ybase= &y_values[to.y()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
617  PtypeO p1=moved.oldPtypeO();
618  ret+=
619  *(xbase+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*capture_i+p1)
620  + *(ybase+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*capture_i+p1);
621  }
622  return ret;
623  }
624  else{
625  // adjust with capture
626  ret+=adjust12(state,to,moved.ptypeO(),moved.capturePtypeO());
627  const Offset diff = to-from;
628  int capture_i = offset_index[diff.index()];
629  if (capture_i >= 0){
630  Square base=to;
631  PtypeO ptypeO1=moved.ptypeO();
632  PtypeO ptypeO2=moved.capturePtypeO();
633  const int *xbase1= &x_values[base.x()][ptypeOIndex(ptypeO1)][0][ptypeOIndex((PtypeO)0)];
634  const int *xbase2= &x_values[base.x()][ptypeOIndex(ptypeO2)][0][ptypeOIndex((PtypeO)0)];
635  const int *ybase1= &y_values[base.y()][ptypeOIndex(ptypeO1)][0][ptypeOIndex((PtypeO)0)];
636  const int *ybase2= &y_values[base.y()][ptypeOIndex(ptypeO2)][0][ptypeOIndex((PtypeO)0)];
637  PtypeO p1=moved.oldPtypeO();
638  ret+=
639  *(xbase1+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*capture_i+p1)
640  + *(ybase1+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*capture_i+p1)
641  - *(xbase2+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*capture_i+p1)
642  - *(ybase2+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*capture_i+p1);
643  }
644  return ret;
645  }
646  }
647 }
648 
649 int osl::eval::ml::
651 {
652  if (! p.isOnBoard())
653  return 0;
654  int ret = 0;
655  for (size_t i=0; i<offsets.size(); ++i) {
656  const Square target = p.square() + offsets[i];
657  const Piece q = state.pieceAt(target);
658  if (! q.isPiece()|| p == q)
659  continue;
660  assert(!target.isPieceStand());
661  assert(p.isOnBoard() && q.isOnBoard());
662  int v = value(i, q, p, values);
663  ret += v;
664  }
665  return ret;
666 }
667 
668 int osl::eval::ml::
669 PiecePair::pieceValue(const NumEffectState& state, Piece p, const Weights& values)
670 {
671  return pieceValueDouble(state, p, values)/2;
672 }
673 
674 /* ------------------------------------------------------------------------- */
675 // ;;; Local Variables:
676 // ;;; mode:c++
677 // ;;; c-basic-offset:2
678 // ;;; coding:utf-8
679 // ;;; End:
void fillBW(int index, int dir, Ptype p0, Ptype p1)
Definition: piecePair.cc:323
CArray< PiecePair::IndexTable, 10 > & y_table
Definition: piecePair.cc:36
int swapud(int offset_id)
Definition: piecePair.cc:57
bool isOnBoard() const
Definition: basic_type.h:985
static int pieceValue(const NumEffectState &state, Piece p, const Weights &values)
Definition: piecePair.cc:669
座標の差分
Definition: basic_type.h:429
static int sum12One(const Piece *basePtr, const int *xbase, const int *ybase)
Definition: piecePair.cc:529
PtypeO capturePtypeO() const
Definition: basic_type.h:1185
void fillSame(int index, int dir, Ptype p0, Ptype p1)
for same owner
Definition: piecePair.cc:332
bool isPiece() const
Definition: basic_type.h:953
const Piece pieceAt(Square sq) const
Definition: simpleState.h:167
PtypeO ptypeO() const
Definition: basic_type.h:824
CArray3d< int, PTYPEO_SIZE, 12, PTYPEO_SIZE > x_values[10]
Definition: piecePair.cc:290
int y() const
将棋としてのY座標を返す.
Definition: basic_type.h:567
static void compile(const Weights &values)
values を展開してクラス全体で使う
Definition: piecePair.cc:365
static int eval(const NumEffectState &, const Weights &)
Definition: piecePair.cc:450
PtypeO ptypeO() const
移動後のPtype, i.e., 成る手だった場合成った後
Definition: basic_type.h:1162
int value(size_t index) const
Definition: weights.h:27
const int PTYPEO_SIZE
Definition: basic_type.h:308
int x() const
将棋としてのX座標を返す.
Definition: basic_type.h:563
CArray< int, 0x200 > offset_index
Definition: piecePair.cc:33
static int valueCompiled(int offset_id, Piece p, Square p1, PtypeO o1)
Definition: piecePair.h:72
static int pindex(Player player, Ptype ptype)
Definition: piecePair.h:87
PtypeO newPtypeO(Player player, Ptype ptype)
Definition: basic_type.h:211
void setValue(size_t index, int value)
Definition: weights.h:31
Ptype
駒の種類を4ビットでコード化する
Definition: basic_type.h:83
const Piece pieceOf(int num) const
Definition: simpleState.h:76
bool isOnBoard() const
盤面上を表すかどうかの判定. 1<=x() && x()<=9 && 1<=y() && y()<=9 Squareの内部表現に依存する. ...
Definition: basic_type.h:583
static IndexTable plain_table
Definition: piecePair.h:93
const Square from() const
Definition: basic_type.h:1125
圧縮していない moveの表現 .
Definition: basic_type.h:1051
int swaplr(int offset_id)
Definition: piecePair.cc:50
static const int SIZE
Definition: basic_type.h:794
bool isPass() const
Definition: basic_type.h:1092
static CArray< IndexTable, 10 > y_table
Definition: piecePair.h:94
PiecePair::IndexTable & plain_table
Definition: piecePair.cc:34
利きを持つ局面
CArray< PiecePair::IndexTable, 10 > & x_table
Definition: piecePair.cc:35
static int adjust12(NumEffectState const &state, Square base, PtypeO pos, PtypeO neg)
Definition: piecePair.cc:572
static int adjust12One(const Piece *basePtr, const int *xbase1, const int *ybase1, const int *xbase2, const int *ybase2)
Definition: piecePair.cc:560
const Square square() const
Definition: basic_type.h:832
PtypeO
Player + Ptype [-15, 15] PtypeO の O は Owner の O.
Definition: basic_type.h:199
const Square to() const
Definition: basic_type.h:1132
static int pieceValueDouble(const NumEffectState &state, Piece p, const Weights &)
Definition: piecePair.cc:650
Direction
Definition: basic_type.h:310
PtypeO oldPtypeO() const
移動前のPtypeO, i.e., 成る手だった場合成る前
Definition: basic_type.h:1168
void fill(const T_simple &value=T_simple())
Definition: container.h:67
constexpr bool isPiece(Ptype ptype)
ptypeが空白やEDGEでないかのチェック
Definition: basic_type.h:120
CArray3d< int, PTYPEO_SIZE, 12, PTYPEO_SIZE > y_values[10]
Definition: piecePair.cc:290
static int evalWithUpdateCompiled(const NumEffectState &state, Move moved, int last_value)
Definition: piecePair.cc:595
static CArray< IndexTable, 10 > x_table
Definition: piecePair.h:94
Player
Definition: basic_type.h:8
static void sanitize(Weights &values)
Definition: piecePair.cc:396
static int evalWithUpdate(const NumEffectState &state, Move moved, int last_value, const Weights &values)
Definition: piecePair.cc:461
const Piece * getPiecePtr(Square sq) const
Definition: simpleState.h:169
static index_t index(int offset_id, Piece p, Piece q)
Definition: piecePair.cc:440
bool isPieceStand() const
Definition: basic_type.h:576
void fillDiffer(int index, int dir, Ptype p0, Ptype p1)
for different owner
Definition: piecePair.cc:338
static int sum12(NumEffectState const &state, Square base, PtypeO ptypeO)
Definition: piecePair.cc:538
unsigned int ptypeOIndex(PtypeO ptypeo)
Definition: basic_type.h:205
int pindex(Player player, Ptype ptype)
Definition: piecePair.cc:62
static const CArray< Offset, 12 > offsets
Definition: piecePair.h:95
int inv(int offset_id)
Definition: piecePair.cc:45
bool isCapture() const
Definition: basic_type.h:1148