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