1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
/* neighboring8Direct.cc
*/
#include "osl/effect_util/neighboring8Direct.h"
osl::effect_util::Neighboring8Direct::
Table::Table()
{
init(BLACK);
init(WHITE);
}
void osl::effect_util::Neighboring8Direct::
Table::init(const Player player)
{
for (int p=PTYPE_PIECE_MIN; p<=PTYPE_MAX; ++p)
{
const Ptype ptype = static_cast<Ptype>(p);
assert(isPiece(ptype));
const PtypeO ptypeo = newPtypeO(player, ptype);
const int mask = Ptype_Table.getMoveMask(ptype);
for (int d=DIRECTION_MIN; d<=DIRECTION_MAX; ++d)
{
const Direction direction = static_cast<Direction>(d);
if (! (mask & (1<<direction)))
continue;
const Offset offset = Board_Table.getOffset(player, direction);
assert(! offset.zero());
const int x = offset.dx();
const int y = offset.dy();
for (int dy=-1; dy<=1; ++dy)
{
for (int dx=-1; dx<=1; ++dx)
{
const Offset32 offset32 = Offset32(x+dx, y+dy);
table[ptypeOIndex(ptypeo)][offset32.index()].
has_unblockable_effect = true;
}
}
if (isLong(direction))
{
assert(abs(x)<=1);
assert(abs(y)<=1);
for (int i=1; i<8; ++i)
{
const int long_x = x*i;
const int long_y = y*i;
const int target_x = x*(i+1);
const int target_y = y*(i+1);
const Offset32 offset32 = Offset32(target_x, target_y);
Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
e.nearest = Offset(long_x, long_y);
}
for (int i=1; i<9; ++i)
{
const int long_x = x*i;
const int long_y = y*i;
for (int dy=-1; dy<=1; ++dy)
{
const int target_y = long_y+dy;
if ((target_y < -8) || (8 < target_y))
continue;
for (int dx=-1; dx<=1; ++dx)
{
const int target_x = long_x+dx;
if ((target_x < -8) || (8 < target_x))
continue;
const Offset32 offset32 = Offset32(target_x, target_y);
Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
// 近いところ優先
if (e.nearest.zero())
{
e.nearest = Offset(long_x, long_y);
}
}
}
}
}
}
}
}
bool osl::effect_util::Neighboring8Direct::
hasEffectFromTo(const NumEffectState& state, PtypeO ptypeo, Position from,
Position target, Direction d)
{
target += Board_Table.getOffsetForBlack(d); // 8 近傍全て試すなら手番による符合変換は不要
return target.isOnBoard()
&& state.hasEffectFromTo(ptypeo, from, target);
}
bool osl::effect_util::Neighboring8Direct::
hasEffectNaive(const NumEffectState& state, PtypeO ptypeo, Position from,
Position target)
{
const Ptype ptype = getPtype(ptypeo);
if (! Ptype_Table.hasLongMove(ptype))
{
if (abs(from.y() - target.y()) > 3) // knight だけ3
return false;
if (abs(from.x() - target.x()) > 2)
return false;
}
else if (ptype == LANCE)
{
if (abs(from.x() - target.x()) > 1)
return false;
}
// naive な実装
return hasEffectFromTo(state, ptypeo, from, target, UL)
|| hasEffectFromTo(state, ptypeo, from, target, U)
|| hasEffectFromTo(state, ptypeo, from, target, UR)
|| hasEffectFromTo(state, ptypeo, from, target, L)
|| hasEffectFromTo(state, ptypeo, from, target, R)
|| hasEffectFromTo(state, ptypeo, from, target, DL)
|| hasEffectFromTo(state, ptypeo, from, target, D)
|| hasEffectFromTo(state, ptypeo, from, target, DR);
}
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End:
|