00001
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));
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
00245
00246
00247