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


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

/// включаем-выключаем(1-0) режим подсчета количества
/// записанных и считанных позиций
/// надо еще включить флаг TEST_WRITE_READ в j_Hash.h
#define TEST_WRITE_READ_WN 0 
                             




/// разбираем команду go и запускаем расчет

/// реализована поддержка следующих команд:
/// команды для блица типа 5 мин либо 5 мин + добавление за ход в секундах
/// > go btime 300000 wtime 300000 
/// for game in 5min. 

/// > go btime 302000 wtime 302000 winc 2000 binc 2000 
/// with incremental clock 5 min + 2 sec. 

/// время на определенное количество ходов
/// > go movestogo 40 wtime 300000 btime 300000 
/// for 40 moves in 5 min. 
/// причем арена выдает в виде
/// > go wtime 300000 btime 300000  movestogo 40

/// это понятно что для анализа
/// > go infinite 
/// for analysing. 

/// время на ход говорят что фриц не поддерживает а по моему все он держит надо проверять
/// > go movetime 300000 
/// Exactly 5min for the next move, not supported by Fritz. 

/// поиск на заданную глубину
/// > go depth 5 

class c_Go
{

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

	__int64 nodes_y;             /// количество узлов на данной глубине
	__int64 nodes_previous;      /// запоминаем полное количество узлов
	double koff_deepening;       /// высчитываем насколько дольше по времени 
							     /// считается следующая глубина

	double wtime_go_command;     /// оставшееся время на игру за белых
	double btime_go_command;     /// оставшееся время на игру за черных
	double winc_go_command;      ///  добавление времени за ход для белых
	double binc_go_command;      ///  добавление времени за ход для черных

	__int8 depth_max_go_command; /// глубина перебора
	double movetime_go_command;  /// время на ход
	__int8 movestogo_go_command; /// количество ходов за определенное время
	bool infinite_go_command;    /// флаг бесконечного анализа


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

	///
	void parse_go
	(
		struct Position & position,// представление доски
		const std::string string_in//строка команд
	);

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

	/// перебор с циклическим увеличением глубины

	/// циклически перебираем увеличивая глубину до тех пор пока не сработает останов.
	/// т.е. в начале на глубине 1 потом 2 и т.д.
	/// это нужно во первых для заполнения хеш-таблицы
	/// во вторых что бы чувствовать время перебора. например если мы на предыдущей глубине
	/// считали секунду то на следующем в среднем в двадцать раз дольше.

	/// обеспечиваем поддержку нескольких режимов игры

	/// > go depth 5 
	/// поиск на заданную глубину
	/// как только досчитали до заданной глубины depth_max возвращаем результат

	/// > go btime 300000 wtime 300000 
	/// for game in 5min. 
	/// > go btime 302000 wtime 302000 winc 2000 binc 2000 
	/// with incremental clock 5 min + 2 sec. 
	/// команды для блица типа 5 мин либо 5 мин + добавление за ход в секундах
	/// как только время счета превысило time_terminate возвращаем результат
	/// расчет пока слишком примитивный time_terminate = wtime/100;
	/// т.е. мы берем оставшееся время для игры за черных и делим на сто.
	/// оставшееся время мы считали до вызова этой функции и перевели его в секунды

	/// > go infinite
	/// для режима анализа infinite просто задаем depth_max равным 50. 
	/// отсечка будет в глубине
	/// перебора когда придет команда quit или stop

	/// > go movetime 300000 
	/// задание времени на ход тоже очень простое time_terminate = movetime;


	/// > go movestogo 40 wtime 300000 btime 300000 
	/// for 40 moves in 5 min. 
	/// время на определенное количество ходов
	/// не поддерживается эта команда будет распознана как
	/// > go wtime 300000 btime 300000 
	/// сейчас этот момент не актуален но в будущем надо будет править

	///в конце расчета печатаем вариант и делаем ход

	///--------------------------------------------------------------------------
	void deepening
	(
		struct Position & position, /// представление доски
		unsigned __int8 & depth_max,
		double & max_time_move_search
	);


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

	///--------------------------------------------------------------------------
	/// инициализируем параметры игры
	void ini_go_command
	(
		const std::string string_in//строка команд
	);

	///--------------------------------------------------------------------------
	/// инициализируем параметры циклического перебора
	void ini_deepening
	(
		struct Position & position,// представление доски
		unsigned __int8 & depth_max,
		double & max_time_move_search
	);

	///--------------------------------------------------------------------------
	/// проверяем что параметры игры инициализированны
	void test_ini_go_command();

	///--------------------------------------------------------------------------
	///
	void do_bestmove();

	///--------------------------------------------------------------------------
	///
	void print_deepening_line
	(
		struct Position & position,// представление доски
		const __int64 nodes,// количество рассмотренных узлов(позиций)
		const double time_current,  // сколько времени прошло при данной итерации
		const unsigned __int8 depth,
		const __int32 value_root,// оценка лучшего варианта и делаемого хода.
		bool & flag_mate// найден мат 
	);

	///--------------------------------------------------------------------------
	///
	void test_end_deepening
	(
		struct Position & position,// представление доски
		const unsigned __int64 key_control
	);

	///--------------------------------------------------------------------------
	///
	void test_loop
	(
		struct Position & position,// представление доски
 		const __int32 test_eval,// запоминаем оценку материала для контроля
		const unsigned __int64 key_control// запоминаем хеш-ключ для контроля
	);

};
