00001 //---------------------------------------------------------------------------- 00002 /** @file ZobristHash.cpp 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #include "SgSystem.h" 00007 #include "SgRandom.h" 00008 #include "ZobristHash.hpp" 00009 00010 using namespace benzene; 00011 00012 //---------------------------------------------------------------------------- 00013 00014 /** Use hashes defined in ZobrishHashes.hpp if this is true. 00015 @bug Setting this to 0 will break all OpeningBooks and SolverDBs. 00016 Only do this if you really know what you are doing. 00017 */ 00018 #define USE_PREDEFINED_HASHES 1 00019 00020 //---------------------------------------------------------------------------- 00021 00022 ZobristHash::GlobalData::GlobalData() 00023 { 00024 SetPointers(); 00025 GetHashes(); 00026 } 00027 00028 void ZobristHash::GlobalData::SetPointers() 00029 { 00030 m_black_hashes = &m_hashes[1024]; 00031 m_white_hashes = &m_hashes[2048]; 00032 m_color_hashes[BLACK] = m_black_hashes; 00033 m_color_hashes[WHITE] = m_white_hashes; 00034 m_toPlay_hashes[BLACK] = &m_hashes[3072]; 00035 m_toPlay_hashes[WHITE] = &m_hashes[3073]; 00036 m_toPlay_hashes[EMPTY] = &m_hashes[3074]; 00037 } 00038 00039 #if USE_PREDEFINED_HASHES 00040 00041 namespace 00042 { 00043 #include "ZobristHashes.hpp" 00044 } 00045 00046 void ZobristHash::GlobalData::GetHashes() 00047 { 00048 for (int i = 0; i < NUM_HASHES; ++i) 00049 m_hashes[i] = s_predefined_hashes[i]; 00050 } 00051 00052 #else 00053 00054 void ZobristHash::GlobalData::GetHashes() 00055 { 00056 int old_seed = SgRandom::Global().Seed(); 00057 SgRandom::Global().SetSeed(1); 00058 for (int i = 0; i < NUM_HASHES; ++i) 00059 m_hashes[i] = HashUtil::RandomHash(); 00060 SgRandom::SetSeed(old_seed); 00061 } 00062 00063 #endif 00064 00065 //---------------------------------------------------------------------------- 00066 00067 ZobristHash::ZobristHash(int width, int height) 00068 : m_base(GetGlobalData().m_hashes[30 * width + height]) 00069 { 00070 HexAssert(30 * width + height < 1024); 00071 Reset(); 00072 } 00073 00074 ZobristHash::GlobalData& ZobristHash::GetGlobalData() 00075 { 00076 static GlobalData data; 00077 return data; 00078 } 00079 00080 void ZobristHash::Compute(const bitset_t& black, const bitset_t& white) 00081 { 00082 Reset(); 00083 for (int p = 0; p < BITSETSIZE; ++p) 00084 { 00085 if (black.test(p)) m_hash ^= GetGlobalData().m_black_hashes[p]; 00086 if (white.test(p)) m_hash ^= GetGlobalData().m_white_hashes[p]; 00087 } 00088 } 00089 00090 //----------------------------------------------------------------------------