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

#include "Position.h"
#include "PV_line.h"

/// перебор позиций
/// включает в себя данные и методы основного перебора

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

 альфа бета с амортизацией отказов
 int AlphaBeta (pos, depth, alpha, beta) 
 {
	if (depth == 0) return Evaluate(pos);
	best = -INFINITY;
	succ = Successors(pos);
	while (!Empty(succ)) 
	{
		pos = RemoveOne(succ);
		value = -AlphaBeta(pos, depth - 1, -beta, -alpha);
		if (value > best) best = value;
	    if (value > alpha) alpha = value;
        if (alpha >= beta) return alpha;
	}
	return best;
 }
*/


namespace Search
{

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

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

	//---------------------------------------------------------------------------
	/// 
	void set_depth_max_rem
	(
		unsigned __int8 _depth_max_rem//
	);


	//---------------------------------------------------------------------------
	/// 
	void ini_flag_stop_null_move
	(
		bool _flag_stop_null_move//
	);

	//---------------------------------------------------------------------------
	/// 
	void ini_deep_time_terminate
	(
		double _deep_time_terminate//
	);


	//---------------------------------------------------------------------------
	/// 
	void ini_global_loop();


	///---------------------------------------------------------------------------
	/// возвращаем флаг остановки поиска. так если в глубине поиска получили команду
	/// на остановку то передаем ее наружу
	bool get_stop_search();

	///---------------------------------------------------------------------------
	/// возвращаем лучший вариант
	struct PV_line & get_pv_best();

	///---------------------------------------------------------------------------
	/// возвращаем количество рассмотренных узлов
	__int64  get_nodes();

	///---------------------------------------------------------------------------
	///обнуляем количество рассмотренных узлов
	void set_nodes_in_0();

	///---------------------------------------------------------------------------
	/// поиск за белых
	__int32 white
	(
		struct Position & position,/// представление доски
		__int32 alpha,///
		const __int32 beta,///
		const unsigned __int8 depth_max,/// максимальная глубина
		const unsigned __int8 depth,/// глубина
		const __int32 description_move,/// тип хода который привел к данной позиции
		const bool flag_pv_f,/// основной ли это вариант (pv)
		bool flag_check,///флаг шаха
		const bool flag_null_m/// флаг нулевого хода
	);

	///---------------------------------------------------------------------------
	/// поиск за черных 
	__int32 black
	(
		struct Position & position,/// представление доски
		const __int32 alpha,///
		__int32 beta,///
		const unsigned __int8 depth_max,/// максимальная глубина
		const unsigned __int8 depth,/// глубина
		const __int32 description_move,/// тип хода который привел к данной позиции
		const bool flag_pv_f,/// основной ли это вариант (pv)
		bool flag_check,///флаг шаха
		const bool flag_null_m/// флаг нулевого хода
	);

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

	///---------------------------------------------------------------------------
	/// очень эффективная эвристика известная под именем нулевого хода
	/// я долго не мог оценить его по достоинству но в итоге истина мне открылась :)
	/// суть его в том что
	/// мы пропускаем свой ход и если даже при такой форе противник не находит
	/// лучшего хода эту ветку можно подрезать
	/// за белых
	inline __int32 null_move_white
	(
		struct Position & position,/// представление доски
		const __int32 alpha,//
		const __int32 beta,//
		const unsigned __int8 depth_max,/// максимальная глубина
		const unsigned __int8 depth,/// глубина
		const __int32 description_move,/// тип хода который привел к данной позиции
		const bool flag_pv_f,/// основной ли это вариант (pv)
		const bool old_flag_check,///флаг шаха
		const bool flag_null_m,/// флаг нулевого хода
		const unsigned __int8 new_depth, /// следующая глубина
		const unsigned __int64 key_undo
	);

	///---------------------------------------------------------------------------
	/// мы пропускаем свой ход и если даже при такой форе противник не находит
	/// лучшего хода эту ветку можно подрезать
	/// за черных
	inline __int32 null_move_black
	(
		struct Position & position,/// представление доски
		const __int32 alpha,///
		const __int32 beta,///
		const unsigned __int8 depth_max,/// максимальная глубина
		const unsigned __int8 depth,/// глубина
		const __int32 description_move,/// тип хода который привел к данной позиции
		const bool flag_pv_f,/// основной ли это вариант (pv)
		const bool old_flag_check,///флаг шаха
		const bool flag_null_m,/// флаг нулевого хода
		const unsigned __int8 new_depth, /// следующая глубина
		const unsigned __int64 key_undo
	);


	///---------------------------------------------------------------------------
	/// производим расчеты на максимальной глубине. для белых
	inline __int32 max_depth_white
	(
		struct Position & position,/// представление доски
		const __int32 alpha,///
		const __int32 beta,///
		const bool flag_pv_f,/// основной ли это вариант (pv)
		const unsigned __int8 depth/// глубина
	);

	///---------------------------------------------------------------------------
	/// производим расчеты на максимальной глубине. для черных
	inline __int32 max_depth_black
	(
		struct Position & position,/// представление доски
		const __int32 alpha,///
		const __int32 beta,///
		const bool flag_pv_f,/// основной ли это вариант (pv)
		const unsigned __int8 depth/// глубина
	);


	///---------------------------------------------------------------------------
	///
	inline void quit_or_stop();

};
