piecePair.cc
Go to the documentation of this file.
00001 /* piecePair.cc
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   // positive offset [0,5]
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   // negative offset [6,11]
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           // same player
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); // UUL
00078             plain_table.fillSame(index, 10, p0, p1); // UUR
00079             if (p0 != p1) {
00080               ++index;
00081               plain_table.fillSame(index,  0, p1, p0); // UUL
00082               plain_table.fillSame(index, 10, p1, p0); // UUR
00083             }
00084 
00085             ++index;
00086             plain_table.fillSame(index, 1, p0, p1); // UL
00087             plain_table.fillSame(index, 9, p0, p1); // UR
00088             if (p0 != p1) {
00089               ++index;
00090               plain_table.fillSame(index, 1, p1, p0); // UR
00091               plain_table.fillSame(index, 9, p1, p0); // UL
00092             }
00093             
00094             ++index;
00095             plain_table.fillSame(index, 2, p0, p1); // L
00096             plain_table.fillSame(index, 8, p0, p1); // R
00097             if (p0 != p1) { // use the same index as L
00098               plain_table.fillSame(index, 2, p1, p0); // L
00099               plain_table.fillSame(index, 8, p1, p0); // R
00100             }
00101             
00102             ++index;
00103             plain_table.fillSame(index, 11, p0, p1); // U
00104             if (p0 != p1) {
00105               plain_table.fillSame(index, 11, p1, p0); // U
00106             }
00107           }
00108           // different player
00109           {
00110             // UUL, UUR
00111             ++index;
00112             plain_table.fillDiffer(index, 0, p0, p1); // UUL
00113             plain_table.fillDiffer(index, 10, p0, p1); // UUR
00114             ++index;
00115             plain_table.fillDiffer(index, inv(0), p0, p1); // UUL^-1
00116             plain_table.fillDiffer(index, inv(10), p0, p1); // UUR^-1
00117 
00118             // UL, UR
00119             ++index;
00120             plain_table.fillDiffer(index, 1, p0, p1); // UL
00121             plain_table.fillDiffer(index, 9, p0, p1); // UR
00122             ++index;
00123             // DR, DL
00124             plain_table.fillDiffer(index, inv(1), p0, p1); // DR
00125             plain_table.fillDiffer(index, inv(9), p0, p1); // DL
00126 
00127             // LR
00128             ++index;
00129             plain_table.fillDiffer(index, 2, p0, p1); // L
00130             plain_table.fillDiffer(index, inv(2), p0, p1); // R, use the same index as L
00131 
00132             // UD
00133             ++index;
00134             plain_table.fillDiffer(index, 11, p0, p1); // U
00135 
00136             ++index;
00137             plain_table.fillDiffer(index, inv(11), p0, p1); // D
00138           }
00139         }
00140       }  
00141       assert(index+1 == PiecePair::plain_table_size);
00142     }
00143     void makeTableX()
00144     {
00145       // currently only for same player
00146       int index = 0;
00147       // make leftside
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             // (UUL, DDL), (UL, DL)
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             // L
00160             ++index;
00161             x_table[x][2][pi0][pi1] = index;
00162             // U, D
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           } // x
00170         }
00171       }
00172       // make rightside
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             // (UUL, DDL), (UL, DL) => (DDR, UUR), (DR, UR)
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             // L => R
00184             x_table[x-1][swaplr(2)][pi1][pi0] = x_table[x][2][pi0][pi1];
00185           }
00186           // flip col 5
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       // mirror to [6,9]
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           } // x
00204         }
00205       }
00206       // make white player
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       // only for same player
00231       int index = 0;
00232       // for upside direction
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           // same player
00238           for (int y=1; y<=9; ++y) {
00239             for (int d=0; d<2; ++d) { // (UUL, UUR), (UL, UR)
00240               ++index;
00241               y_table[y][d][pi0][pi1] = index;
00242               y_table[y][swaplr(d)][pi0][pi1] = index;
00243             }
00244             // (L, R)
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             // U
00251             ++index;
00252             y_table[y][11][pi0][pi1] = index;
00253           } // y
00254         }
00255       }
00256       // flip for downside direction
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             // (UUL, UUR), 
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             // (UL, UR)
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             // U
00269             y_table[wrap9(y+1)][inv(11)][pi1][pi0] = y_table[y][11][pi0][pi1];
00270           } // y
00271         }
00272       }
00273       // make white player
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]; // plain_values は xに折込
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; // normal
00330   (*this)[inv(dir)][pi0w][pi1w] = -index; // white
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); // swapped order
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; // swapped piece
00346   (*this)[inv(dir)][pi1][pi0w] = -index; // swapped player
00347   (*this)[dir][pi0w][pi1] = -index; // swapped player, swapped piece
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 Square pos1(x,y);
00403       for (size_t i=0; i<offsets.size(); ++i) {
00404         const Square 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, Square pos0, PtypeO p0, Square 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.square(), p.ptypeO(), q.square(), 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.pieceOf(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 Square from = moved.from();
00469   const Square to = moved.to();  
00470 
00471   // adjust from
00472   if (! from.isPieceStand()) {
00473     for (size_t i=0; i<offsets.size(); ++i) {
00474       const Square target = from + offsets[i];
00475       const Piece p = state.pieceAt(target);
00476       if (! p.isPiece() || p.square() == to)
00477         continue;
00478       assert(!target.isPieceStand());
00479       ret -= value(i, p, from, moved.oldPtypeO(), values);      
00480     }  
00481   }
00482   
00483   // adjust to
00484   if (! moved.isCapture()) 
00485   {  
00486     for (size_t i=0; i<offsets.size(); ++i) {
00487       const Square target = to + offsets[i];
00488       const Piece p = state.pieceAt(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   // adjust with capture
00498   for (size_t i=0; i<offsets.size(); ++i) {
00499     const Square target = to + offsets[i];
00500     const Piece p = state.pieceAt(target);
00501     if (! p.isPiece())
00502       continue;
00503     assert(!target.isPieceStand());
00504     ret += value(i, p, to, moved.ptypeO(), values);      
00505     if (p.square() == 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, Square pos0, PtypeO p0, Square 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,Square 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,Square 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 Square from = moved.from();
00600   const Square to = moved.to();  
00601 
00602   // adjust from
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     // adjust to
00610     if (! moved.isCapture()) {
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       // adjust with capture
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         Square 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 Square target = p.square() + offsets[i];
00658     const Piece q = state.pieceAt(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 // ;;; Local Variables:
00677 // ;;; mode:c++
00678 // ;;; c-basic-offset:2
00679 // ;;; coding:utf-8
00680 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines