00001
00002
00003 #include "osl/eval/piecePair.h"
00004
00005 osl::eval::ml::PiecePair::IndexTable osl::eval::ml::PiecePair::plain_table;
00006 osl::CArray<osl::eval::ml::PiecePair::IndexTable, 10> osl::eval::ml::PiecePair::x_table,
00007 osl::eval::ml::PiecePair::y_table;
00008 const osl::CArray<osl::Offset, 12> osl::eval::ml::PiecePair::offsets = {
00009
00010 DirectionPlayerTraits<UUL, BLACK>::offset(),
00011 DirectionPlayerTraits<UL, BLACK>::offset(),
00012 DirectionPlayerTraits<L, BLACK>::offset(),
00013 DirectionPlayerTraits<DL, BLACK>::offset(),
00014 DirectionPlayerTraits<UUR, WHITE>::offset(),
00015 DirectionPlayerTraits<D, BLACK>::offset(),
00016
00017 DirectionPlayerTraits<UUL, WHITE>::offset(),
00018 DirectionPlayerTraits<DR, BLACK>::offset(),
00019 DirectionPlayerTraits<R, BLACK>::offset(),
00020 DirectionPlayerTraits<UR, BLACK>::offset(),
00021 DirectionPlayerTraits<UUR, BLACK>::offset(),
00022 DirectionPlayerTraits<U, BLACK>::offset(),
00023 };
00024
00025 namespace osl
00026 {
00027 namespace eval
00028 {
00029 namespace ml
00030 {
00031 namespace ppair
00032 {
00033 CArray<int, 0x200> offset_index;
00034 PiecePair::IndexTable& plain_table = PiecePair::plain_table;
00035 CArray<PiecePair::IndexTable, 10>& x_table = PiecePair::x_table;
00036 CArray<PiecePair::IndexTable, 10>& y_table = PiecePair::y_table;
00037
00038 void makeOffsetIndex()
00039 {
00040 offset_index.fill(-1);
00041 for (size_t i=0; i<PiecePair::offsets.size(); ++i) {
00042 offset_index[PiecePair::offsets[i].index()] = i;
00043 }
00044 }
00045 inline int inv(int offset_id)
00046 {
00047 assert(offset_id >= 0 && offset_id < 12);
00048 return (offset_id + 6) % 12;
00049 }
00050 inline int swaplr(int offset_id)
00051 {
00052 assert(offset_id >= 0 && offset_id < 12);
00053 if (offset_id == 11)
00054 return 11;
00055 return 10 - offset_id;
00056 }
00057 inline int swapud(int offset_id)
00058 {
00059 assert(offset_id >= 0 && offset_id < 12);
00060 return swaplr(inv(offset_id));
00061 }
00062 int pindex(Player player, Ptype ptype) { return PiecePair::IndexTable::pindex(player, ptype); }
00063 void makeTable()
00064 {
00065 int index = 0;
00066 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00067 for (int ip1=ip0; ip1<=PTYPE_MAX; ++ip1) {
00068 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00069
00070 {
00071 #ifndef NDEBUG
00072 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00073 assert(plain_table[0][pi0][pi1] == 0);
00074 #endif
00075 ++index;
00076 plain_table.fillSame(index, 0, p0, p1);
00077 plain_table.fillSame(index, 10, p0, p1);
00078 if (p0 != p1) {
00079 ++index;
00080 plain_table.fillSame(index, 0, p1, p0);
00081 plain_table.fillSame(index, 10, p1, p0);
00082 }
00083
00084 ++index;
00085 plain_table.fillSame(index, 1, p0, p1);
00086 plain_table.fillSame(index, 9, p0, p1);
00087 if (p0 != p1) {
00088 ++index;
00089 plain_table.fillSame(index, 1, p1, p0);
00090 plain_table.fillSame(index, 9, p1, p0);
00091 }
00092
00093 ++index;
00094 plain_table.fillSame(index, 2, p0, p1);
00095 plain_table.fillSame(index, 8, p0, p1);
00096 if (p0 != p1) {
00097 plain_table.fillSame(index, 2, p1, p0);
00098 plain_table.fillSame(index, 8, p1, p0);
00099 }
00100
00101 ++index;
00102 plain_table.fillSame(index, 11, p0, p1);
00103 if (p0 != p1) {
00104 plain_table.fillSame(index, 11, p1, p0);
00105 }
00106 }
00107
00108 {
00109
00110 ++index;
00111 plain_table.fillDiffer(index, 0, p0, p1);
00112 plain_table.fillDiffer(index, 10, p0, p1);
00113 ++index;
00114 plain_table.fillDiffer(index, inv(0), p0, p1);
00115 plain_table.fillDiffer(index, inv(10), p0, p1);
00116
00117
00118 ++index;
00119 plain_table.fillDiffer(index, 1, p0, p1);
00120 plain_table.fillDiffer(index, 9, p0, p1);
00121 ++index;
00122
00123 plain_table.fillDiffer(index, inv(1), p0, p1);
00124 plain_table.fillDiffer(index, inv(9), p0, p1);
00125
00126
00127 ++index;
00128 plain_table.fillDiffer(index, 2, p0, p1);
00129 plain_table.fillDiffer(index, inv(2), p0, p1);
00130
00131
00132 ++index;
00133 plain_table.fillDiffer(index, 11, p0, p1);
00134
00135 ++index;
00136 plain_table.fillDiffer(index, inv(11), p0, p1);
00137 }
00138 }
00139 }
00140 assert(index+1 == PiecePair::plain_table_size);
00141 }
00142 void makeTableX()
00143 {
00144
00145 int index = 0;
00146
00147 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00148 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00149 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00150 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00151 for (int x=1; x<=5; ++x) {
00152
00153 for (int d=0; d<2; ++d) {
00154 ++index;
00155 x_table[x][d][pi0][pi1] = index;
00156 x_table[x][swapud(d)][pi0][pi1] = index;
00157 }
00158
00159 ++index;
00160 x_table[x][2][pi0][pi1] = index;
00161
00162 ++index;
00163 x_table[x][11][pi0][pi1] = index;
00164 x_table[x][inv(11)][pi1][pi0] = index;
00165 ++index;
00166 x_table[x][5][pi0][pi1] = index;
00167 x_table[x][inv(5)][pi1][pi0] = index;
00168 }
00169 }
00170 }
00171
00172 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00173 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00174 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00175 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00176 for (int x=2; x<=5; ++x) {
00177
00178 for (int d=0; d<2; ++d) {
00179 x_table[x-1][inv(d)][pi1][pi0] = x_table[x][d][pi0][pi1];
00180 x_table[x-1][inv(swapud(d))][pi1][pi0] = x_table[x][swapud(d)][pi0][pi1];
00181 }
00182
00183 x_table[x-1][swaplr(2)][pi1][pi0] = x_table[x][2][pi0][pi1];
00184 }
00185
00186 for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
00187 if (swaplr(d) == (int)d || x_table[5][d][pi0][pi1] == 0)
00188 continue;
00189 x_table[5][swaplr(d)][pi0][pi1] = x_table[5][d][pi0][pi1];
00190 }
00191 }
00192 }
00193
00194 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00195 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00196 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00197 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00198 for (int x=6; x<=9; ++x) {
00199 for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
00200 x_table[x][d][pi0][pi1] = x_table[10-x][swaplr(d)][pi0][pi1];
00201 }
00202 }
00203 }
00204 }
00205
00206 for (int x=1; x<=9; ++x) {
00207 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00208 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00209 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00210 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00211 const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
00212 for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
00213 assert(x_table[x][d][pi0][pi1]);
00214 x_table[10-x][inv(d)][pi0w][pi1w] = -x_table[x][d][pi0][pi1];
00215 }
00216 }
00217 }
00218 }
00219 assert(PiecePair::x_table_size == index+1);
00220 for (int x=1; x<=9; ++x)
00221 x_table[x].amplify(PiecePair::plain_table_size);
00222 }
00223 int wrap9(int y)
00224 {
00225 return (y-1)%9 + 1;
00226 }
00227 void makeTableY()
00228 {
00229
00230 int index = 0;
00231
00232 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00233 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00234 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00235 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00236
00237 for (int y=1; y<=9; ++y) {
00238 for (int d=0; d<2; ++d) {
00239 ++index;
00240 y_table[y][d][pi0][pi1] = index;
00241 y_table[y][swaplr(d)][pi0][pi1] = index;
00242 }
00243
00244 ++index;
00245 y_table[y][2][pi0][pi1] = index;
00246 y_table[y][2][pi1][pi0] = index;
00247 y_table[y][swaplr(2)][pi0][pi1] = index;
00248 y_table[y][swaplr(2)][pi1][pi0] = index;
00249
00250 ++index;
00251 y_table[y][11][pi0][pi1] = index;
00252 }
00253 }
00254 }
00255
00256 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00257 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00258 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00259 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00260 for (int y=1; y<=9; ++y) {
00261
00262 y_table[wrap9(y+2)][inv(0)][pi1][pi0] = y_table[y][0][pi0][pi1];
00263 y_table[wrap9(y+2)][inv(swaplr(0))][pi1][pi0] = y_table[y][swaplr(0)][pi0][pi1];
00264
00265 y_table[wrap9(y+1)][inv(1)][pi1][pi0] = y_table[y][1][pi0][pi1];
00266 y_table[wrap9(y+1)][inv(swaplr(1))][pi1][pi0] = y_table[y][swaplr(1)][pi0][pi1];
00267
00268 y_table[wrap9(y+1)][inv(11)][pi1][pi0] = y_table[y][11][pi0][pi1];
00269 }
00270 }
00271 }
00272
00273 for (int ip0=PTYPE_PIECE_MIN; ip0<=PTYPE_MAX; ++ip0) {
00274 for (int ip1=PTYPE_PIECE_MIN; ip1<=PTYPE_MAX; ++ip1) {
00275 const Ptype p0 = static_cast<Ptype>(ip0), p1 = static_cast<Ptype>(ip1);
00276 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00277 const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
00278 for (int y=1; y<=9; ++y) {
00279 for (size_t d=0; d<PiecePair::offsets.size(); ++d) {
00280 y_table[10-y][inv(d)][pi0w][pi1w] = -y_table[y][d][pi0][pi1];
00281 }
00282 }
00283 }
00284 }
00285 assert(PiecePair::y_table_size == index+1);
00286 for (int y=1; y<=9; ++y)
00287 y_table[y].amplify(PiecePair::plain_table_size+PiecePair::x_table_size);
00288 }
00289
00290 CArray3d<int, PTYPEO_SIZE, 12, PTYPEO_SIZE> x_values[10], y_values[10];
00291 }
00292 using namespace ppair;
00293 }
00294 }
00295 }
00296
00297
00298 osl::eval::ml::
00299 PiecePair::IndexTable::IndexTable()
00300 {
00301 fill(0);
00302 }
00303
00304 void osl::eval::ml::
00305 PiecePair::IndexTable::amplify(int base)
00306 {
00307 for (size_t d=0; d<offsets.size(); ++d) {
00308 for (int ip0=0; ip0<PTYPEO_SIZE; ++ip0) {
00309 for (int ip1=0; ip1<PTYPEO_SIZE; ++ip1) {
00310 signed short& target = (*this)[d][ip0][ip1];
00311 if (target > 0) {
00312 target += base;
00313 }
00314 else if (target < 0)
00315 {
00316 target -= base;
00317 }
00318 }
00319 }
00320 }
00321 }
00322 void osl::eval::ml::
00323 PiecePair::IndexTable::fillBW(int index, int dir, Ptype p0, Ptype p1)
00324 {
00325 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00326 const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
00327
00328 (*this)[dir][pi0][pi1] = index;
00329 (*this)[inv(dir)][pi0w][pi1w] = -index;
00330 }
00331 void osl::eval::ml::
00332 PiecePair::IndexTable::fillSame(int index, int dir, Ptype p0, Ptype p1)
00333 {
00334 fillBW(index, dir, p0, p1);
00335 fillBW(index, inv(dir), p1, p0);
00336 }
00337 void osl::eval::ml::
00338 PiecePair::IndexTable::fillDiffer(int index, int dir, Ptype p0, Ptype p1)
00339 {
00340 const int pi0 = pindex(BLACK, p0), pi1 = pindex(BLACK, p1);
00341 const int pi0w = pindex(WHITE, p0), pi1w = pindex(WHITE, p1);
00342
00343 (*this)[inv(dir)][pi0][pi1w] = index;
00344 (*this)[dir][pi1w][pi0] = index;
00345 (*this)[inv(dir)][pi1][pi0w] = -index;
00346 (*this)[dir][pi0w][pi1] = -index;
00347 }
00348
00349
00350
00351 void osl::eval::ml::
00352 PiecePair::init()
00353 {
00354 static bool initialized = false;
00355 if (initialized)
00356 return;
00357 initialized = true;
00358 makeOffsetIndex();
00359 makeTable();
00360 makeTableX();
00361 makeTableY();
00362 }
00363
00364 void osl::eval::ml::
00365 PiecePair::compile(const Weights& weights)
00366 {
00367 for (int i=1; i<=9; ++i) {
00368 x_values[i].fill(0);
00369 y_values[i].fill(0);
00370 }
00371 for (size_t d=0; d<offsets.size(); ++d) {
00372 for (int ip0=0; ip0<PTYPEO_SIZE; ++ip0) {
00373 for (int ip1=0; ip1<PTYPEO_SIZE; ++ip1) {
00374 int plain = 0;
00375 if (plain_table[d][ip0][ip1] > 0)
00376 plain = weights.value(plain_table[d][ip0][ip1]);
00377 else if (plain_table[d][ip0][ip1] < 0)
00378 plain = -weights.value(-plain_table[d][ip0][ip1]);
00379 for (int i=1; i<=9; ++i) {
00380 x_values[i][ip0][d][ip1] = plain;
00381 if (x_table[i][d][ip0][ip1] > 0)
00382 x_values[i][ip0][d][ip1] += weights.value(x_table[i][d][ip0][ip1]);
00383 else if (x_table[i][d][ip0][ip1] < 0)
00384 x_values[i][ip0][d][ip1] += -weights.value(-x_table[i][d][ip0][ip1]);
00385 if (y_table[i][d][ip0][ip1] > 0)
00386 y_values[i][ip0][d][ip1] = weights.value(y_table[i][d][ip0][ip1]);
00387 else if (y_table[i][d][ip0][ip1] < 0)
00388 y_values[i][ip0][d][ip1] = -weights.value(-y_table[i][d][ip0][ip1]);
00389 }
00390 }
00391 }
00392 }
00393 }
00394
00395 void osl::eval::ml::
00396 PiecePair::sanitize(Weights& values)
00397 {
00398 values.setValue(0,0);
00399 for (int x=1; x<=9; ++x) {
00400 for (int y=1; y<=9; ++y) {
00401 const Square pos1(x,y);
00402 for (size_t i=0; i<offsets.size(); ++i) {
00403 const Square pos0 = pos1+offsets[i];
00404 if (! pos0.isOnBoard())
00405 continue;
00406 for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p) {
00407 const Ptype ptype = static_cast<Ptype>(p);
00408 assert(isPiece(ptype));
00409 index_t idx = index(i, pos0, newPtypeO(BLACK, ptype), pos1, newPtypeO(WHITE, ptype));
00410 values.setValue(abs(idx[0]), 0);
00411 idx = index(i, pos0, newPtypeO(WHITE, ptype), pos1, newPtypeO(BLACK, ptype));
00412 values.setValue(abs(idx[0]), 0);
00413 }
00414 }
00415 }
00416 }
00417 }
00418
00419 osl::eval::ml::PiecePair::index_t osl::eval::ml::
00420 PiecePair::index(int offset_id, Square pos0, PtypeO p0, Square pos1, PtypeO p1)
00421 {
00422 assert(pos0 != pos1);
00423 assert(! pos0.isPieceStand() && ! pos1.isPieceStand());
00424
00425 assert(pos0 - pos1 == offsets[offset_id]);
00426 index_t ret = {
00427 plain_table[offset_id][ptypeOIndex(p0)][ptypeOIndex(p1)],
00428 x_table[pos0.x()][offset_id][ptypeOIndex(p0)][ptypeOIndex(p1)],
00429 y_table[pos0.y()][offset_id][ptypeOIndex(p0)][ptypeOIndex(p1)],
00430 };
00431 assert(abs(ret[0]) < plain_table_size);
00432 assert(abs(ret[1]) < plain_table_size + x_table_size);
00433 assert(abs(ret[2]) < plain_table_size + x_table_size + y_table_size);
00434 assert(ret[1] == 0 || abs(ret[1]) > plain_table_size);
00435 assert(ret[2] == 0 || abs(ret[2]) > plain_table_size + x_table_size);
00436 return ret;
00437 }
00438
00439 osl::eval::ml::PiecePair::index_t osl::eval::ml::
00440 PiecePair::index(int offset_id, Piece p, Piece q)
00441 {
00442 assert(p.isPiece());
00443 assert(q.isPiece());
00444 assert(p != q);
00445 assert(p.isOnBoard() && q.isOnBoard());
00446 return index(offset_id, p.square(), p.ptypeO(), q.square(), q.ptypeO());
00447 }
00448
00449 int osl::eval::ml::
00450 PiecePair::eval(const NumEffectState& state, const Weights& values)
00451 {
00452 int ret = 0;
00453 for (int i=0; i<Piece::SIZE; i++) {
00454 const Piece p = state.pieceOf(i);
00455 ret += pieceValueDouble(state, p, values);
00456 }
00457 return ret/2;
00458 }
00459
00460 int osl::eval::ml::
00461 PiecePair::evalWithUpdate(const NumEffectState& state, Move moved, int last_value, const Weights& values)
00462 {
00463 if (moved.isPass())
00464 return last_value;
00465
00466 int ret = last_value;
00467 const Square from = moved.from();
00468 const Square to = moved.to();
00469
00470
00471 if (! from.isPieceStand()) {
00472 for (size_t i=0; i<offsets.size(); ++i) {
00473 const Square target = from + offsets[i];
00474 const Piece p = state.pieceAt(target);
00475 if (! p.isPiece() || p.square() == to)
00476 continue;
00477 assert(!target.isPieceStand());
00478 ret -= value(i, p, from, moved.oldPtypeO(), values);
00479 }
00480 }
00481
00482
00483 if (! moved.isCapture())
00484 {
00485 for (size_t i=0; i<offsets.size(); ++i) {
00486 const Square target = to + offsets[i];
00487 const Piece p = state.pieceAt(target);
00488 if (! p.isPiece())
00489 continue;
00490 assert(!target.isPieceStand());
00491 ret += value(i, p, to, moved.ptypeO(), values);
00492 }
00493 return ret;
00494 }
00495
00496
00497 for (size_t i=0; i<offsets.size(); ++i) {
00498 const Square target = to + offsets[i];
00499 const Piece p = state.pieceAt(target);
00500 if (! p.isPiece())
00501 continue;
00502 assert(!target.isPieceStand());
00503 ret += value(i, p, to, moved.ptypeO(), values);
00504 if (p.square() == to)
00505 continue;
00506 ret -= value(i, p, to, moved.capturePtypeO(), values);
00507 }
00508 const Offset diff = to - from;
00509 int capture_i = offset_index[diff.index()];
00510 if (capture_i >= 0)
00511 ret -= value(capture_i, to, moved.capturePtypeO(), from, moved.oldPtypeO(), values);
00512
00513 return ret;
00514 }
00515
00516 int osl::eval::ml::
00517 PiecePair::valueCompiled(int offset_id, Square pos0, PtypeO p0, Square pos1, PtypeO p1)
00518 {
00519 assert(pos0 != pos1);
00520 assert(! pos0.isPieceStand() && ! pos1.isPieceStand());
00521 assert(pos0 - pos1 == offsets[offset_id]);
00522
00523 return x_values[pos0.x()][ptypeOIndex(p0)][offset_id][ptypeOIndex(p1)]
00524 + y_values[pos0.y()][ptypeOIndex(p0)][offset_id][ptypeOIndex(p1)];
00525 }
00526
00527 template <int Direction, int Offset>
00528 inline int osl::eval::ml::
00529 PiecePair::sum12One(const Piece *base_ptr,const int *xbase,const int *ybase)
00530 {
00531 const Piece p = *(base_ptr-Offset);
00532 PtypeO p1=p.ptypeO();
00533 return
00534 *(xbase+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*Direction+p1)
00535 + *(ybase+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*Direction+p1);
00536 }
00537 inline int osl::eval::ml::
00538 PiecePair::sum12(NumEffectState const& state,Square base,PtypeO ptypeO)
00539 {
00540 const int *xbase= &x_values[base.x()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
00541 const int *ybase= &y_values[base.y()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
00542 const Piece* base_ptr= state.getPiecePtr(base);
00543 return
00544 sum12One<4,18>(base_ptr,xbase,ybase)+
00545 + sum12One<3,17>(base_ptr,xbase,ybase)
00546 + sum12One<2,16>(base_ptr,xbase,ybase)
00547 + sum12One<1,15>(base_ptr,xbase,ybase)
00548 + sum12One<0,14>(base_ptr,xbase,ybase)
00549 + sum12One<5,1>(base_ptr,xbase,ybase)
00550 + sum12One<11,-1>(base_ptr,xbase,ybase)
00551 + sum12One<6,-14>(base_ptr,xbase,ybase)
00552 + sum12One<7,-15>(base_ptr,xbase,ybase)
00553 + sum12One<8,-16>(base_ptr,xbase,ybase)
00554 + sum12One<9,-17>(base_ptr,xbase,ybase)
00555 + sum12One<10,-18>(base_ptr,xbase,ybase);
00556 }
00557
00558 template<int Direction, int Offset>
00559 inline int osl::eval::ml::
00560 PiecePair::adjust12One(const Piece *base_ptr,const int *xbase1,const int *ybase1,const int *xbase2,const int *ybase2)
00561 {
00562 const Piece p = *(base_ptr-Offset);
00563 PtypeO p1=p.ptypeO();
00564 return
00565 *(xbase1+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*Direction+p1)
00566 + *(ybase1+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*Direction+p1)
00567 - *(xbase2+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*Direction+p1)
00568 - *(ybase2+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*Direction+p1);
00569 }
00570
00571 inline int osl::eval::ml::
00572 PiecePair::adjust12(NumEffectState const& state,Square base,PtypeO pos,PtypeO neg)
00573 {
00574 const int *xbase1= &x_values[base.x()][ptypeOIndex(pos)][0][ptypeOIndex((PtypeO)0)];
00575 const int *xbase2= &x_values[base.x()][ptypeOIndex(neg)][0][ptypeOIndex((PtypeO)0)];
00576 const int *ybase1= &y_values[base.y()][ptypeOIndex(pos)][0][ptypeOIndex((PtypeO)0)];
00577 const int *ybase2= &y_values[base.y()][ptypeOIndex(neg)][0][ptypeOIndex((PtypeO)0)];
00578 const Piece* base_ptr= state.getPiecePtr(base);
00579 return
00580 adjust12One<4,18>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00581 + adjust12One<3,17>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00582 + adjust12One<2,16>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00583 + adjust12One<1,15>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00584 + adjust12One<0,14>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00585 + adjust12One<5,1>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00586 + adjust12One<11,-1>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00587 + adjust12One<6,-14>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00588 + adjust12One<7,-15>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00589 + adjust12One<8,-16>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00590 + adjust12One<9,-17>(base_ptr,xbase1,ybase1,xbase2,ybase2)
00591 + adjust12One<10,-18>(base_ptr,xbase1,ybase1,xbase2,ybase2);
00592 }
00593
00594 int osl::eval::ml::
00595 PiecePair::evalWithUpdateCompiled(const NumEffectState& state, Move moved, int last_value)
00596 {
00597 int ret = last_value;
00598 const Square from = moved.from();
00599 const Square to = moved.to();
00600
00601
00602 if (from.isPieceStand()) {
00603 ret+=sum12(state,to,moved.ptypeO());
00604 return ret;
00605 }
00606 else{
00607 ret-=sum12(state,from,moved.oldPtypeO());
00608
00609 if (! moved.isCapture()) {
00610 ret+=sum12(state,to,moved.ptypeO());
00611 const Offset diff = to-from;
00612 int capture_i = offset_index[diff.index()];
00613 if (capture_i >= 0){
00614 PtypeO ptypeO=moved.ptypeO();
00615 const int *xbase= &x_values[to.x()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
00616 const int *ybase= &y_values[to.y()][ptypeOIndex(ptypeO)][0][ptypeOIndex((PtypeO)0)];
00617 PtypeO p1=moved.oldPtypeO();
00618 ret+=
00619 *(xbase+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*capture_i+p1)
00620 + *(ybase+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*capture_i+p1);
00621 }
00622 return ret;
00623 }
00624 else{
00625
00626 ret+=adjust12(state,to,moved.ptypeO(),moved.capturePtypeO());
00627 const Offset diff = to-from;
00628 int capture_i = offset_index[diff.index()];
00629 if (capture_i >= 0){
00630 Square base=to;
00631 PtypeO ptypeO1=moved.ptypeO();
00632 PtypeO ptypeO2=moved.capturePtypeO();
00633 const int *xbase1= &x_values[base.x()][ptypeOIndex(ptypeO1)][0][ptypeOIndex((PtypeO)0)];
00634 const int *xbase2= &x_values[base.x()][ptypeOIndex(ptypeO2)][0][ptypeOIndex((PtypeO)0)];
00635 const int *ybase1= &y_values[base.y()][ptypeOIndex(ptypeO1)][0][ptypeOIndex((PtypeO)0)];
00636 const int *ybase2= &y_values[base.y()][ptypeOIndex(ptypeO2)][0][ptypeOIndex((PtypeO)0)];
00637 PtypeO p1=moved.oldPtypeO();
00638 ret+=
00639 *(xbase1+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*capture_i+p1)
00640 + *(ybase1+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*capture_i+p1)
00641 - *(xbase2+(&x_values[0][0][1][0]-&x_values[0][0][0][0])*capture_i+p1)
00642 - *(ybase2+(&y_values[0][0][1][0]-&y_values[0][0][0][0])*capture_i+p1);
00643 }
00644 return ret;
00645 }
00646 }
00647 }
00648
00649 int osl::eval::ml::
00650 PiecePair::pieceValueDouble(const NumEffectState& state, Piece p, const Weights& values)
00651 {
00652 if (! p.isOnBoard())
00653 return 0;
00654 int ret = 0;
00655 for (size_t i=0; i<offsets.size(); ++i) {
00656 const Square target = p.square() + offsets[i];
00657 const Piece q = state.pieceAt(target);
00658 if (! q.isPiece()|| p == q)
00659 continue;
00660 assert(!target.isPieceStand());
00661 assert(p.isOnBoard() && q.isOnBoard());
00662 int v = value(i, q, p, values);
00663 ret += v;
00664 }
00665 return ret;
00666 }
00667
00668 int osl::eval::ml::
00669 PiecePair::pieceValue(const NumEffectState& state, Piece p, const Weights& values)
00670 {
00671 return pieceValueDouble(state, p, values)/2;
00672 }
00673
00674
00675
00676
00677
00678
00679