
/*
  Échiquier pour les échecs classiques, les échecs Fischer et les échecs Capablanca.
*/

#ifndef CHESS_H
#define CHESS_H

#include <stddef.h>

#define BOARD_SIZE 210
#define NIL -1
#define EMPTY_SQUARE '.'
#define UNDEFINED '?'
#define BORDER '#'

#define ALL_MOVES 0
#define CHECK_DETECTION 1
#define CASTLING_CHECK_DETECTION 2

#define CAPTURE 1
#define CASTLING 2

typedef char t_board[BOARD_SIZE];

/*
  Échiquier de 15 sur 14. Idée empruntée à Reinhard Scharnagl.
  http://www.open-aurec.com/wbforum/viewtopic.php?p=23082#p23082
*/

enum chess_variant { cv_undefined, cv_normal, cv_capablanca, cv_fischerandom, cv_caparandom };

struct t_castling
{
  int k_rook_x; /* Colonne de la "tour du roi", de 0 à 9, ou NIL si le roque n'est pas autorisé. */
  int q_rook_x; /* Colonne de la "tour de la dame", idem. */
};

struct t_position_info
{
  int check;
  int k_castling_possible;
  int q_castling_possible;
  int king_square;
};

struct t_position
{
  t_board board;
  char active;
  struct t_castling white, black;
  int passant;
  int halfmove;
  int fullmove;
  int board_10x8;
  int white_king_square;
  int black_king_square;
};

struct t_move
{
  unsigned char from;
  unsigned char to;
  unsigned char capture;
  char promotion;
};

void castling_to_str(const struct t_position position, char* str, const size_t str_size);
void print_position(const struct t_position position);
void prettyprint_position(const struct t_position position);
void erase_position(struct t_position* position);
void load_position(struct t_position* position, char placement[], char active, char castling[], char passant[], char halfmove[], char fullmove[]);
void load_position_from_fen(struct t_position* position, const char fen[]);
void get_fen(const struct t_position position, char* str, const size_t str_size);
struct t_move encode_move(const unsigned char from, const unsigned char to, const unsigned char capture, const char promotion);
void move2str(const struct t_move move, char* str, const size_t str_size);
int generate_moves(const struct t_position position, const int options, struct t_move* moves, size_t array_size);
struct t_position_info get_position_info(struct t_position* position, const int detect_only_check);
int do_move(struct t_move move, struct t_position* position);
int generate_castling(const struct t_position position, const struct t_position_info info, struct t_move* moves, size_t array_size);
int generate_legal_moves(const struct t_position position, const struct t_position_info info, struct t_move* moves, size_t array_size, const int one_move);
struct t_move str2move(const char str[]);
void print_info(const struct t_position_info info);
void castling2str(const struct t_move move, char* str, const size_t str_size, const enum chess_variant variant);

#endif
