#ifndef EVAL_H_INCLUDED
#define EVAL_H_INCLUDED

#include <stdint.h>
#include <stdio.h>
#include "bitboard.h"
#include "quadboard.h"
#include "state.h"

// 16-bit evaluation data type
typedef int16_t EVAL;
#define EVAL_PRINT PRId16
#define EVAL_SCAN SCNd16
#define EVAL_MAX INT16_MAX
#define EVAL_DRAW 0

// the piece square table data type
typedef struct {
    EVAL w[64];
} EVAL_PST;

// the attack maps data type
typedef struct {
    BITBOARD bb_pt[2][6];
    BITBOARD bb_tot[2];
} EVAL_ATTACK;

// the simple evaluation weights
typedef struct {
    EVAL_PST pst[5];
    EVAL_PST kst[2];
    EVAL phase[6];
} EVAL_SIM_WEIGHTS;

// simple evaluation constants
#define EVAL_SIM_FILE "eval_simple.txt"
#define EVAL_SIM_K_MID 0
#define EVAL_SIM_K_END 1
#define EVAL_SIM_P_START 5
extern EVAL_SIM_WEIGHTS eval_sim_w;

// the tactic evaluation weights
typedef struct {
    EVAL_PST pst[5];
    EVAL_PST kst[2];
    EVAL pp[2][2][8];
    double phase[5];
    double phase_off;
    double atk[2][5][6];
    double atk_off;
    double atk_mul;
    double chk[3][6];
    double chk_off;
    double chk_mul;
    EVAL turn;
} EVAL_TAC_WEIGHTS;

// tactic evaluation constants
#define EVAL_TAC_FILE "eval_tactic.txt"
#define EVAL_TAC_K_MID 0
#define EVAL_TAC_K_END 1
#define EVAL_TAC_C_ZONE 0
#define EVAL_TAC_C_NONE 1
#define EVAL_TAC_C_MANY 2
extern EVAL_TAC_WEIGHTS eval_tac_w;

// initialise the constants
void eval_init();

// mate scores
#define EVAL_MATE (EVAL_MAX - 1000)
#define EVAL_MATE_PLY(ply) ((ply) - EVAL_MAX)

// mate score conversion
EVAL eval_ply_2_abs(EVAL scr, int ply);
EVAL eval_abs_2_ply(EVAL scr, int ply);

// convert the score in a UCI string
void eval_print_uci(char* uci, EVAL score);

// pst input/output in readable form
void eval_pst_print(FILE* fp, EVAL_PST* pst);
void eval_pst_scan(FILE* fp, EVAL_PST* pst);

// compute the pst score
EVAL eval_pst_score(EVAL_PST* pst, BITBOARD bb, PLAYER pl);

// compute the attack maps
void eval_attack_init(EVAL_ATTACK* atk, const QUADBOARD* qb);

// random evaluation
#define EVAL_RAND_MAX 20000
EVAL eval_rand(QUADBOARD* qb, STATE st);

// polish evaluation
EVAL eval_simple(QUADBOARD* qb, STATE st);

// tactic evaluation
//EVAL eval_tactic(QUADBOARD* qb, STATE st);

// evaluation hub
EVAL eval(QUADBOARD* qb, STATE st);

#endif // EVAL_H_INCLUDED
