00001
00002
00003 #include "osl/effect_util/sendOffPosition.h"
00004 #include "osl/ptypeTable.h"
00005 #include "osl/misc/bitOp.h"
00006 #include <boost/foreach.hpp>
00007
00008 osl::effect_util::SendOffPosition::
00009 Table::Table()
00010 {
00011 normal[0] = Offset( 1, 1);
00012 normal[1] = Offset( 1, 0);
00013 normal[2] = Offset( 1,-1);
00014 normal[3] = Offset( 0, 1);
00015 normal[4] = Offset( 0,-1);
00016 normal[5] = Offset(-1, 1);
00017 normal[6] = Offset(-1, 0);
00018 normal[7] = Offset(-1,-1);
00019
00020 const Position center(5,5);
00021 const PtypeO king = newPtypeO(BLACK, KING);
00022 for (int i=0; i<8; ++i)
00023 {
00024 const Offset king_position = normal[i];
00025 for (int j=0; j<8; ++j)
00026 {
00027 const Offset target = normal[j];
00028 if (i==j)
00029 continue;
00030 const int dx = king_position.dx() - target.dx();
00031 const int dy = king_position.dy() - target.dy();
00032 const EffectContent effect
00033 = Ptype_Table.getEffect(king, Offset32(dx, dy));
00034 if (! effect.hasEffect())
00035 {
00036 reverse[i].push_back(j);
00037 }
00038 }
00039 }
00040
00041 for (int i=0; i<256; ++i)
00042 {
00043 unsigned int val = i;
00044 while (val)
00045 {
00046 const int j = misc::BitOp::takeOneBit(val);
00047
00048 BOOST_FOREACH(int p, reverse[j])
00049 {
00050 if (! reverse_all[i].isMember(p))
00051 reverse_all[i].push_back(p);
00052 }
00053 }
00054 }
00055 }
00056
00057 template <osl::Player Attack>
00058 osl::effect_util::SendOffPosition::SendOff8
00059 #if (defined __GNUC__) && (! defined GPSONE) && (! defined GPSUSIONE)
00060 __attribute__ ((used))
00061 #endif
00062 osl::effect_util::
00063 SendOffPosition::find(const NumEffectState& state, Position king_position,
00064 Position8& out)
00065 {
00066 assert(out.empty());
00067 int flags=0;
00068 for (int i=0; i<8; ++i)
00069 {
00070 testPosition<Attack>(state, king_position+table.normal[i], i, flags);
00071 }
00072 SendOff8 data = 0;
00073 BOOST_FOREACH(int i, table.reverse_all[flags])
00074 {
00075 const Position candidate = king_position + table.normal[i];
00076 if (! state.getPieceAt(candidate).isEdge()
00077 && state.countEffect(alt(Attack), candidate) == 1) {
00078 out.push_back(candidate);
00079 data |= (1<<i);
00080 }
00081 }
00082 return data;
00083 }
00084
00085 void osl::effect_util::
00086 SendOffPosition::unpack(SendOff8 flags8, Position king_position,
00087 Position8& out)
00088 {
00089 assert(out.empty());
00090 unsigned int flags = flags8;
00091 while (flags) {
00092 const int i = misc::BitOp::takeOneBit(flags);
00093 const Position candidate = king_position + table.normal[i];
00094 out.push_back(candidate);
00095 }
00096 }
00097
00098 osl::effect_util::SendOffPosition::SendOff8 osl::effect_util::
00099 SendOffPosition::find(Player attack, const NumEffectState& state,
00100 Position king_position,
00101 Position8& out)
00102 {
00103 if (attack == BLACK)
00104 return find<BLACK>(state, king_position, out);
00105 else
00106 return find<WHITE>(state, king_position, out);
00107 }
00108
00109
00110
00111
00112
00113