patternGroup.cc
Go to the documentation of this file.
00001 /* patternGroup.cc
00002  */
00003 #include "osl/rating/group/patternGroup.h"
00004 #include <sstream>
00005 
00006 osl::rating::PatternGroup::PatternGroup(Direction d, Direction d2) 
00007   : Group(name(d, d2)), direction(d), direction2(d2)
00008 {
00009   for (int attack=0; attack<3; ++attack) {
00010     for (int defense=0; defense<3; ++defense) {
00011       for (int s=PTYPE_PIECE_MIN; s<= PTYPE_MAX; ++s) {
00012         for (int t=PTYPE_PIECE_MIN; t<= PTYPE_MAX; ++t) {
00013           push_back(new Pattern(d, d2, static_cast<Ptype>(s), static_cast<Ptype>(t), true, attack, defense));
00014           push_back(new Pattern(d, d2, static_cast<Ptype>(s), static_cast<Ptype>(t), false, attack, defense));
00015         }
00016         push_back(new Pattern(d, d2, static_cast<Ptype>(s), PTYPE_EMPTY, true, attack, defense));
00017         push_back(new Pattern(d, d2, static_cast<Ptype>(s), PTYPE_EDGE, true, attack, defense)); // redundant
00018       }
00019     }
00020   }
00021   target_table.fill(0);
00022   for (int x=1; x<=9; ++x) {
00023     for (int y=1; y<=9; ++y) {
00024       const Square src(x,y);
00025       const Square target_b = Pattern::nextSquare(BLACK, src, direction, direction2);
00026       const Square target_w = Pattern::nextSquare(WHITE, src, direction, direction2);
00027       target_table[playerToIndex(BLACK)][src.index()] = target_b.uintValue();
00028       target_table[playerToIndex(WHITE)][src.index()] = target_w.uintValue();
00029     }
00030   }
00031 }
00032 
00033 int osl::rating::PatternGroup::findMatch(const NumEffectState& state, Move move, const RatingEnv& env) const
00034 {
00035   const Ptype self = move.ptype();
00036   const Square position
00037     = Square::makeDirect(target_table[playerToIndex(move.player())][move.to().index()]);
00038   assert(position == Pattern::nextSquare(move, direction, direction2));
00039   const Piece p = (position == move.from()) ? Piece::EMPTY() : state.pieceAt(position);
00040   const Ptype target = p.ptype();
00041   if (env.pattern_cache[position.index()] < 0)
00042     env.pattern_cache[position.index()] = CountEffect2::index(state, position, env) 
00043       * (PTYPE_MAX+1-PTYPE_PIECE_MIN) * ((PTYPE_MAX+1 - PTYPE_PIECE_MIN)*2 +2);
00044   const int base = env.pattern_cache[position.index()];
00045 
00046   int index = base + (self - PTYPE_PIECE_MIN)*((PTYPE_MAX+1 - PTYPE_PIECE_MIN)*2 +2);
00047   if (!isPiece(target)) {
00048     index += (PTYPE_MAX+1-PTYPE_PIECE_MIN)*2 + (target == PTYPE_EMPTY ? 0 : 1);
00049   }
00050   else {
00051     index += (target - PTYPE_PIECE_MIN)*2 + (p.owner() != move.player());
00052   }
00053   return index;
00054 }
00055 
00056 std::string osl::rating::PatternGroup::name(Direction direction, Direction direction2) 
00057 {
00058   std::ostringstream ss;
00059   ss << "Pattern" << direction;
00060   if (direction2 != Pattern::INVALID)
00061       ss << direction2;
00062   return ss.str();
00063 }
00064 
00065 const osl::CArray<osl::Direction,4> osl::rating::PatternLongGroup::rook_direction4 = {{ U, L, D, R }};
00066 const osl::CArray<osl::Direction,4> osl::rating::PatternLongGroup::bishop_direction4 = {{ UL, DL, DR, UR }};
00067 
00068 std::string osl::rating::PatternLongGroup::name(int direction_id)
00069 {
00070   std::ostringstream ss;
00071   ss << "PatLong" << direction_id;
00072   return ss.str();
00073 }
00074 
00075 osl::rating::PatternLongGroup::PatternLongGroup(int d) 
00076   : Group(name(d)), direction_id(d)
00077 {
00078   const CArray<Ptype,5> self_list = {{ ROOK, PROOK, BISHOP, PBISHOP, LANCE }};
00079   for (int s=0; s<((d == 0) ? 5 : 4); ++s) {
00080     const Ptype self = self_list[s];
00081     const Direction direction = makeDirection(self);
00082     for (int attack=0; attack<3; ++attack) {
00083       for (int defense=0; defense<3; ++defense) {
00084         for (int t=PTYPE_PIECE_MIN; t<= PTYPE_MAX; ++t) {
00085           push_back(new PatternLong(direction, self, LongTarget(static_cast<Ptype>(t), true,  true, attack, defense)));
00086           push_back(new PatternLong(direction, self, LongTarget(static_cast<Ptype>(t), true,  false, attack, defense)));
00087           push_back(new PatternLong(direction, self, LongTarget(static_cast<Ptype>(t), false, true, attack, defense)));
00088           push_back(new PatternLong(direction, self, LongTarget(static_cast<Ptype>(t), false, false, attack, defense)));
00089         }
00090         push_back(new PatternLong(direction, self, LongTarget(PTYPE_EMPTY, true,  true, attack, defense)));
00091         push_back(new PatternLong(direction, self, LongTarget(PTYPE_EMPTY, false,  true, attack, defense)));
00092       }
00093     }
00094     push_back(new PatternLong(direction, self, LongTarget(PTYPE_EDGE, true, true, 0, 0)));
00095   }
00096 }
00097 
00098 int osl::rating::PatternLongGroup::findMatch(const NumEffectState& state, Move move, const RatingEnv& env) const
00099 {  
00100   const size_t unit = ((PTYPE_MAX+1-PTYPE_PIECE_MIN)*4+2)*9+1;
00101   const Ptype self = move.ptype();
00102   int base = 0;
00103   switch (self) {
00104   case ROOK:
00105     break;
00106   case PROOK:
00107     base += unit; break;
00108   case BISHOP:
00109     base += unit*2; break;
00110   case PBISHOP:
00111     base += unit*3; break;
00112   case LANCE:
00113     if (direction_id != 0)
00114       return -1;
00115     base += unit*4; break;
00116   default:
00117     return -1;
00118   }
00119   const Direction direction = makeDirection(self);
00120   const PieceSquare pp = PatternLong::find(state, move, direction);
00121 
00122   int index = base;
00123   if (pp.first.isEdge()) {
00124     index += unit - 1;
00125   } else {
00126     index += ((PTYPE_MAX+1-PTYPE_PIECE_MIN)*4+2)*CountEffect2::index(state, pp.second, env);
00127     if (pp.first.isEmpty()) {
00128       index += (PTYPE_MAX+1-PTYPE_PIECE_MIN)*4;
00129       index += ! LongTarget::isPromotable(move, pp.second);
00130     }
00131     else {
00132       assert(pp.first.isPiece());
00133       index += (pp.first.ptype()-PTYPE_PIECE_MIN)*4;
00134       index += (! LongTarget::isPromotable(move, pp.second))*2;
00135       index += (pp.first.owner() != move.player());
00136     }
00137   }
00138   return index;
00139 }
00140 
00141 std::string osl::rating::PatternLongGroup2::name(int direction_id)
00142 {
00143   std::ostringstream ss;
00144   ss << "PatLong2" << direction_id;
00145   return ss.str();
00146 }
00147 
00148 osl::rating::PatternLongGroup2::PatternLongGroup2(int d) 
00149   : Group(name(d)), direction_id(d)
00150 {
00151   const CArray<Ptype,5> self_list = {{ ROOK, PROOK, BISHOP, PBISHOP, LANCE }};
00152   for (int s=0; s<((d == 0) ? 5 : 4); ++s) {
00153     const Ptype self = self_list[s];
00154     const Direction direction = makeDirection(self);
00155     for (int t=PTYPE_PIECE_MIN; t<= PTYPE_MAX; ++t) {
00156       push_back(new PatternLong2(direction, self, LongTarget2(static_cast<Ptype>(t), true)));
00157       push_back(new PatternLong2(direction, self, LongTarget2(static_cast<Ptype>(t), false)));
00158     }
00159     push_back(new PatternLong2(direction, self, LongTarget2(PTYPE_EDGE, true)));
00160   }
00161 }
00162 
00163 int osl::rating::PatternLongGroup2::findMatch(const NumEffectState& state, Move move, const RatingEnv& ) const
00164 {  
00165   const size_t unit = (PTYPE_MAX+1-PTYPE_PIECE_MIN)*2+1;
00166   const Ptype self = move.ptype();
00167   int base = 0;
00168   switch (self) {
00169   case ROOK:
00170     break;
00171   case PROOK:
00172     base += unit; break;
00173   case BISHOP:
00174     base += unit*2; break;
00175   case PBISHOP:
00176     base += unit*3; break;
00177   case LANCE:
00178     if (direction_id != 0)
00179       return -1;
00180     base += unit*4; break;
00181   default:
00182     return -1;
00183   }
00184   const Direction direction = makeDirection(self);
00185   const Piece p = PatternLong2::find(state, move, direction);
00186 
00187   int index = base;
00188   if (! p.isPiece()) {
00189     index += unit - 1;
00190   } else {
00191     assert(p.isPiece());
00192     index += (p.ptype()-PTYPE_PIECE_MIN)*2;
00193     index += (p.owner() != move.player());
00194   }
00195   return index;
00196 }
00197 
00198 osl::rating::
00199 PatternBlockGroup::PatternBlockGroup(Ptype a) 
00200   : Group(std::string("PatternBlock")+Ptype_Table.getCsaName(a)), attacker(a)
00201 {
00202   assert(a == LANCE || a == ROOK || a == BISHOP);
00203   for (int s=PTYPE_PIECE_MIN; s<=PTYPE_MAX; ++s) {
00204     const Ptype self = static_cast<Ptype>(s);
00205     for (int attack=0; attack<3; ++attack) {
00206       for (int defense=0; defense<3; ++defense) {
00207         for (int t=PTYPE_PIECE_MIN; t<= PTYPE_MAX; ++t) {
00208           push_back(new PatternBlock(self, a, LongTarget(static_cast<Ptype>(t), true,  true, attack, defense)));
00209           push_back(new PatternBlock(self, a, LongTarget(static_cast<Ptype>(t), true,  false, attack, defense)));
00210           push_back(new PatternBlock(self, a, LongTarget(static_cast<Ptype>(t), false, true, attack, defense)));
00211           push_back(new PatternBlock(self, a, LongTarget(static_cast<Ptype>(t), false, false, attack, defense)));
00212         }
00213         push_back(new PatternBlock(self, a, LongTarget(PTYPE_EMPTY, true,  true, attack, defense)));
00214         push_back(new PatternBlock(self, a, LongTarget(PTYPE_EMPTY, false,  true, attack, defense)));
00215       }
00216     }
00217   }
00218 }
00219 
00220 int osl::rating::
00221 PatternBlockGroup::findMatch(const NumEffectState& state, Move move, const RatingEnv& env) const
00222 {  
00223   const size_t unit = ((PTYPE_MAX+1-PTYPE_PIECE_MIN)*4+2)*9;
00224   const PieceSquare pp = PatternBlock::find(state, move, attacker);
00225   if (pp.first.isEdge())
00226     return -1;
00227 
00228   int index = (move.ptype() - PTYPE_PIECE_MIN)*unit;
00229   index += ((PTYPE_MAX+1-PTYPE_PIECE_MIN)*4+2)*CountEffect2::index(state, pp.second, env);
00230   if (pp.first.isEmpty()) {
00231     index += (PTYPE_MAX+1-PTYPE_PIECE_MIN)*4;
00232     index += ! pp.second.canPromote(alt(state.turn()));
00233   }
00234   else {
00235     assert(pp.first.isPiece());
00236     index += (pp.first.ptype()-PTYPE_PIECE_MIN)*4;
00237     index += (! pp.second.canPromote(pp.first.isPiece() ? alt(pp.first.owner()) : alt(move.player())))*2;
00238     index += (pp.first.owner() != move.player());
00239   }
00240   return index;
00241 }
00242 
00243 /* ------------------------------------------------------------------------- */
00244 // ;;; Local Variables:
00245 // ;;; mode:c++
00246 // ;;; c-basic-offset:2
00247 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines