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