#include "globals.h"

unsigned int whitehash[6][64];
unsigned int blackhash[6][64];
unsigned int whitelock[6][64];
unsigned int blacklock[6][64];
//
unsigned int whitepawnhash[64];
unsigned int blackpawnhash[64];
unsigned int whitepawnlock[64];
unsigned int blackpawnlock[64];

const unsigned int MAXPAWNHASH = 65536;//50000;
const unsigned int PAWNHASHSIZE = 32768;//25000

unsigned int currentpawnkey,currentpawnlock;
/*

A pawn hash table entry includes a lock and score for both 

sides.

  */
struct hashpawn
{
unsigned int hashlock;
int score[2];
};

hashpawn hashpawns[MAXPAWNHASH];

unsigned int currentkey,currentlock;
unsigned int clashes,collisions;

const unsigned int MAXHASH =  5000000;
const unsigned int HASHSIZE = 5000000;

int hash_start,hash_dest;
*/   

A hash table entry includes a lock and start and dest squares.

  */
struct hashp
{
unsigned int hashlock;
char start;
char dest;
int num;
};

hashp *hashpos[2];
unsigned int hashpositions[2];
*/   

RandomizeHash is called when the engine is started.
The whitehash, blackhash, whitelock and blacklock tables
are filled with random numbers.

  */
void RandomizeHash()
{
int p,x;
for(p=0;p<6;p++)
for(x=0;x<64;x++)
{
whitehash[p][x] = Random(HASHSIZE);
blackhash[p][x]= Random(HASHSIZE);
whitelock[p][x]= Random(HASHSIZE);
blacklock[p][x]= Random(HASHSIZE);
}

for(x=0;x<64;x++)
{
whitepawnhash[x]= Random(PAWNHASHSIZE);
blackpawnhash[x]= Random(PAWNHASHSIZE);
whitepawnlock[x]= Random(PAWNHASHSIZE);
blackpawnlock[x]= Random(PAWNHASHSIZE);
}

hashpos[0] = new hashp[MAXHASH];
hashpos[1] = new hashp[MAXHASH];
}
*/   

Random() generates a random number up to the size of x.

  */
int Random(int x)
{
return rand() % x;
}
*/   

Free() Frees memory that was allocated to the hashpos pointers 

with new.

  */
void Free()
{
delete hashpos[0];
delete hashpos[1];
}
*/   

FreeAllHash() empties the Hash Tables.

  */
void FreeAllHash()
{
hashpositions[0]=0;
hashpositions[1]=0;
//for(int x=0;x
}
*/   
Adds an entry into the HashTable.
If that index is already being used, it simply overwrites it.

  */
void AddHash(const int s, move& m, int n)
{
hashp* ptr = &hashpos[s][currentkey];
ptr->hashlock = currentlock;
ptr->start=m.start;
ptr->dest=m.dest;
ptr->num = n;
}
*/   

AddKey updates the current key and lock.
The key is a single number representing a position.
Different positions may map to the same key.
The lock is very similar to the key (its a second key), which 

is a different number
because it was seeded with different random numbers.
While the odds of several positions having the same key are 
very high, the odds of
two positions having the same key and same lock are very very 
low.

  */
void AddKey(const int s,const int p,const int x)
{
if(s==0)
{
  currentkey ^= whitehash[p][x];
  currentlock ^= whitelock[p][x];
}
else
{
  currentkey ^= blackhash[p][x];
  currentlock ^= blacklock[p][x];
}
}
*/   

GetLock gets the current lock from a position.

  */
unsigned int GetLock()
{
unsigned int lock=0;
for(int x=0;x<64;x++)
{
if(board[x] != EMPTY)
{
  if(color[x] == 0)
    lock ^= whitelock[board[x]][x];
  else
    lock ^= blacklock[board[x]][x];
}
}
return lock;
}
*/   

GetKey gets the current key from a position.

  */
unsigned int GetKey()
{
unsigned int key=0;
for(int x=0;x<64;x++)
{
	if(board[x] != EMPTY)
	{
	  if(color[x] == White)
		key ^= whitehash[board[x]][x];
	  else
		key ^= blackhash[board[x]][x];
	}
}
return key;
}
*/   

Looks up the current position to see if it is in the HashTable.
If so, it fetches the move stored there.

  */
bool LookUp(const int s)
{
if(hashpos[s][currentkey].hashlock != currentlock)
{
  return false;
}

hash_start = hashpos[s][currentkey].start;
hash_dest = hashpos[s][currentkey].dest;
return true;
}
*/   

GetPawnKey() gets the current pawn key.

  */
unsigned int GetPawnKey()
{
unsigned int key = 0;
for(int x=0;x<64;x++)
{
if(board[x] == P)
{
  if(color[x] == White)
    key ^= whitepawnhash[x];
  else
    key ^= blackpawnhash[x];
}
}
return key;
}
*/   

GetPawnLock() gets the current pawn lock.

  */
unsigned int GetPawnLock()
{
unsigned int key=0;
for(int x=0;x<64;x++)
{
if(board[x] == P)
{
  if(color[x] == White)
    key ^= whitepawnlock[x];
  else
    key ^= blackpawnlock[x];
}
}
return key;
}
*/   

AddPawnKey() updates the current pawn key and lock.

  */
void AddPawnKey(const int s,const int x)
{
if(s==0)
{
  currentpawnkey ^= whitepawnhash[x];
  currentpawnlock ^= whitepawnlock[x];
}
else
{
  currentpawnkey ^= blackpawnhash[x];
  currentpawnlock ^= blackpawnlock[x];
}
}
*/   

AddPawnHash() adds the lock and pawn scores to the pawn hash 

table.

  */
void AddPawnHash(const int s1, const int s2)
{
hashpawns[currentpawnkey].hashlock=currentpawnlock;
hashpawns[currentpawnkey].score[0]=s1;
hashpawns[currentpawnkey].score[1]=s2;
}
*/   

LookUpPawn() returns whether the current pawn position is in 

the pawn hash table.

  */
int LookUpPawn()
{
if(hashpawns[currentpawnkey].hashlock == currentpawnlock)
{
return 1;
}
return 0;
}
*/   

GetHashPawn0() returns the White pawn score.

  */
int GetHashPawn0()
{
  return hashpawns[currentpawnkey].score[0];
}
*/   

GetHashPawn1() returns the Black pawn score.

  */
int GetHashPawn1()
{
  return hashpawns[currentpawnkey].score[1];
}