00001
00002
00003 #ifndef EFFECT_UTIL_NEIGHBORING8DIRECT_H
00004 #define EFFECT_UTIL_NEIGHBORING8DIRECT_H
00005
00006 #include "osl/state/numEffectState.h"
00007 #include "osl/direction.h"
00008
00009 namespace osl
00010 {
00011 namespace effect_util
00012 {
00016 class Neighboring8Direct
00017 {
00018 class Table
00019 {
00020 struct Entry
00021 {
00022 bool has_unblockable_effect;
00023 Offset nearest;
00024 Entry() : has_unblockable_effect(false), nearest(Offset::ZERO())
00025 {
00026 }
00027 };
00028 CArray2d<Entry,PTYPEO_SIZE,Offset32::SIZE> table;
00029 void init(Player);
00030 public:
00031 Table();
00032 bool hasEffect(const NumEffectState& state,
00033 PtypeO ptypeo, Square from,
00034 Square target) const
00035 {
00036 const Offset32 offset32 = Offset32(target, from);
00037 const Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
00038 if (e.has_unblockable_effect)
00039 return true;
00040 if (e.nearest.zero())
00041 return false;
00042 assert(Ptype_Table.hasLongMove(getPtype(ptypeo)));
00043 const Square nearest = from+e.nearest;
00044 if (nearest.isEdge())
00045 {
00046 return false;
00047 }
00048 return state.isEmptyBetween(from, nearest, false);
00049 }
00050 bool hasEffectOrAdditional(const NumEffectState& state,
00051 PtypeO ptypeo, Square from,
00052 Square target) const
00053 {
00054 const Offset32 offset32 = Offset32(target, from);
00055 const Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
00056 if (e.has_unblockable_effect)
00057 return true;
00058 if (e.nearest.zero())
00059 return false;
00060 assert(Ptype_Table.hasLongMove(getPtype(ptypeo)));
00061 const Square nearest = from+e.nearest;
00062 if (nearest.isEdge())
00063 {
00064 return false;
00065 }
00066 Offset offset=Board_Table.getShortOffset(Offset32(nearest,from));
00067 assert(! offset.zero());
00068 Square pos=from+offset;
00069 Piece p = state.pieceAt(pos);
00070 for (; p.isEmpty(); pos+=offset, p=state.pieceAt(pos)) {
00071 if (pos==nearest)
00072 return true;
00073 }
00074 assert(p.isPiece());
00075 if (pos == nearest || state.hasEffectByPiece(p, nearest))
00076 return true;
00077 const Player attack = getOwner(ptypeo);
00078 if (target != state.kingSquare(alt(attack)))
00079 return false;
00080
00081 const Direction dir = longToShort(Board_Table.getLongDirection(attack,Offset32(nearest, from)));
00082 return pos == state.kingMobilityOfPlayer(alt(attack), dir);
00083 }
00084 Square findNearest(const NumEffectState& state,
00085 PtypeO ptypeo, Square from,
00086 Square target) const
00087 {
00088 const Offset32 offset32 = Offset32(target, from);
00089 const Entry& e = table[ptypeOIndex(ptypeo)][offset32.index()];
00090 if (e.has_unblockable_effect)
00091 return from;
00092 if (e.nearest.zero())
00093 return Square::STAND();
00094 assert(Ptype_Table.hasLongMove(getPtype(ptypeo)));
00095 const Square nearest = from+e.nearest;
00096 if (!nearest.isEdge() && state.isEmptyBetween(from, nearest, false))
00097 return nearest;
00098 return Square::STAND();
00099 }
00100 };
00101 static const Table table;
00102 public:
00106 static bool hasEffect(const NumEffectState& state,
00107 PtypeO ptypeo, Square from,
00108 Square target)
00109 {
00110 return table.hasEffect(state, ptypeo, from, target);
00111 }
00116 static bool hasEffectOrAdditional(const NumEffectState& state,
00117 PtypeO ptypeo, Square from,
00118 Square target)
00119 {
00120 return table.hasEffectOrAdditional(state, ptypeo, from, target);
00121 }
00122 static Square findNearest(const NumEffectState& state,
00123 PtypeO ptypeo, Square from,
00124 Square target)
00125 {
00126 return table.findNearest(state, ptypeo, from, target);
00127 }
00128 private:
00129 static bool hasEffectFromTo(const NumEffectState& state,
00130 PtypeO ptypeo, Square from,
00131 Square target, Direction d);
00132 public:
00133 static bool hasEffectNaive(const NumEffectState& state,
00134 PtypeO ptypeo, Square from,
00135 Square target);
00136 };
00137
00138 }
00139 using effect_util::Neighboring8Direct;
00140 }
00141
00142 #endif
00143
00144
00145
00146