00001
00002
00003 #ifndef _PATH_ENCODING_H
00004 #define _PATH_ENCODING_H
00005
00006 #include "osl/move.h"
00007 #include "osl/misc/carray.h"
00008 #include "osl/misc/carray2d.h"
00009 #include <iosfwd>
00010 namespace osl
00011 {
00012 class PathEncodingTable
00013 {
00014 public:
00015 static const size_t MaxEncodingLength = 256;
00016 private:
00017 typedef CArray<CArray2d<unsigned long long, Position::SIZE, PTYPE_SIZE>,
00018 MaxEncodingLength> array_t;
00019 array_t values;
00020 public:
00021 PathEncodingTable();
00022 ~PathEncodingTable();
00023 unsigned long long get(size_t depth, Position pos, Ptype ptype) const
00024 {
00025 return values[depth](pos.index(), ptype-PTYPE_MIN);
00026 }
00030 unsigned long long get(size_t depth, Move m) const
00031 {
00032 const Position from = m.from();
00033 const Position to = m.to();
00034 const Ptype fromPtype = m.oldPtype();
00035 const Ptype toPtype = m.ptype();
00036 depth %= 256;
00037 return get(depth, from, fromPtype) + get(depth, to, toPtype) + 1;
00038 }
00039 };
00040 extern const PathEncodingTable Path_Encoding_Table;
00041 class PathEncoding
00042 {
00043 unsigned long long path;
00044 int depth;
00045 public:
00046 explicit PathEncoding(int d=0) : path(0), depth(d)
00047 {
00048 }
00049 explicit PathEncoding(Player turn, int d=0)
00050 : path((turn == BLACK) ? 0 : 1), depth(d)
00051 {
00052 }
00053 PathEncoding(const PathEncoding& org, Move m)
00054 : path(org.path), depth(org.depth)
00055 {
00056 pushMove(m);
00057 }
00058 Player turn() const { return (path % 2) ? WHITE : BLACK; }
00059 void pushMove(Move m)
00060 {
00061 assert(m.player() == turn());
00062 path += Path_Encoding_Table.get(depth, m);
00063 ++depth;
00064 }
00065 void popMove(Move m)
00066 {
00067 --depth;
00068 path -= Path_Encoding_Table.get(depth, m);
00069 assert(m.player() == turn());
00070 }
00071 unsigned long long getPath() const { return path; }
00072 int getDepth() const { return depth; }
00073 };
00074
00075 inline bool operator==(const PathEncoding& l, const PathEncoding& r)
00076 {
00077 return l.getPath() == r.getPath();
00078 }
00079 inline bool operator!=(const PathEncoding& l, const PathEncoding& r)
00080 {
00081 return !(l == r);
00082 }
00083 std::ostream& operator<<(std::ostream&, const PathEncoding&);
00084 }
00085
00086 #endif
00087
00088
00089
00090