#ifndef A_STRUCTURE_H
#define A_STRUCTURE_H


//--------------------------------------------------------------------------
/* +
 * описываем структуры
 *
 * АВТОР ChessTerminator75
 * ПОСЛЕДНЕЕ ИЗМЕНЕНИЕ 17.05.2008
*/
//--------------------------------------------------------------------------

/*******************************************
коллекция всех структур используемых в программе
********************************************/

// Bitboard

// + 1 - потому что нулевой индекс массива тоже используем 
// в результате получаем: 
//количество индексов = максимально доступный индекс + 1

// максимум на имя фигур 6 + 1
#define MAX_NAME 7

// максимум координаты фигуры 63 + 1
#define MAX_COORDINATE 64

// максимально поддерживаемая длина варианта и она же глубина поиска 100 + 1
#define MAX_DEPTH 101

// максимально поддерживаемое количество ходов из позиции
#define MAX_MOVE 256

// битовая доска
struct T_Bitboard {
//-------------------------------------------------
// доска представлена следующим образом
//A8(56) B8(57) C8(58) D8(59) E8(60) F8(61) G8(62) H8(63)
//A7(48) B7(49) C7(50) D7(51) E7(52) F7(53) G7(54) H7(55)
//A6(40) B6(41) C6(42) D6(43) E6(44) F6(45) G6(46) H6(47)
//A5(32) B5(33) C5(34) D5(35) E5(36) F5(37) G5(38) H5(39)
//A4(24) B4(25) C4(26) D4(27) E4(28) F4(29) G4(30) H4(31)
//A3(16) B3(17) C3(18) D3(19) E3(20) F3(21) G3(22) H3(23)
//A2(8)  B2(9)  C2(10) D2(11) E2(12) F2(13) G2(14) H2(15)
//A1(0)  B1(1)  C1(2)  D1(3)  E1(4)  F1(5)  G1(6)  H1(7)
//

//A1(LSB)- это нулевой бит H8(MSB)-это 63 бит
// т.е. битовая развертка выглядит следующим образом
// H8(63) G8(62) F8(61) . . . . . .C1(2) B1(1) A1(0)
//-------------------------------------------------
// ДОСКА
// в этих 64 битных переменных
// пишется только факт наличия или отсутствия фигуры в каком то поле
// причем неизвестно  что это за фигура известен только цвет по принадлежности
// к той или иной переменной
unsigned __int64  all_piece;// все фигуры
unsigned __int64  all_white_piece;// все белые фигуры
unsigned __int64  all_black_piece;// все черные фигуры

//-------------------------------------------------
// СПИСКИ ФИГУР
/*
 имя фигуры
 0 - нет фигуры
 1 - пешка 
 2 - конь 
 3 - слон
 4 - ладья 
 5 - ферзь 
 6 - король
*/
// битовые списки белых и черных фигур
unsigned __int64 white_piece[MAX_NAME];
unsigned __int64 black_piece[MAX_NAME];

// имя фигуры от координаты 
int white_name_from_coord[MAX_COORDINATE];
int black_name_from_coord[MAX_COORDINATE];

//-------------------------------------------------
// ВСПОМОГАТЕЛЬНАЯ ИНФОРМАЦИЯ
// цвет хода 0 - черные 1 - белые
bool colour_move;

// разрешение взятия на проходе 1/0
bool taking_passage_yes;

// х координата битого поля(конвертируем из буквы)
// так а - 0 , h - 7 таким образом по х отображение прямое
int  taking_passage_x;

// у координата битого поля
// так '1' - 0 , '8' - 7 таким образом отображение тоже прямое только сдвинуто на 1
int  taking_passage_y;

// рокировка белых в длинную сторону   1/0
bool castling_Q;

// рокировка белых в короткую сторону  1/0
bool castling_K;

// рокировка черных в длинную сторону  1/0
bool castling_q;

// рокировка черных в короткую сторону 1/0
bool castling_k;

// 64 битный хеш-ключ позиции
unsigned __int64 hash_key ;

// оценка позиции
int eval ;

};//struct T_Bitboard {

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

int move[MAX_MOVE];
/*
в целом числе массива move мы упаковали следующую информацию (используем 27 бит)
  --3 бит--      --6 бит--   --6 бит--     --6 бит--  --6 бит-- 
 ходящая фигура  куда ходим  откуда ходим  тип хода   взятая фигура


идем справа т.е. с младшего бита
             --6 бит-- 
             взятая фигура

 0 - нет фигуры
 1 - пешка 
 2 - конь 
 3 - слон
 4 - ладья 
 5 - ферзь 
 6 - король

 запись move = тип фигуры
 чтение move & 63 ( 63 это ...000111111)

            --6 бит--
            тип хода
 0 - нет хода
 1 – простой ход
 2 – взятие
 3 – длинная рокировка
 4 – короткая рокировка
 5 – взятие на проходе

 12 - превращение в конь 
 13 - превращение в слон
 14 - превращение в ладья 
 15 - превращение в ферзь 

 22 - взятие с превращением в конь 
 23 - взятие с превращением в слон
 24 - взятие с превращением в ладья 
 25 - взятие с превращением в ферзь 
 
 запись move = move | (тип хода << 6)
 чтение (move>>6) & 63

             --6 бит--
             откуда ходим (0 -63)
 запись move = move | (откуда ходим << 12)
 чтение (move>>12) & 63

             --6 бит--
             куда ходим (0 -63)
 запись move = move | (куда ходим << 18)
 чтение (move>>18) & 63

             --3 бит-- 
             ходящая фигура
 0 - нет фигуры
 1 - пешка 
 2 - конь 
 3 - слон
 4 - ладья 
 5 - ферзь 
 6 - король
 запись move = move | (куда ходим << 24)
 чтение (move>>24) & 7 ( 7 это ...000111)
*/

// оценка используемая для сортировки ходов
int sorting_score[MAX_MOVE];

// конец взятий в списке точнее первое не взятие т.е количество взятий 
// (помним что массив у нас начинается с нуля)
int end_captures;

// конец списка точнее первая пустая позиция т.е. количество ходов
int end_list;

};//struct T_list_surplus_moves {

//---------------------------------------------------------------------------
// эта структура нужна реализатору(делателю) ходов для восстановления позиции после хода
struct T_undo {

// флаг возврата взятия на проходе 1/0
bool return_taking_passage;

// х координата битого поля(конвертируем из буквы) 
// так а - 0 , h - 7 таким образом по х отображение прямое
int  taking_passage_x;

// у координата битого поля
// так '1' - 0 , '8' - 7 таким образом отображение тоже прямое только сдвинуто на 1
int  taking_passage_y;

// флаг рокировки белых в длинную сторону
bool return_castling_Q;

// флаг рокировки белых в короткую сторону
bool return_castling_K;

// флаг рокировки черных в длинную сторону
bool return_castling_q;

// флаг рокировки черных в короткую сторону
bool return_castling_k;

};//struct T_undo {

//---------------------------------------------------------------------------
// линия варианта
struct T_PV {

// описание хода смотреть в структуре T_list_surplus_moves
int move[MAX_DEPTH]; 

// оценка варианта
int score_move;

// длина варианта
int  depth_max;

};//struct T_PV {

//---------------------------------------------------------------------------
// реализуем кэширование лучшего хода в данной позиции
struct T_hash_moves {

// хеш ключ позиции
unsigned __int64 key;

// описание хода смотреть в структуре T_list_surplus_moves
int move;

// оценка хода
int score_move;

// 1 - улучшили альфу(бету), 3 - локальный максимум(минимум), 2 - отсечка по бете(альфе)
int  flag_hash_moves;

// глубина записи данной позиции
int  depth;

// полная глубина поиска
int  depth_max;

// TEST
int hash_alpha;

// TEST
int hash_beta;

// возраст элемента таблицы. нужен что бы перезаписывать элементы от прошлых позиций
int age;

};//struct T_PV {

//---------------------------------------------------------------------------
// реализуем ход - убицу
struct T_killer_moves {

// описание хода смотреть в струкутре T_list_surplus_moves
int move[MAX_DEPTH];

};//struct T_killer_moves {

//---------------------------------------------------------------------------

#endif // !defined D_STRUCTURE_H






