#ifndef EVALUATE_H
#define EVALUATE_H

#include "defs.h"
#include <stdlib.h>
#include <stdio.h>

#define ROPEN 25
#define RSEMI 15
#define ROOKINACTIVE 15
#define QOPEN 7
#define QSEMI  3
#define BMOB 3
#define QMOB 1

// points (on a non-linear scale), not cp
#define TRAPPEDR 7
#define TRAPPEDB 10  
#define TRAPPEDN 10
#define OUTPOST 25
#define MARAUDER 40

#define ISOLATED 10
#define WEAK 8
#define WEAKATTACKED 4
#define DOUBLED 10

#define WINNER 50
#define PASSED 10
#define NOTALONE 4
#define CONNECTED 2
#define STOPPED 7
#define ESCORT 6
#define ROOKSUPPORT 7
#define CANDIDATE 3
#define QUEENED 400

#define STM_BONUS 5
#define GRAINS 4

#define EHASH

/* defects used to index KS scale  4 points ea, basically */
#define SHELTER0 3
#define SHELTER1 5
#define SHELTER2 7
#define SHELTER3 9
#define STORM1 3
#define STORM2 6
#define KINGOUT 4
#define KINGOFF 1
#define OFILEOPEN 4

#define ATT_BISHOP 3
#define ATT_ROOK 5
#define ATT_QUEEN 10
#define ATT_KNIGHT 3
#define ATT_PAWN  2
#define BACKATTACK 4
/*
	defect
	2	-647
	3	-671
	4	-238
	4 ...
	attacks/2			-490
	drop shelters by 1	-260
	+1					-268
	storm 2 & 4			-227
	location			-310
	coordination		-267
	Qx2					-337
	boostc				-227
*/

#define DEFECTK 4

/* coordination boost for attack on same square */
#define BOOSTC(v) (((v)>ATT_ROOK)*((v)-ATT_ROOK))

/*
 * uncoordinated attacks/tropism curve sometimes, attacks are VERY
 * uncoordinated to the extent that they are NOT cumulative But if >=2 pieces
 * are added to a Queen, it is much more likely that the attack has merit EG
 * a near queen attacks several squares around the King, and >=2 OTHER
 * attackers are likely to ADD to or defend her attack
 * 
 * NB. Search **WILL** find all the exceptions to these rules, and Fruit/Rybka/
 * and any good engine will exploit that!!! Assume the combinations below are
 * 'perfectly' uncoordinated - which means: only an overwhelming # of
 * attackers can be said to be coordinated
 * 
 * Q	R	R	N	N	B	B 0	0	0	0
 * 0	0	1		2		8 0	0	0	0
 * 0	1	1		4		16 0	0	0	0
 * 1	0	0		4		16 0	0	0	1
 * 1	0	0		8		32 0	0	1	0
 * 0	0	0		5		20 0	1	1	0
 * 0	0	0		10		40		any 2 rooks
 * over open file 1	0	0	0	0	0	0
 * 		24		Queen 'rook' attack 1	0	1	0
 * 0	0	0		11	12	48 1	0	0	1
 * 1	0	0		14	18	72 1	0	0	1
 * 1	1	0		16	22	88	Q+N+N+B 1	1
 * 0	1	0	1	0		17	24	96
 * Q+R+N+B
 */

#define BOOSTA(v) (((v)>(ATT_QUEEN))*((v)-(ATT_QUEEN))/2)


static const int ntropism[8] = {0, ATT_KNIGHT, ATT_KNIGHT, ATT_KNIGHT-1, 0, 0, 0, 0};
static const int btropism[8] = {0, ATT_BISHOP, ATT_BISHOP/2, ATT_BISHOP/3, 0, 0, 0, 0};
static const int rtropism[8] = {0, ATT_ROOK, ATT_ROOK/2, ATT_ROOK/3, 0, 0, 0, 0};
static const int qtropism[8] = {0, ATT_QUEEN, ATT_QUEEN, ATT_QUEEN/2, 0, 0, 0, 0};

extern int	tropism_q[256];
extern int	tropism_r[256];
extern int	tropism_b[256];
extern int	tropism_n[256];


/* an adjacent piece MUST be lost or protected
 * a second 'helper' must be assumed to be the protector of the first
 * a third piece *may* be uncoordinated, but >=4 can safely assume to be at least somewhat coordinated
 */
//                                0  1  2   3   4   5   6   7   8   9   0   1   2   3   4    5    6    7    8    9    0    1    2    3    4    5    6    7    8    9    0    1

#define BLOCKED(s,c) (board[s] == (BK|(c)) || board[s] == OB)

#define DIAGR(x) (FILE((x))+RANK((x)))
#define DIAGL(x) (FILE((x))+7-RANK((x)))

#define LAPD(c,o,d) (lapd[c][o][d])

#define LAP(c,f) (lap[c][(f)+1])

#define WFILEO(f) (lap[1][(f)+1]==0)
#define BFILEO(f) (lap[0][(f)+1]==7)

#define WFILEC(f) (lap[1][(f)+1]>0)
#define BFILEC(f) (lap[0][(f)+1]<7)

#define BFILESEMI(r,f) ((r)>lap[0][(f)+1] || lap[0][(f)+1]>4)  
#define WFILESEMI(r,f) ((r)<lap[1][(f)+1] || lap[1][(f)+1]<3)  

#define WDIAGRO(d) (lapd[1][1][d]==-1)
#define WDIAGLO(d) (lapd[1][0][d]==-1)

#define BDIAGRO(d) (lapd[0][1][d]==8)
#define BDIAGLO(d) (lapd[0][0][d]==8)

#define WDIAGRSEMI(r,d) ((r) < lapd[1][1][d])
#define WDIAGLSEMI(r,d) ((r) < lapd[1][0][d])

#define BDIAGRSEMI(r,d) ((r) > lapd[0][1][d])
#define BDIAGLSEMI(r,d) ((r) > lapd[0][0][d])


#define PASSEDW(r,f) (LAP(BLACK,(f)-1) >= (r) && LAP(BLACK,(f)) > (r) && LAP(BLACK,(f)+1) >= (r))
#define PASSEDB(r,f) (LAP(WHITE,(f)-1) <= (r) && LAP(WHITE,(f)) < (r) && LAP(WHITE,(f)+1) <= (r))

#define HPASSEDW(r,f) (LAP(BLACK,(f)) > (r) && (LAP(BLACK,(f)-1) >= (r) || LAP(BLACK,(f)+1) >= (r)) && (WFILEC((f)-1) || WFILEC((f)+1)))
#define HPASSEDB(r,f) (LAP(WHITE,(f)) < (r) && (LAP(WHITE,(f)-1) <= (r) || LAP(WHITE,(f)+1) <= (r)) && (BFILEC((f)-1) || BFILEC((f)+1)))

#define WEAKB(r,f)  (LAP(BLACK,(f)-1) > (r) && LAP(BLACK,(f)+1) > (r))
#define WEAKW(r,f)  (LAP(WHITE,(f)-1) < (r) && LAP(WHITE,(f)+1) < (r))

#define SAFE4W(r,f)  (LAP(BLACK,(f)-1) >= (r) && LAP(BLACK,(f)+1) >= (r))
#define SAFE4B(r,f)  (LAP(WHITE,(f)-1) <= (r) && LAP(WHITE,(f)+1) <= (r))


#define ISOLATEDW(f) (WFILEO((f)-1) && WFILEO((f)+1))
#define ISOLATEDB(f) (BFILEO((f)-1) && BFILEO((f)+1))

#define ISCENTER(s) ((s) > H2 && (s) < A7 && FILE(s) > 1 && FILE(s) < 6)

extern int      stm;
extern int      ply;
extern int      evals;
extern int      board[256];
extern int      kingsq[2];
extern int      force[2];
extern int      types[16];
extern int      pieces[2][16];

extern int feature[2][nbFeatures];

extern int      distance[256];
extern /* const */ char pst[16][192];
extern int      rootphase;
extern const int passed_pawn[8];
extern const int blocked_passer[8];
extern const int escorted_passer[8];
extern const int supported_passer[8];
extern const int connected_passer[8];
extern const int f_curve[128];
extern const int p_curve[64];
extern int      castle;
extern const int middle[192];
extern const int outposts[2][192];
extern const int sq_color[192];
extern const int ntrap[192];
extern const int btrap[192];
extern const int corner[2][192];
extern const int border[192];
extern int      bk_defect[192];
extern int      wk_defect[192];

int             w_passer_wins (int p);
int             b_passer_wins (int p);
int             material (int *drawn);

int             vectors[273];

int             attacked_by_white (int sq);
int             attacked_by_black (int sq);

int             knight_fight (int sq);

sEHASHENTRY    *eprobe (void);
void            estore (int s);
int checkboard (void);
#endif
