説明を見る。00001
00002
00003 #ifndef OSL_HASH_KEY_H
00004 #define OSL_HASH_KEY_H
00005
00006 #include "osl/basic_type.h"
00007 #include "osl/bits/pieceStand.h"
00008 #include "osl/simpleState.h"
00009 #include <cstddef>
00010
00011 namespace osl
00012 {
00013 namespace hash
00014 {
00015 struct BoardKey96 : public std::pair<uint64_t,uint32_t>
00016 {
00017 BoardKey96() {}
00018 BoardKey96(const std::pair<uint64_t,uint32_t>& src)
00019 : std::pair<uint64_t,uint32_t>(src)
00020 {
00021 }
00022 uint32_t signature() const { return second; }
00023 size_t size() const { return 2; }
00024 uint64_t operator[](size_t i) const { return i ? first : second; }
00025 };
00026 class HashGenTable;
00027 struct HashKey128Layout
00028 {
00029 uint64_t board64;
00030 uint32_t board32, piece_stand;
00031 };
00036 class HashKey128 : private HashKey128Layout
00037 {
00038 friend class HashGenTable;
00039 public:
00040 HashKey128()
00041 {
00042 board64 = board32 = piece_stand = 0;
00043 }
00044 HashKey128(uint64_t h0, uint32_t h1, uint32_t s)
00045 {
00046 board64 = h0;
00047 board32 = h1;
00048 piece_stand = s;
00049 }
00050 HashKey128(const HashKey128Layout& src) : HashKey128Layout(src)
00051 {
00052 }
00053 const BoardKey96 boardKey() const {
00054 return std::make_pair(board64, board32);
00055 }
00056 uint64_t boardKey64() const { return board64; }
00057 uint64_t signature() const { return board32; }
00059 uint64_t hash64() const { return board64 + pieceStand64(); }
00060 uint64_t pieceStand64() const {
00061 return Stand_Hash.toUint64(pieceStand());
00062 }
00063 const PieceStand pieceStand() const{ return PieceStand(piece_stand); }
00064 const PieceStand blackStand() const { return PieceStand(piece_stand); }
00065 void setPieceStand(const PieceStand& p) { piece_stand=p.getFlags(); }
00066
00071 bool isSameBoard(const HashKey128& key) const
00072 {
00073 return boardKey() == key.boardKey();
00074 }
00075 HashKey128& operator+=(const HashKey128& r)
00076 {
00077 board64 += r.board64;
00078 board32 += r.board32;
00079 PieceStand new_stand(piece_stand);
00080 new_stand.addAtmostOnePiece(r.pieceStand());
00081 piece_stand = new_stand.getFlags();
00082 return *this;
00083 }
00084 HashKey128& operator-=(const HashKey128& r)
00085 {
00086 board64 -= r.board64;
00087 board32 -= r.board32;
00088 PieceStand new_stand(piece_stand);
00089 new_stand.subAtmostOnePiece(r.pieceStand());
00090 piece_stand = new_stand.getFlags();
00091 return *this;
00092 }
00093 void add(Move move) { board64 += move.intValue(); }
00094 void changeTurn() { board64 ^= static_cast<uint64_t>(1); }
00095 void setPlayer(Player p)
00096 {
00097 board64 &= ~static_cast<uint64_t>(1);
00098 board64 |= playerToIndex(p);
00099 }
00100 bool playerBit() const { return board64 & 1; }
00101 bool isPlayerOfTurn(Player p) const
00102 {
00103 return playerBit() == playerToIndex(p);
00104 }
00105 Player turn() const { return isPlayerOfTurn(BLACK) ? BLACK : WHITE; }
00110 void setRandom();
00111 size_t size() const { return 2; }
00112 uint64_t operator[](size_t i) const { return i ? board64 : board32; }
00113 struct StandHash
00114 {
00115 CArray<uint64_t, 19*3*3> HashMajorPawn;
00116 CArray<uint64_t, 5*5*5*5> HashPiece;
00117 StandHash();
00118 uint64_t toUint64(PieceStand stand) const
00119 {
00120 int major_pawn = stand.get(PAWN)*9
00121 + stand.get(ROOK)*3 + stand.get(BISHOP);
00122 int pieces = stand.get(GOLD)*125 + stand.get(SILVER)*25
00123 + stand.get(KNIGHT)*5 + stand.get(LANCE);
00124 return HashMajorPawn[major_pawn] + HashPiece[pieces];
00125 }
00126 };
00127 static const StandHash Stand_Hash;
00128 };
00129 inline bool operator==(const HashKey128& l, const HashKey128& r)
00130 {
00131 return l.boardKey() == r.boardKey() && l.pieceStand() == r.pieceStand();
00132 }
00133 inline bool operator!=(const HashKey128& l, const HashKey128& r)
00134 {
00135 return !(l==r);
00136 }
00141 inline bool operator<(const HashKey128& l, const HashKey128& r)
00142 {
00143 if (l.pieceStand() < r.pieceStand())
00144 return true;
00145 else if (r.pieceStand() < l.pieceStand())
00146 return false;
00147 return l.boardKey() < r.boardKey();
00148 }
00149
00150 typedef HashKey128 HashKeyBase;
00151 typedef BoardKey96 BoardKey;
00152 class HashKey : public HashKeyBase
00153 {
00154 public:
00155 HashKey() :HashKeyBase(){}
00156 HashKey(const SimpleState&);
00157 const HashKey newHashWithMove(Move move) const;
00158 const HashKey newMakeMove(Move) const;
00159 const HashKey newUnmakeMove(Move) const;
00160
00161 void dumpContents(std::ostream& os) const;
00162 void dumpContentsCerr() const;
00163 static const HashKey readFromDump(const std::string&);
00164 static const HashKey readFromDump(std::istream&);
00165 };
00166 std::ostream& operator<<(std::ostream& os,const HashKey& h);
00167
00168 class HashGenTable
00169 {
00170 static const CArray2d<HashKey128Layout,Square::SIZE,PTYPEO_SIZE> key;
00171 public:
00172 static void addHashKey(HashKey& hk,Square sq,PtypeO ptypeo) {
00173 assert(sq.isValid() && isValidPtypeO(ptypeo));
00174 hk += HashKey128(key[sq.index()][ptypeo-PTYPEO_MIN]);
00175 }
00176 static void subHashKey(HashKey& hk,Square sq,PtypeO ptypeo) {
00177 assert(sq.isValid() && isValidPtypeO(ptypeo));
00178 hk -= HashKey128(key[sq.index()][ptypeo-PTYPEO_MIN]);
00179 }
00180 };
00181
00182 }
00183 using hash::HashKey;
00184 using hash::HashGenTable;
00185 using hash::BoardKey;
00186 }
00187
00188 namespace std
00189 {
00190 template <typename T> struct hash;
00191 template <>
00192 struct hash<osl::HashKey>{
00193 unsigned long operator()(const osl::HashKey& h) const {
00194 return h.signature();
00195 }
00196 };
00197 template<>
00198 struct hash<osl::BoardKey>
00199 {
00200 unsigned long operator()(const osl::BoardKey& h) const {
00201 return h.signature();
00202 }
00203 };
00204 }
00205
00206 #endif
00207
00208
00209
00210