00001
00002
00003 #ifndef BOARD_TABLE_H
00004 #define BOARD_TABLE_H
00005
00006 #include "osl/direction.h"
00007 #include "osl/misc/carray.h"
00008 #include "osl/offset32.h"
00009
00010 namespace osl
00011 {
00012 class BoardTable
00013 {
00014 CArray<Direction,Offset32::SIZE> directions;
00015
00016 CArray<signed char,Offset::ONBOARD_OFFSET_SIZE> short8Offset;
00017 CArray<unsigned char,Offset::ONBOARD_OFFSET_SIZE> short8Dir;
00018 CArray<Offset, Offset32::SIZE> short_offsets;
00019 CArray<Offset, Offset32::SIZE> short_offsets_not_knight;
00020 #ifndef MINIMAL
00021 CArray<int,Offset32Wide::SIZE> space_counts;
00022 #endif
00023 public:
00024 static const CArray<Offset, DIRECTION_SIZE> offsets;
00025 static const CArray<int, DIRECTION_SIZE> dxs;
00026 static const CArray<int, DIRECTION_SIZE> dys;
00027 private:
00028 template<Direction Dir>
00029 void setDirections();
00030 template<Direction Dir>
00031 void setKnightDirections();
00032 void init();
00033 public:
00037 const Offset getOffsetForBlack(Direction dir) const{
00038 return offsets[static_cast<int>(dir)];
00039 }
00040 int getDxForBlack(Direction dir) const{
00041 return dxs[static_cast<int>(dir)];
00042 }
00043 int getDyForBlack(Direction dir) const{
00044 return dys[static_cast<int>(dir)];
00045 }
00046 template<Player P>
00047 const Offset getOffset(Direction dir) const{
00048 return getOffsetForBlack(dir)*playerToMul(P);
00049 }
00050 const Offset getOffset(Player pl,Direction dir) const{
00051 if (pl==BLACK)
00052 return getOffset<BLACK>(dir);
00053 else
00054 return getOffset<WHITE>(dir);
00055 }
00056
00061 const Position nextPosition(Player P, Position pos, Direction dr) const
00062 {
00063 assert(pos.isOnBoard());
00064 const Offset offset = getOffset(P, dr);
00065 return pos + offset;
00066 }
00067
00068 BoardTable();
00070 template <Player P>
00071 Direction getLongDirection(Offset32 offset32) const
00072 {
00073 assert(offset32.isValid());
00074 const Offset32 blackOffset32 = offset32.blackOffset32<P>();
00075 Direction ret=directions[blackOffset32.index()];
00076 assert(isValid(ret));
00077 return ret;
00078 }
00079 Direction getLongDirection(Player P, Offset32 offset32) const
00080 {
00081 if (P == BLACK)
00082 return getLongDirection<BLACK>(offset32);
00083 else
00084 return getLongDirection<WHITE>(offset32);
00085 }
00087 template <Player P>
00088 Direction getLongDirection(Position from, Position to) const
00089 {
00090 return getLongDirection<P>(Offset32(to,from));
00091 }
00092 #ifndef MINIMAL
00093
00099 int spaceCounts(Position from,Position to) const
00100 {
00101 Offset32Wide offset32(from,to);
00102 return space_counts[offset32.index()];
00103 }
00104 #endif
00105
00110 const Offset getShortOffset(Offset32 offset32) const{
00111 assert(offset32.isValid());
00112 return short_offsets[offset32.index()];
00113 }
00119 const Offset getShortOffsetNotKnight(Offset32 offset32) const{
00120 assert(offset32.isValid());
00121 return short_offsets_not_knight[offset32.index()];
00122 }
00126 Offset getShort8OffsetUnsafe(Position from,Position to) const{
00127 int i=(int)(to.uintValue())-(int)(from.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00128 return Offset::makeDirect(short8Offset[i]);
00129 }
00133 template<Player P>
00134 Direction getShort8Unsafe(Position from,Position to) const{
00135 if(P==BLACK)
00136 return static_cast<Direction>(short8Dir[(int)(to.uintValue())-(int)(from.uintValue())-Offset::ONBOARD_OFFSET_MIN]);
00137 else
00138 return static_cast<Direction>(short8Dir[(int)(from.uintValue())-(int)(to.uintValue())-Offset::ONBOARD_OFFSET_MIN]);
00139 }
00140 template<Player P>
00141 Direction getShort8(Position from,Position to) const{
00142 assert(from.isOnBoard() && to.isOnBoard());
00143 assert(from.x()==to.x() || from.y()==to.y() ||
00144 abs(from.x()-to.x())==abs(from.y()-to.y()));
00145 return getShort8Unsafe<P>(from,to);
00146 }
00147
00148 template<Player P>
00149 Direction getShort8(Position from,Position to,Offset& o) const{
00150 assert(from.isOnBoard() && to.isOnBoard());
00151 assert(from.x()==to.x() || from.y()==to.y() ||
00152 abs(from.x()-to.x())==abs(from.y()-to.y()));
00153 int i=(int)(to.uintValue())-(int)(from.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00154 o=Offset::makeDirect(short8Offset[i]);
00155 Direction d=static_cast<Direction>(short8Dir[i]);
00156 if(P==BLACK)
00157 return d;
00158 else
00159 return inverse(d);
00160 }
00166 bool isBetween(Position t,Position p0,Position p1) const
00167 {
00168 int i1=(int)(t.uintValue())-(int)(p0.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00169 int i2=(int)(p1.uintValue())-(int)(t.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00170 assert(short8Dir[i1]!=DIRECTION_INVALID_VALUE || short8Dir[i2]!=DIRECTION_INVALID_VALUE);
00171 return short8Dir[i1]==short8Dir[i2];
00172 }
00173 };
00174
00175 extern const BoardTable Board_Table;
00176 }
00177
00178
00179 #endif
00180
00181
00182
00183