00001 //---------------------------------------------------------------------------- 00002 /** @file ZobristHash.hpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef ZOBRISTHASH_HPP 00007 #define ZOBRISTHASH_HPP 00008 00009 #include "Hex.hpp" 00010 00011 _BEGIN_BENZENE_NAMESPACE_ 00012 00013 //---------------------------------------------------------------------------- 00014 00015 /** Zobrist Hashing. 00016 00017 Hash values are shared amoung all instances of ZobristHash. 00018 00019 Each unique boardsize has its own base hash, so hashes of 00020 positions on different boardsizes should never collide. 00021 */ 00022 class ZobristHash 00023 { 00024 public: 00025 /** Constructs a ZobristHash object for the given boardsize. */ 00026 ZobristHash(int width, int height); 00027 00028 /** Returns the current hash value for the color to play. */ 00029 hash_t Hash(HexColor toPlay) const; 00030 00031 /** Helper function: same as Hash(EMPTY). */ 00032 hash_t Hash() const; 00033 00034 /** Reset hash to the base hash value. */ 00035 void Reset(); 00036 00037 /** Sets the hash to base hash value updated with the played 00038 stones in black and white. */ 00039 void Compute(const bitset_t& black, const bitset_t& white); 00040 00041 /** Incrementally updates the hash value with the given move. */ 00042 void Update(HexColor color, HexPoint cell); 00043 00044 private: 00045 00046 /** Hash for the current state. */ 00047 hash_t m_hash; 00048 00049 /** Base hash. */ 00050 hash_t m_base; 00051 00052 //---------------------------------------------------------------------- 00053 00054 /** Data shared amoungst all instances of ZobristHash. */ 00055 struct GlobalData 00056 { 00057 static const int NUM_HASHES = 4096; 00058 00059 hash_t m_hashes[NUM_HASHES]; 00060 00061 hash_t* m_black_hashes; 00062 00063 hash_t* m_white_hashes; 00064 00065 hash_t* m_color_hashes[BLACK_AND_WHITE]; 00066 00067 hash_t* m_toPlay_hashes[BLACK_WHITE_EMPTY]; 00068 00069 GlobalData(); 00070 00071 void SetPointers(); 00072 00073 void GetHashes(); 00074 }; 00075 00076 /** Returns a reference to a static local variable so that it is 00077 initialized on first use if some global variable is 00078 initialized. */ 00079 static GlobalData& GetGlobalData(); 00080 }; 00081 00082 inline hash_t ZobristHash::Hash(HexColor toPlay) const 00083 { 00084 return m_hash ^ *GetGlobalData().m_toPlay_hashes[toPlay]; 00085 } 00086 00087 inline hash_t ZobristHash::Hash() const 00088 { 00089 return Hash(EMPTY); 00090 } 00091 00092 inline void ZobristHash::Reset() 00093 { 00094 m_hash = m_base; 00095 } 00096 00097 inline void ZobristHash::Update(HexColor color, HexPoint cell) 00098 { 00099 HexAssert(HexColorUtil::isBlackWhite(color)); 00100 HexAssert(0 <= cell && cell < BITSETSIZE); 00101 m_hash ^= GetGlobalData().m_color_hashes[color][cell]; 00102 } 00103 00104 //---------------------------------------------------------------------------- 00105 00106 _END_BENZENE_NAMESPACE_ 00107 00108 #endif // ZOBRISTHASH_HPP