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