
#define BOOK_EXTRA_SIZE 250000
#define NOVAL -30000

// =======================================
// OPENING BOOK
// =======================================
class COpeningBook
{
 // structures needed
 struct SBookEntry
 {
  SBookEntry ()
	{
	pNext = NULL;
	wValue = NOVAL;
	}
  ~SBookEntry ()
	{
	}
  void Save (FILE *pFile, unsigned int wPosKey )
  {
		wPosKey &= 65535;
		fwrite (&ulCheck, 4, 1, pFile);
		fwrite (&wKey   , 2, 1, pFile);
		fwrite (&wValue , 2, 1, pFile);
		fwrite (&wPosKey , 2, 1, pFile);
  }
  unsigned int Load (FILE *pFile )
  {
	unsigned int wPosKey = 0;
	fread (&ulCheck, 4, 1, pFile);
	fread (&wKey   , 2, 1, pFile);
	fread (&wValue , 2, 1, pFile);
	fread (&wPosKey , 2, 1, pFile);
	return wPosKey;
  }

  unsigned long ulCheck;
  SBookEntry* pNext;
  unsigned short wKey;
  short wValue;
 };

 public:
 // ctor&dtor
	COpeningBook ( )
	{
	m_pHash = new SBookEntry [ 131072 ];
	m_pExtra = new SBookEntry [ BOOK_EXTRA_SIZE ];
	m_nListSize = 0;
	m_nPositions = 0;
	}

	~COpeningBook ( )
	{
	delete []m_pHash;
	delete []m_pExtra;
	}

 // Functions
 int DoLearning ( int nResult );
 int FindMoves ( SBoard &Board, int Moves[], short wValues[] );
 int DoMove ( SBoard &Board, int &nBestMove );
 void RemovePosition ( SBoard &Board, int bQuiet );
 int  GetValue ( SBoard &Board );
 void AddPosition ( SBoard &Board, short wValue, int bQuiet );
 void AddPosition ( unsigned long ulKey,  unsigned long ulCheck, short wValue, int bQuiet );
 int Load (char *sFileName );
 void Save (char *sFileName, int nTimes );

 // Data
 SBookEntry *m_pHash;
 SBookEntry *m_pExtra;
 int m_nListSize;
 int m_nPositions;
};
