00001
00002
00003 #include "osl/effect_util/neighboring8Direct.h"
00004 #include "osl/oslConfig.h"
00005 osl::effect_util::Neighboring8Direct::Table osl::effect_util::Neighboring8Direct::table;
00006
00007 static osl::SetUpRegister _initializer([](){ osl::effect_util::Neighboring8Direct::init(); });
00008
00009 void osl::effect_util::Neighboring8Direct::
00010 init()
00011 {
00012 table.init(BLACK);
00013 table.init(WHITE);
00014 }
00015
00016 void osl::effect_util::Neighboring8Direct::
00017 Table::init(const Player player)
00018 {
00019 for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p)
00020 {
00021 const Ptype ptype = static_cast<Ptype>(p);
00022 assert(isPiece(ptype));
00023 const PtypeO ptypeo = newPtypeO(player, ptype);
00024 const int mask = Ptype_Table.getMoveMask(ptype);
00025 for (int d=DIRECTION_MIN; d<=DIRECTION_MAX; ++d)
00026 {
00027 const Direction direction = static_cast<Direction>(d);
00028 if (! (mask & (1<<direction)))
00029 continue;
00030 const Offset offset = Board_Table.getOffset(player, direction);
00031 assert(! offset.zero());
00032 const int x = offset.dx();
00033 const int y = offset.dy();
00034 for (int dy=-1; dy<=1; ++dy)
00035 {
00036 for (int dx=-1; dx<=1; ++dx)
00037 {
00038 const Offset32 offset32 = Offset32(x+dx, y+dy);
00039 table[ptypeOIndex(ptypeo)][offset32.index()].
00040 has_unblockable_effect = true;
00041 }
00042 }
00043 if (isLong(direction))
00044 {
00045 assert(abs(x)<=1);
00046 assert(abs(y)<=1);
00047 for (int i=1; i<8; ++i)
00048 {
00049 const int long_x = x*i;
00050 const int long_y = y*i;
00051 const int target_x = x*(i+1);
00052 const int target_y = y*(i+1);
00053 const Offset32 offset32 = Offset32(target_x, target_y);
00054 Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
00055 e.nearest = Offset(long_x, long_y);
00056 }
00057 for (int i=1; i<9; ++i)
00058 {
00059 const int long_x = x*i;
00060 const int long_y = y*i;
00061 for (int dy=-1; dy<=1; ++dy)
00062 {
00063 const int target_y = long_y+dy;
00064 if ((target_y < -8) || (8 < target_y))
00065 continue;
00066 for (int dx=-1; dx<=1; ++dx)
00067 {
00068 const int target_x = long_x+dx;
00069 if ((target_x < -8) || (8 < target_x))
00070 continue;
00071 const Offset32 offset32 = Offset32(target_x, target_y);
00072 Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
00073
00074 if (e.nearest.zero())
00075 {
00076 e.nearest = Offset(long_x, long_y);
00077 }
00078 }
00079 }
00080 }
00081 }
00082 }
00083 }
00084 }
00085
00086 bool osl::effect_util::Neighboring8Direct::
00087 hasEffectFromTo(const NumEffectState& state, PtypeO ptypeo, Square from,
00088 Square target, Direction d)
00089 {
00090 target += Board_Table.getOffsetForBlack(d);
00091 return target.isOnBoard()
00092 && state.hasEffectIf(ptypeo, from, target);
00093 }
00094
00095 bool osl::effect_util::Neighboring8Direct::
00096 hasEffectNaive(const NumEffectState& state, PtypeO ptypeo, Square from,
00097 Square target)
00098 {
00099 const Ptype ptype = getPtype(ptypeo);
00100 if (! Ptype_Table.hasLongMove(ptype))
00101 {
00102 if (abs(from.y() - target.y()) > 3)
00103 return false;
00104 if (abs(from.x() - target.x()) > 2)
00105 return false;
00106 }
00107 else if (ptype == LANCE)
00108 {
00109 if (abs(from.x() - target.x()) > 1)
00110 return false;
00111 }
00112
00113
00114 return hasEffectFromTo(state, ptypeo, from, target, UL)
00115 || hasEffectFromTo(state, ptypeo, from, target, U)
00116 || hasEffectFromTo(state, ptypeo, from, target, UR)
00117 || hasEffectFromTo(state, ptypeo, from, target, L)
00118 || hasEffectFromTo(state, ptypeo, from, target, R)
00119 || hasEffectFromTo(state, ptypeo, from, target, DL)
00120 || hasEffectFromTo(state, ptypeo, from, target, D)
00121 || hasEffectFromTo(state, ptypeo, from, target, DR);
00122 }
00123
00124
00125
00126
00127