No Zobrist key

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
cdani
Posts: 2204
Joined: Sat Jan 18, 2014 10:24 am
Location: Andorra

Re: No Zobrist key

Post by cdani »

Daniel Anulliero wrote:Mersenne twister is a good generator and they had 1000 64 bits numbers on the page (I can't find now)
http://www.math.sci.hiroshima-u.ac.jp/~ ... T/emt.html
flok

Re: No Zobrist key

Post by flok »

Henk wrote:

Code: Select all

        public override int GetHashCode()
        {
            int hash = 0;
            for &#40;int i = 0; i < SIZE-1; i++)
            &#123;
                hash += &#40;int&#41;&#40;rep&#91;i&#93; % 13&#41;;
                hash = &#40;hash << 4&#41;;
               
            &#125;
            hash += &#40;int&#41;&#40;rep&#91;SIZE-1&#93; % 13&#41;;


            return hash;
        &#125;
Maybe this is better. At least I understand it. Collecting 8 times four bits because hash code must be 32 bits. Largest prime for four bits is 13.
Can you explain why this is a good hash?
Did you test how often it has collisions?
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: No Zobrist key

Post by Henk »

flok wrote:
Henk wrote:

Code: Select all

        public override int GetHashCode&#40;)
        &#123;
            int hash = 0;
            for &#40;int i = 0; i < SIZE-1; i++)
            &#123;
                hash += &#40;int&#41;&#40;rep&#91;i&#93; % 13&#41;;
                hash = &#40;hash << 4&#41;;
               
            &#125;
            hash += &#40;int&#41;&#40;rep&#91;SIZE-1&#93; % 13&#41;;


            return hash;
        &#125;
Maybe this is better. At least I understand it. Collecting 8 times four bits because hash code must be 32 bits. Largest prime for four bits is 13.
Can you explain why this is a good hash?
Did you test how often it has collisions?
I don't know if it is a good hash but I understand the code. Might be it is a bad hash with many collisions but I don't think it makes my engine play worse.

Best is to switch too Zobrist key but maybe that is a waste of time.
Daniel Anulliero
Posts: 759
Joined: Fri Jan 04, 2013 4:55 pm
Location: Nice

Re: No Zobrist key

Post by Daniel Anulliero »

cdani wrote:
Daniel Anulliero wrote:Mersenne twister is a good generator and they had 1000 64 bits numbers on the page (I can't find now)
http://www.math.sci.hiroshima-u.ac.jp/~ ... T/emt.html
Yes I know the site Daniel but it's the 1000 numbers I can't find in it :wink:
AndrewGrant
Posts: 1756
Joined: Tue Apr 19, 2016 6:08 am
Location: U.S.A
Full name: Andrew Grant

Re: No Zobrist key

Post by AndrewGrant »

#WeAreAllDraude #JusticeForDraude #RememberDraude #LeptirBigUltra
"Those who can't do, clone instead" - Eduard ( A real life friend, not this forum's Eduard )
Daniel Anulliero
Posts: 759
Joined: Fri Jan 04, 2013 4:55 pm
Location: Nice

Re: No Zobrist key

Post by Daniel Anulliero »

AndrewGrant wrote:http://www.math.sci.hiroshima-u.ac.jp/~ ... 64.out.txt

Took me 15 seconds. Come on :)
Cool Andrew lol
You know I am an old man now , with less vision !! :)
User avatar
stegemma
Posts: 859
Joined: Mon Aug 10, 2009 10:05 pm
Location: Italy
Full name: Stefano Gemma

Re: No Zobrist key

Post by stegemma »

Henk wrote:Properties side to move, castling rights, ep target square are stored in

Code: Select all

rep&#91;7&#93; = board.Other;
If you know a much simpler and still effective formula to compute a hash key then that would be better. For I don't like mystic code. Might be I found it somewhere on internet. Can't remember.
This is my last version of my "mystic" code to generate hash, already discussed in another thread:

Code: Select all

	uint64_t _URandS&#40;uint64_t &seed0, uint64_t &seed1&#41;
	&#123;
		uint64_t x = seed0;
		const uint64_t y = seed1;
		seed0 = y;
		x ^= x << 23; // a
		x ^= x >> 17; // b
		x ^= y ^ &#40;y >> 26&#41;; // c
		seed1 = x;
		return x + y;
	&#125;

	uint64_t clsBoard&#58;&#58;GetBookHash&#40;) const
	&#123;
		// NB&#58; non cambiare mai questa definizione, per non perdere i libri già compilati!!!
		#define HH&#40;a&#41; seeds&#91;0&#93; ^= &#40;a&#41;; boBookHash ^= _URandS&#40;seeds&#91;0&#93;, seeds&#91;1&#93;);
		uint64_t seeds&#91;&#93; = &#123; 0xA10E014701010401ULL, 0x02C070202CDE2ULL &#125;;
		uint64_t boBookHash = boBits&#91;boAllPieces&#93;;
		HH&#40;boBits&#91;boKings&#93;)
		HH&#40;boBits&#91;boQueens&#93;)
		HH&#40;boBits&#91;boRooks&#93;)
		HH&#40;boBits&#91;boBishops&#93;)
		HH&#40;boBits&#91;boKnights&#93;)
		HH&#40;boBits&#91;boPawns&#93;)
		HH&#40;color&#41;
		HH&#40;boBits&#91;boFriends&#93;)
		HH&#40;boBits&#91;boEnpPawn&#93; - boBits&#91;boCastlings&#93;)
		return boBookHash;
	&#125;
It is a little crazy but it works ;)
Author of Drago, Raffaela, Freccia, Satana, Sabrina.
http://www.linformatica.com
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: No Zobrist key

Post by Henk »

Henk wrote:I use this key for hash table.

Code: Select all

 
        public Key&#40;IChessBoardBits board&#41;
        &#123;
            rep = new ulong&#91;SIZE&#93;;
            rep&#91;0&#93; = board.Pawns;
            rep&#91;1&#93; = board.Kings;
            rep&#91;2&#93; = board.Knights;
            rep&#91;3&#93; = board.Bishops;
            rep&#91;4&#93; = board.Rooks;
            rep&#91;5&#93; = board.Queens;
            rep&#91;6&#93; = board.WhitePieces;
            rep&#91;7&#93; = board.Other;
        &#125;

        public bool Equals&#40;Key key&#41;
        &#123;
            for &#40;int i = 0; i < SIZE; i++)
            &#123;
                if &#40;rep&#91;i&#93; != key&#91;i&#93;) return false;
            &#125;
            return true;
        &#125;

        

        public override int GetHashCode&#40;)
        &#123;
            int hash, i;
            for &#40;hash = i = 0; i < SIZE; ++i&#41;
            &#123;
                for &#40;int j = 0; j < 4; j++)
                &#123;
                    hash += &#40;int&#41;&#40;rep&#91;i&#93; >> &#40;j * 8&#41;);
                    hash += &#40;hash << 10&#41;;
                    hash ^= &#40;hash >> 6&#41;;
                &#125;
            &#125;
            hash += &#40;hash << 3&#41;;
            hash ^= &#40;hash >> 11&#41;;
            hash += &#40;hash << 15&#41;;
          
          
            return hash;
         &#125;
And I wonder if it does make my engine slow and if Zobrist key would be much better. But hash table is not used in qSearch.

[Don't ask how GetHashCode works for it's abracadabra to me now]
Found it. It was copied from this site.

https://en.wikipedia.org/wiki/Jenkins_hash_function
User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: No Zobrist key

Post by hgm »

If you calculate the hash for the entire board from scratch in every node it doesn't really matter much what method you use. It will always be orders of magnitude too slow.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: No Zobrist key

Post by Henk »

Yes. Zobrist key is better but still don't know if it is worth while to change my code.

By the way I forget a % 256 when extracting a byte.

Code: Select all

 //Jenkins hash function
        public override int GetHashCode&#40;)
        &#123;
            int hash, i;
            for &#40;hash = i = 0; i < SIZE; ++i&#41;
            &#123;
                for &#40;int j = 0; j < 4; j++)
                &#123;
                    var octet = &#40;int&#41;(&#40;rep&#91;i&#93; >> &#40;j * 8&#41;) % 256&#41;;
                    hash += octet;
                    hash += &#40;hash << 10&#41;;
                    hash ^= &#40;hash >> 6&#41;;
                &#125;
            &#125;
            hash += &#40;hash << 3&#41;;
            hash ^= &#40;hash >> 11&#41;;
            hash += &#40;hash << 15&#41;;


            return hash;
        &#125;

Might be this is faster:
http://www.isthe.com/chongo/tech/comp/f ... #FNV-param

Code: Select all

  // FNV hash function
        public override int GetHashCode&#40;)
        &#123;
            unchecked
            &#123;
                int hash = &#40;int&#41;2166136261;

                for &#40;int i = 0; i < SIZE; ++i&#41;
                &#123;
                    for &#40;int j = 0; j < 4; j++)
                    &#123;
                        hash *= 16777619;
                        var octet = &#40;int&#41;(&#40;rep&#91;i&#93; >> &#40;j * 8&#41;) % 256&#41;;
                        hash ^= octet;

                    &#125;
                &#125;
                return hash;
            &#125;
        &#125;