
/// АВТОР Бренкман Андрей (Brenkman Andrey)
/// ПОСЛЕДНЕЕ ИЗМЕНЕНИЕ 2.05.10
/// УРОВЕНЬ МОЕГО ДОВЕРИЯ 50%


//!
#include "a_Header_constants.h"
#include "a_Undo.h"
#include "a_List.h"
#include "a_Position.h"

#define TEST_H 0 // включаем-выключаем(1-0) режим вывода в файл тестовой информации


/// реализуем ZObrist-ключи


class l_ZObrist
{

/// поля класса
//////////////////////////////////////////////////////////////////////////////////////
private:

	/// в начале нам нужно заполнить вспомогательный массив случайных чисел 
	/// связанных с расположением фигуры на доске в нем все фигуры на всех полях
	/// это трехмерный массив координаты которого цвет, имя, координата фигуры
	/// массив этот глобальный и содержит случайные числа
	/// в дальнейшем складывая эти числа мы получим случайный ключ тем не менее
	/// однозначно связанный с данной позицией
	/// [цвет фигуры][имя фигуры][координата фигуры]
	/// 2*6*64= 768 
	unsigned __int64 random_piese_key[2][MAX_NAME][MAX_COORDINATE];

	/// массив для запоминания хеш-ключей позиций при погружении на глубину
	/// т.е. у нас записываются не только ходы в pv_current но и ключи позиций
	/// другими словами запоминаем ветку ключей позиций
	unsigned __int64 hash_three_moves[MAX_DEPTH];

	/// массив для запоминания хеш-ключей позиций
	/// при анализе входящей строки от оболочки
	/// другими словами запоминаем ветку ключей позиций расчитанных по входящей строке от оболочки
	unsigned __int64 hash_string_moves[1000];

	/// запоминаем количество ходов в строке
	unsigned __int16 save_cnt_move;

//////////////////////////////////////////////////////////////////////////////////////
public:

	/// РАБОТА С ХЕШ - КЛЮЧОМ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	///---------------------------------------------------------------------------
	/// каждой возможной позиции каждой возможной фигуры 
	/// присваиваем случайное число
	void ini_random_piese_key();

	///---------------------------------------------------------------------------
	/// инициализируем ключ начальной позиции
	void start_position_random_key
	(
		struct Position & position/// представление доски
	);

	///---------------------------------------------------------------------------
	/// меняем ключ во время хода
	void modification_random_key
	(
		struct Position & position,/// представление доски
		bool  colour_figure,/// цвет ходящей стороны
		unsigned __int8 i,/// номер хода по списку
		struct List & list_surplus_moves,/// представление списка ходов
		struct Undo & undo///информация для отката хода
	);


//////////////////////////////////////////////////////////////////////////////////////
private:

	///---------------------------------------------------------------------------
	/// генерируем случайный 64 битный ключ
	unsigned __int64 rand_64();


//////////////////////////////////////////////////////////////////////////////////////
public:

	/// ПОВТОРЫ ПОЗИЦИЙ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	///---------------------------------------------------------------------------
	/// возвращаем количество ходов в строке игры переданной из оболочки
	__int32 get_save_cnt_move();

	///---------------------------------------------------------------------------
	/// инициализируем хеш-массив повторов возрастающими числами что бы исключить ложное срабатывание
	void ini_hash_three();

	///---------------------------------------------------------------------------
	/// инициализируем хеш-массив повторов возрастающими числами что бы исключить ложное срабатывание
	void ini_hash_string_moves();

	///---------------------------------------------------------------------------
	/// запоминаем хеш-ключ на текущей глубине
	/// нужно для детектора повторов в линии варианта
	void save_hash_three
	(
		unsigned __int64 key,/// хеш-ключ
		unsigned __int8 depth /// глубина
	);

	///---------------------------------------------------------------------------
	/// запоминаем хеш-ключ для текущего хода
	/// нужно для детектора повторов в линии партии переданной оболочкой
	void save_hash_string_moves
	(
		unsigned __int64 key,/// хеш-ключ
		unsigned __int16 cnt_move /// счетчик ходов
	);

	///---------------------------------------------------------------------------
	/// анализируем линию ключей полученную из строки партии. если видим совпадение то возвращаем 1 иначе 0
	/// конечно совпадение не должно быть трехкратным ведь тогда это уже ничья
	bool analysis_hash_string_moves
	(
		unsigned __int8 depth /// глубина
	);

};