説明を見る。00001
00002
00003 #ifndef OSL_BOARD_TABLE_H
00004 #define OSL_BOARD_TABLE_H
00005
00006 #include "osl/basic_type.h"
00007 #include "osl/container.h"
00008 #include "osl/bits/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)*sign(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 Square nextSquare(Player P, Square 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(Square from, Square to) const
00089 {
00090 return getLongDirection<P>(Offset32(to,from));
00091 }
00092 #ifndef MINIMAL
00093
00099 int spaceCounts(Square from,Square 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(Square from,Square 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(Square from,Square 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 Direction getShort8Unsafe(Player P, Square from,Square to) const{
00141 if(P==BLACK)
00142 return getShort8Unsafe<BLACK>(from, to);
00143 else
00144 return getShort8Unsafe<WHITE>(from, to);
00145 }
00146 template<Player P>
00147 Direction getShort8(Square from,Square to) const{
00148 assert(from.isOnBoard() && to.isOnBoard());
00149 assert(from.x()==to.x() || from.y()==to.y() ||
00150 abs(from.x()-to.x())==abs(from.y()-to.y()));
00151 return getShort8Unsafe<P>(from,to);
00152 }
00153
00154 template<Player P>
00155 Direction getShort8(Square from,Square to,Offset& o) const{
00156 assert(from.isOnBoard() && to.isOnBoard());
00157 assert(from.x()==to.x() || from.y()==to.y() ||
00158 abs(from.x()-to.x())==abs(from.y()-to.y()));
00159 int i=(int)(to.uintValue())-(int)(from.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00160 o=Offset::makeDirect(short8Offset[i]);
00161 Direction d=static_cast<Direction>(short8Dir[i]);
00162 if(P==BLACK)
00163 return d;
00164 else
00165 return inverse(d);
00166 }
00172 bool isBetween(Square t,Square p0,Square p1) const
00173 {
00174 int i1=(int)(t.uintValue())-(int)(p0.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00175 int i2=(int)(p1.uintValue())-(int)(t.uintValue())-Offset::ONBOARD_OFFSET_MIN;
00176 assert(short8Dir[i1]!=DIRECTION_INVALID_VALUE || short8Dir[i2]!=DIRECTION_INVALID_VALUE);
00177 return short8Dir[i1]==short8Dir[i2];
00178 }
00179 bool isBetweenSafe(Square t,Square p0,Square p1) const
00180 {
00181 if (getShortOffsetNotKnight(Offset32(t, p0)).zero())
00182 return false;
00183 return isBetween(t, p0, p1);
00184 }
00185 };
00186
00187 extern const BoardTable Board_Table;
00188 }
00189
00190
00191 #endif
00192
00193
00194
00195