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




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

/// включаем-выключаем(1-0) контроль списка ходов 
#define KONTROL_B 0 

/// 
#define TEST_H 0 



/// реализуем битбоард(bit board) генератор
/// это простой генератор без ротации тем не менее в его написании
/// мне помогла статья:
/// "Hyatt, Robert. Rotated bitmaps, a new twist on an old idea"

/// по позиции заданной в классе Chess_bitboard генерирует список ходов
/// список ходов избыточен потому что включает ходы под шах и открывающие шах
/// + реализован детектор шахов

/// проверка на шах в этом модуле не сделана потому что это требует движения фигур
/// поэтому на шах позицию мы проверяем в другом месте после реализации хода

/// ТЕСТИРОВАНИЕ
/// тестируем в полном переборе на специальных тестовых позициях
/// на данный момент(7.09.11) багов(bugs) не замечено


///---------------------------------------------------------------------------
/// список возможных ходов 
class h_Generator_moves 
{

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

	///---------------------------------------------------------------------------
	/// генерируем список взятий + превращения пешки (для белых)
	void generator_captures_white
	(
		struct List & list,/// представление списка ходов
		const struct Position & position /// представление доски            
	);

	///---------------------------------------------------------------------------
	/// генерируем список взятий  + превращения пешки (для черных)
	void generator_captures_black
	(
		struct List & list,/// представление списка ходов
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// генерируем список остальных ходов 
	/// (т.е. всех ходов кроме взятий + превращения пешки)(для белых)
	void generator_move_white
	(
		struct List & list,/// представление списка ходов
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// генерируем список остальных ходов 
	/// (т.е. всех ходов кроме взятий + превращения пешки)(для черных)
	void generator_move_black
	(
		struct List & list,/// представление списка ходов
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// под боем ли король белых если шаха нет то функция 
	/// возвращает 0 иначе цифру шахующей фигуры
	unsigned __int8 king_white_check
	(
		const struct Position & position /// представление доски   
	);

	///---------------------------------------------------------------------------
	/// под боем ли король черных если шаха нет то функция 
	/// возвращает 0 иначе цифру шахующей фигуры
	unsigned __int8 king_black_check
	(
		const struct Position & position /// представление доски   
	);


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


	///---------------------------------------------------------------------------
	/// под боем ли белые поля если шаха нет то функция 
	/// возвращает 0 иначе цифру шахующей фигуры
	inline unsigned __int8 white_check_square
	(
		const unsigned __int8 & sq,///индекс проверяемого поля(0-63) 
		const struct Position & position /// представление доски   
	);

	///---------------------------------------------------------------------------
	/// под боем ли черные поля если шаха нет то функция 
	/// возвращает 0 иначе цифру шахующей фигуры
	inline unsigned __int8 black_check_square
	(
		const unsigned __int8 & sq,///индекс проверяемого поля(0-63) 
		const struct Position & position /// представление доски   
	);

	///---------------------------------------------------------------------------
	/// заполняем список ходов - взятия за белых
	/// две функции только из за разного контроля списков(строки взятия)
	inline void list_capture_white
	(
		struct List & list,/// представление списка ходов
		const unsigned __int8 name,/// имя ходящей фигуры
		const unsigned __int8 type_move,/// тип хода
		const unsigned __int8 & from,/// откуда ходим
		const unsigned __int8 & to,/// куда ходим
		unsigned __int8 & count,/// номер хода в списке
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// заполняем список ходов - взятия за черных
	/// две функции только из за разного контроля списков(строки взятия)
	inline void list_capture_black
	(
		struct List & list,/// представление списка ходов
		const unsigned __int8 name,/// имя ходящей фигуры
		const unsigned __int8 type_move,/// тип хода
		const unsigned __int8 & from,/// откуда ходим
		const unsigned __int8 & to,/// куда ходим
		unsigned __int8 & count,/// номер хода в списке
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// заполняем список ходов
	inline void list_record_move_white
	(
		struct List & list,/// представление списка ходов
		const unsigned __int8 name,/// имя ходящей фигуры
		const unsigned __int8 type_move,/// тип хода
		const unsigned __int8 & from,/// откуда ходим
		const unsigned __int8 & to,/// куда ходим
		unsigned __int8 & count,/// номер хода в списке
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// заполняем список ходов
	inline void list_record_move_black
	(
		struct List & list,/// представление списка ходов
		const unsigned __int8 name,/// имя ходящей фигуры
		const unsigned __int8 type_move,/// тип хода
		const unsigned __int8 & from,/// откуда ходим
		const unsigned __int8 & to,/// куда ходим
		unsigned __int8 & count,/// номер хода в списке
		const struct Position & position /// представление доски    
	);

	///---------------------------------------------------------------------------
	/// заполняем список ходов для особых случаев типа рокировки 
	/// взятия на проходе и превращений пешек
	inline void list_record_special
	(
		struct List & list,/// представление списка ходов
		const unsigned __int8 name,/// имя ходящей фигуры
		const unsigned __int8 d_m,/// тип хода
		unsigned __int8 & count,/// номер хода в списке
		const unsigned __int8 & from,/// откуда ходим
		const unsigned __int8 to,/// куда ходим
		const unsigned __int8 capture/// имя взятой фигуры
	);

	///---------------------------------------------------------------------------
	/// контролируем выход за пределы доски, за пределы списка а также пустые взятия  
	/// все это для белых фигур генератора взятий
	inline void KONTROL_captures_W
	(
		const struct Position & position, /// представление доски    
		const unsigned __int8 & from,/// откуда ходит фигура
		const unsigned __int8 & to,/// куда ходит фигура
		const unsigned __int8 & p,/// номер хода в списке
		const unsigned __int8 name_figure/// имя ходящей фигуры
	);

	///---------------------------------------------------------------------------
	/// контролируем выход за пределы доски, за пределы списка а также пустые взятия  
	/// все это для черных фигур генератора взятий
	inline void KONTROL_captures_B
	(
		const struct Position & position, /// представление доски    
		const unsigned __int8 & from,/// откуда ходит фигура
		const unsigned __int8 & to,/// куда ходит фигура
		const unsigned __int8 & p,/// номер хода в списке
		const unsigned __int8 name_figure/// имя ходящей фигуры
	);

	///---------------------------------------------------------------------------
	/// контролируем выход за пределы доски, за пределы списка 
	/// для генератора ходов 
	inline void KONTROL_move
	(
		const unsigned __int8 & from,// откуда ходит фигура
		const unsigned __int8 & to,// куда ходит фигура
		const unsigned __int8 & p// номер хода в списке
	);


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

	///---------------------------------------------------------------------------
	/// ищем первый установленный бит(т.е. бежим справа)
	__inline __int32 bit_scan_forward_win32
	(
		const unsigned __int64 analyzed_number/// число в котором ищем взведенный бит
	);

	///---------------------------------------------------------------------------
	/// ищем последний установленный бит(т.е. бежим слева)
	__inline __int32 bit_scan_reverse_win32
	(
		const unsigned __int64 analyzed_number/// число в котором ищем взведенный бит
	);
};