
// constants

#define PST(col,pc,sq,ph) (Pst[col][pc-1][sq][ph])
#define PST_OP(col,pc,sq) (Pst[col][pc-1][sq][OPENING])
#define PST_EG(col,pc,sq) (Pst[col][pc-1][sq][ENDGAME])
int Pst[2][6][64][2]; // [colour][piece][square][phase]
int EgKingCentralization[8][8]; // [real][central_file]

const int PawnRank[8] = { 0, 0, 0,10,30,60,100,100};
const int PawnFile[8] = {-3,-1,0,1,1,0,-1,-3};
const int KnightLine[8] = {-4,-2,0,1,1,0,-2,-4};
const int KnightRank[8] = {-2,-1,0,1,2,3,2,1};
const int BishopLine[8] = {-3,-1,0,1,1,0,-1,-3};
const int RookFile[8] = {-2,-1,0,1,1,0,-1,-2};
const int QueenLine[8] = {-3,-1,0,1,1,0,-1,-3};
const int KingLine[8] = {-3,-1,0,1,1,0,-1,-3};
const int KingFile[8] = {3,4,2,0,0,2,4,3};
const int KingRank[4] = {0,-1,-3,-5};
const int KnightTrapped = 100;
const int KnightOutpostFile[4] = {0,0,1,2};
const int KnightOutpostRank[8] = {0,0,0,1,5,3,0,-1};
 
class Personality {
public:
	int index,
		cross_now,
		rand_prob,
		mutated_gene,
		one_sign_prob,
		averaging_prob;	
	float interval_step;
	static const int mh_size = 8,
		max_groups = 128;
	int cross_table[max_groups];
	sint16 m_hist[2][mh_size];
	float crossing;
	uint8 m_ind[2];
	bool visible;
	FILE *output;
	char origin;
	int EG_DOUBLED_PAWN_PENALTY,
		EG_ISOLATED_PAWN_PENALTY,
		EG_ISOLATED_DOUBLED_PAWN_PENALTY,
		OP_ISOLATED_PAWN_PENALTY,
		EG_WEAK_ISOLATED_PAWN_PENALTY,
		OP_WEAK_ISOLATED_PAWN_PENALTY,
		EG_UNPROTECTED_PAWN_PENALTY,
		EG_BACKWARD_PAWN_PENALTY,
		OP_BACKWARD_PAWN_PENALTY,
		EG_WEAK_BACKWARD_PAWN_PENALTY,
		OP_WEAK_BACKWARD_PAWN_PENALTY,
		OP_PASSED_PAWN[8],
		EG_PASSED_PAWN[8],
		EG_UNSTOPPABLE_PASSED_PAWN,
		EG_PASSED_PAWN_WO_OUR_BLOCKER[8], // WO - without
		EG_PASSED_PAWN_WO_OPP_BLOCKER[8],
		EG_PASSED_PAWN_WO_MOB_BLOCKER[8],		
		OP_PASSED_CHAIN[8],
		EG_PASSED_CHAIN[8],
		PASSED_PAWN_CANT_MOVE_PENALTY[8],

		EG_PASSED_PAWN_DEFENDER[8],
		EG_PASSED_PAWN_ATTACKER[8],
		OP_DEFENDED_PASSED_PAWN[8],
		EG_DEFENDED_PASSED_PAWN[8],
		OP_CANDIDATE_PASSED_PAWN[8],
		EG_CANDIDATE_PASSED_PAWN[8],

		INNER_SIDE_SHELTER[4],
		CENTRAL_SHELTER[4],
		OUTER_SIDE_SHELTER[4],		
		STORM_SHELTER_PENALTY_1,
		STORM_CHAIN,
		INNER_SIDE_STORM[5],
		CENTRAL_STORM[5],
		OUTER_SIDE_STORM[5],
		SECOND_INNER_SIDE_SHELTER[4],
		SECOND_CENTRAL_SHELTER[4],
		SECOND_OUTER_SIDE_SHELTER[4],

		KNIGHT_ATT_WEIGHT_GS, // good shelter
		KNIGHT_ATT_WEIGHT_BS, // bad shelter
		BISHOP_ATT_WEIGHT_GS,
		BISHOP_ATT_WEIGHT_BS,
		BISHOP_ATT_WEAK_SQUARES,
		ROOK_ATT_WEIGHT_GS,
		ROOK_ATT_WEIGHT_BS,
		QUEEN_ATT_WEIGHT_GS,
		QUEEN_ATT_WEIGHT_BS,
		PIECE_ATT_WEIGHT[16],
		SAFETY_RATIO,
		MAX_SHELTER_VALUE,
		MIN_SHELTER_VALUE,
		NON_PAWN_DEFENDER_VALUE[8],

		OP_KNIGHT_MOB_1[9],
		EG_KNIGHT_MOB_1[9],
		OP_BISHOP_MOB_1[14],
		EG_BISHOP_MOB_1[14],
		OP_ROOK_MOB_1[15],
		EG_ROOK_MOB_1[15],
		OP_QUEEN_MOB_1[8],
		OP_QUEEN_MOB_2[15],
		EG_QUEEN_MOB_2[15],
		OP_ENEMY_SIDE_MOB,
		EG_ENEMY_SIDE_MOB,			

		OP_ROOK_ON_7TH,
		EG_ROOK_ON_7TH,
		OP_QUEEN_ON_7TH,
		EG_QUEEN_ON_7TH,

		OP_ROOK_HALF_OPEN_FILE,
		EG_ROOK_HALF_OPEN_FILE,
		OP_ROOK_OPEN_FILE,
		EG_ROOK_OPEN_FILE,
		OP_ROOK_FILE_ATT_KING_1,
		OP_ROOK_FILE_ATT_KING_2,
		OP_ROOK_ATT_WEAK_PAWN,
		OP_PAWNS_BEHIND_ROOK_PENALTY,
		TRAPPED_PENALTY_1,
		TRAPPED_PENALTY_2,
		BLOCKED_PENALTY,	
		KNIGHT_OUTPOST_OPENING[2][64],
						
		CONNECTED_ROOKS,				
		EG_KING_ZONE_PENALTY,		
		ATTACKED_PIECE_BONUS,
		ATTACKED_PAWN_BONUS,
		EG_SNEAKER,
		ATTACKED_WEAK_PAWN,

		PINNED_KING,
		UNDEFENDED_PINNED_KING,
		PINNED_QUEEN,
		UNDEFENDED_PINNED_QUEEN,
		X_RAY_KING,
		X_RAY_QUEEN,
		OP_DOUBLE_STORM_BONUS,
		OP_SINGLE_STORM_BONUS,
		OP_BLOCKED_STORM_PENALTY,
		
		// init
		PawnOpening[64], 	  
		PawnEndgame[64], 	  
		KnightOpening[64],	
		KnightEndgame[64],
		KnightOutpostOpening[64],
		BishopOpening[64],
		BishopEndgame[64],
		RookOpening[64],
		RookEndgame[64],
		QueenOpening[64],
		QueenEndgame[64],
		KingOpening[64],
		KingEndgame[64];	

	// functions
	void Reset() {
		index = 0;
		rand_prob = 20;
		crossing = 0.12;
		mutated_gene = 0;
		one_sign_prob = 15;
		averaging_prob = 50;
		interval_step = 0.1;
		visible = true;	
		for(int k = 0; k < mh_size; k++)
			m_hist[0][k] = m_hist[1][k] = -1;
	}
	Personality() {
		Reset();		
	}	
	void Init(char *params);
	void EvInit(double *prm);
	void ParseParams();
	void ParseParams(char *params, double *result, bool print = true);
	void InitTables(double *prm);
	void ParseFile(char *file_name);
	void ParseFile(char *rank, char *file_name);
	void ModifyFile(char *input_name, char *cross_name, char *output_name);
	void InitPST();
};

#ifdef PERSON_VISIBLE
#define PERSON_DEBUG true
#define PersonInitTable(shift, name, param, func, inc) {\
	fprintf(output, "\n%s\n", name);\
	for(int i = 0; i < (sizeof(param)/sizeof(int)); i++) {\
		param[i] = func;\
	}\
	for(int k = 0, s = 0, c = (sizeof(param)/sizeof(int)); k < 1; k++) {\
		for(int i = 0; i < (sizeof(param)/sizeof(int)); i++) {\
			s += param[i];\
		}\
		s /= c;\
		if(!(shift)) {s = 0;}\
		for(int i = 0; i < (sizeof(param)/sizeof(int)); i++) {\
			param[i] -= s;\
			fprintf(output, "%3d ", param[i]);\
			if(i % 8 == 7)	fprintf(output, "\n");\
		}\
	}\
	index += inc;\
}

#define PersonInitSingle(name, param, func) {\
	param = func;\
	fprintf(output, "\n%s\n%d\n", name, param);\
}
#else
#define PERSON_DEBUG false
#define PersonInitTable(shift, name, param, func, inc) {\
	for(int i = 0; i < (sizeof(param)/sizeof(int)); i++) {\
		param[i] = func;\
	}\
	for(int k = 0, s = 0, c = (sizeof(param)/sizeof(int)); k < 1; k++) {\
		for(int i = 0; i < (sizeof(param)/sizeof(int)); i++) {\
			s += param[i];\
		}\
		s /= c;\
		if(!(shift)) {s = 0;}\
		for(int i = 0; i < (sizeof(param)/sizeof(int)); i++) {\
			param[i] -= s;\
		}\
	}\
	index += inc;\
}
#define PersonInitSingle(name, param, func) {\
	param = func;\
}
#endif

void Personality::Init(char *params) {

	const int max_param = 4096;
	double *prm = (double*) malloc((max_param) * sizeof(double));

	output = fopen("PERSON INIT.txt","w+");	
	ParseParams(params, prm);
	
	EvInit(prm);
	
	fclose(output);
	free(prm);
}

void Personality::EvInit(double *prm) {
	InitTables(prm);
	InitPST();
}

#ifndef AUTO
void Personality::ParseParams() {
	output = fopen("PERSON INIT.txt","w+");	
	char EvParameter[] = { 
		"  -8.698 -14.576 -32.500  -7.598 -12.188 -16.642  -2.064  -8.000\
		-20.000  -8.000 -30.000   0.400   1.150 400.000   0.731   0.307\
		0.366   0.574   0.530  -0.300   0.433   0.619   0.291   0.058\
		0.301   0.652  78.363  75.670  19.400  -3.087   0.868   0.246\
		-20.386  -2.333   2.744  31.803   4.867  21.949  14.375  -0.286\
		0.148   0.221   0.243  -0.021  32.247  13.134  15.344  18.039\
		10.000  29.669  45.652  12.123  36.053  34.906   0.550  44.882\
		29.487 142.615  15.879  29.731   0.910 -30.120   1.320   1.496\
		7.372   0.800  18.459   0.432  15.418   0.651  20.500   0.395\
		8.000   0.500  17.000   0.500  15.000   0.350   1.000   1.000\
		-12.138  35.182   7.470  50.021  21.376  21.147  19.385  10.825\
		22.240  10.000   3.000 -15.000 -100.000 -50.000 -50.000   5.969\
		1.264  -1.197  -0.457   9.847   7.020   2.596   3.617   9.119\
		10.688   2.243   5.181   0.136   5.017   7.621   0.610  14.700\
		6.000  12.500   2.800   4.371   1.514   5.365 -10.017  24.704\
		17.581  20.000   3.000 -10.000 -20.000  -7.000 -15.000 -30.000\
		-15.000  25.000  15.000 -15.000"
	};
	Init(EvParameter);
}
#endif

void Personality::ParseParams(char *params, double *result, bool print) {
	
	int i = 0, k = 0, length = strlen(params);
	if(print = false)  fprintf(output, "Parameters:");

	while(i < length) {		
		if(params[i] == '<') {
			if(print)   fprintf(output, "\n\n");
			while(params[i++] != '>');
		}
		if(params[i] == '[') {			
			while(params[i++] != ']');
		}
		if(params[i] == '#')	while(isdigit(params[++i])) ;
		if(params[i] == ',' ||	params[i] == '.' || isspace(params[i])
		|| (i >= 1 && (isdigit(params[i-1]) || params[i-1] == '-' || params[i-1] == '.'))) {
			i++;
			continue;
		}
		if(params[i] == '\0') return;
		if(!isdigit(params[i]) && (params[i] != '-')) {
			ASSERT(false);
			printf("error...\n");
			return;	
		}		
		result[k++] = atof(params + i++);
		if(print)  	fprintf(output, "  %8.1f", result[k-1]);
	}	
}

void Personality::ParseFile(char *file_name) {
	char *rank = new char[1024];
	ParseFile(rank, file_name);
	delete [] rank;
}

void Personality::ParseFile(char *rank, char *file_name) {

	FILE *input_file;		
	int rank_size = sizeof(rank);
	int total_x = 0, length = 0;

	input_file = fopen(file_name, "r");
	if (!input_file) {
		printf("Error. Bison.exe and Parameters.txt should be in one folder\n");	
		return;
	} 
	fseek(input_file, 0, SEEK_SET);
	while(fgets(rank, rank_size, input_file)) {
		total_x++;
		length = MAX(length, strlen(rank));
	}
	char *result = (char*) malloc((length * total_x) * sizeof(char));
	*result = '\0';

	fseek(input_file, 0, SEEK_SET);
	while(fgets(rank, rank_size, input_file)) {
		strcat(result, rank);
	}	
	Init(result);
	free(result);
	fclose(input_file);	
}

void Personality::InitPST() {
	 int colour, square, sq, s;

	 for(colour = 0; colour <= 1; colour++)
	 for(square = 0; square < 64; square++) {	
		 if(colour == WHITE) {s = +1; sq = RANK_MIRROR_INIT(square);} 
		 else				 {s = -1; sq = square;}

		 PST(colour, PAWN, square, OPENING) = s * PawnOpening[sq];
		 PST(colour, PAWN, square, ENDGAME) = s * PawnEndgame[sq];
		 PST(colour, KNIGHT, square, OPENING) = s * KnightOpening[sq];
		 PST(colour, KNIGHT, square, ENDGAME) = s * KnightEndgame[sq];
		 PST(colour, BISHOP, square, OPENING) = s * BishopOpening[sq];
		 PST(colour, BISHOP, square, ENDGAME) = s * BishopEndgame[sq];
		 PST(colour, ROOK, square, OPENING) = s * RookOpening[sq];
		 PST(colour, ROOK, square, ENDGAME) = s * RookEndgame[sq];
		 PST(colour, QUEEN, square, OPENING) = s * QueenOpening[sq];
		 PST(colour, QUEEN, square, ENDGAME) = s * QueenEndgame[sq];
		 PST(colour, KING, square, OPENING) = s * KingOpening[sq];
		 PST(colour, KING, square, ENDGAME) = s * KingEndgame[sq];
		 KNIGHT_OUTPOST_OPENING[colour][square] = s * KnightOutpostOpening[sq];
	 }

	 int real, center, result, delta;
	 for(real = FILE_A; real <= FILE_H; real++)
	 for(center = FILE_A; center <= FILE_H; center++) {
		 result = -PST(WHITE, KING, SQUARE_MAKE(real, RANK_3), ENDGAME);
		 delta = ABS(real - center);
		 delta = MIN(delta, FILE_D-FILE_A);
		 result += PST(WHITE, KING, SQUARE_MAKE(FILE_D-delta, RANK_3), ENDGAME);
		 EgKingCentralization[real][center] = result;
	 }
 }

void Personality::InitTables(double *prm) {

	PersonInitSingle("EG_DOUBLED_PAWN_PENALTY", EG_DOUBLED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("EG_ISOLATED_PAWN_PENALTY", EG_ISOLATED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("EG_ISOLATED_DOUBLED_PAWN_PENALTY", EG_ISOLATED_DOUBLED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("OP_ISOLATED_PAWN_PENALTY", OP_ISOLATED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("EG_WEAK_ISOLATED_PAWN_PENALTY", EG_WEAK_ISOLATED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("OP_WEAK_ISOLATED_PAWN_PENALTY", OP_WEAK_ISOLATED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("EG_UNPROTECTED_PAWN_PENALTY", EG_UNPROTECTED_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("EG_BACKWARD_PAWN_PENALTY", EG_BACKWARD_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("OP_BACKWARD_PAWN_PENALTY", OP_BACKWARD_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("EG_WEAK_BACKWARD_PAWN_PENALTY", EG_WEAK_BACKWARD_PAWN_PENALTY, prm[index++]);
	PersonInitSingle("OP_WEAK_BACKWARD_PAWN_PENALTY", OP_WEAK_BACKWARD_PAWN_PENALTY, prm[index++]);
	PersonInitTable(0,"OP_PASSED_PAWN", OP_PASSED_PAWN, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_PASSED_PAWN", EG_PASSED_PAWN, PawnRank[i]*prm[index], 1);
	PersonInitSingle("EG_UNSTOPPABLE_PASSED_PAWN", EG_UNSTOPPABLE_PASSED_PAWN, prm[index++]);
	PersonInitTable(0,"EG_PASSED_PAWN_WO_OUR_BLOCKER", EG_PASSED_PAWN_WO_OUR_BLOCKER, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_PASSED_PAWN_WO_OPP_BLOCKER", EG_PASSED_PAWN_WO_OPP_BLOCKER, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_PASSED_PAWN_WO_MOB_BLOCKER", EG_PASSED_PAWN_WO_MOB_BLOCKER, PawnRank[i]*prm[index], 1);	
	PersonInitTable(0,"OP_PASSED_CHAIN", OP_PASSED_CHAIN, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_PASSED_CHAIN", EG_PASSED_CHAIN, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"PASSED_PAWN_CANT_MOVE_PENALTY", PASSED_PAWN_CANT_MOVE_PENALTY, PawnRank[i]*prm[index], 1);

	PersonInitTable(0,"EG_PASSED_PAWN_DEFENDER", EG_PASSED_PAWN_DEFENDER, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_PASSED_PAWN_ATTACKER", EG_PASSED_PAWN_ATTACKER, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"OP_DEFENDED_PASSED_PAWN", OP_DEFENDED_PASSED_PAWN, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_DEFENDED_PASSED_PAWN", EG_DEFENDED_PASSED_PAWN, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"OP_CANDIDATE_PASSED_PAWN", OP_CANDIDATE_PASSED_PAWN, PawnRank[i]*prm[index], 1);
	PersonInitTable(0,"EG_CANDIDATE_PASSED_PAWN", EG_CANDIDATE_PASSED_PAWN, PawnRank[i]*prm[index], 1);

	PersonInitTable(0,"CENTRAL_SHELTER", CENTRAL_SHELTER, prm[index++], 0);
	PersonInitTable(0,"INNER_SIDE_SHELTER", INNER_SIDE_SHELTER, CENTRAL_SHELTER[i]*prm[index], 1);
	PersonInitTable(0,"OUTER_SIDE_SHELTER", OUTER_SIDE_SHELTER, CENTRAL_SHELTER[i]*prm[index], 1);	
	PersonInitSingle("STORM_SHELTER_PENALTY_1", STORM_SHELTER_PENALTY_1, prm[index++]);
	PersonInitSingle("STORM_CHAIN", STORM_CHAIN, prm[index++]);
	PersonInitTable(0,"CENTRAL_STORM", CENTRAL_STORM, prm[index++], 0);
	PersonInitTable(0,"INNER_SIDE_STORM", INNER_SIDE_STORM, MAX(CENTRAL_STORM[i]*prm[index],0), 1);	
	PersonInitTable(0,"OUTER_SIDE_STORM", OUTER_SIDE_STORM, MAX(CENTRAL_STORM[i]*prm[index],0), 1);
	PersonInitTable(0,"SECOND_INNER_SIDE_SHELTER", SECOND_INNER_SIDE_SHELTER, CENTRAL_SHELTER[i]*prm[index], 1);
	PersonInitTable(0,"SECOND_CENTRAL_SHELTER", SECOND_CENTRAL_SHELTER, CENTRAL_SHELTER[i]*prm[index], 1);
	PersonInitTable(0,"SECOND_OUTER_SIDE_SHELTER", SECOND_OUTER_SIDE_SHELTER, CENTRAL_SHELTER[i]*prm[index], 1);

	PersonInitSingle("KNIGHT_ATT_WEIGHT_GS", KNIGHT_ATT_WEIGHT_GS, prm[index++]);
	PersonInitSingle("KNIGHT_ATT_WEIGHT_BS", KNIGHT_ATT_WEIGHT_BS, prm[index++]);
	PersonInitSingle("BISHOP_ATT_WEIGHT_GS", BISHOP_ATT_WEIGHT_GS, prm[index++]);
	PersonInitSingle("BISHOP_ATT_WEIGHT_BS", BISHOP_ATT_WEIGHT_BS, prm[index++]);
	PersonInitSingle("BISHOP_ATT_WEAK_SQUARES", BISHOP_ATT_WEAK_SQUARES, prm[index++]);
	PersonInitSingle("ROOK_ATT_WEIGHT_GS", ROOK_ATT_WEIGHT_GS, prm[index++]);
	PersonInitSingle("ROOK_ATT_WEIGHT_BS", ROOK_ATT_WEIGHT_BS, prm[index++]);
	PersonInitSingle("QUEEN_ATT_WEIGHT_GS", QUEEN_ATT_WEIGHT_GS, prm[index++]);
	PersonInitSingle("QUEEN_ATT_WEIGHT_BS", QUEEN_ATT_WEIGHT_BS, prm[index++]);
	PersonInitTable(0,"PIECE_ATT_WEIGHT", PIECE_ATT_WEIGHT, i<=1 ? 0 : prm[index]*(pow(i-2, prm[index+1])) + prm[index+2], 3);
	PersonInitSingle("SAFETY_RATIO", SAFETY_RATIO, MAX(prm[index], 1)		;index++);
	PersonInitSingle("MAX_SHELTER_VALUE", MAX_SHELTER_VALUE, MAX(prm[index], 1)		;index++);
	PersonInitSingle("MIN_SHELTER_VALUE", MIN_SHELTER_VALUE, MAX(prm[index], 1)		;index++);
	PersonInitTable(0,"NON_PAWN_DEFENDER_VALUE", NON_PAWN_DEFENDER_VALUE, 30*(prm[index]*(pow(i, prm[index+1])) + prm[index+2]), 3);

	PersonInitSingle("OP_ENEMY_SIDE_MOB", OP_ENEMY_SIDE_MOB, 100.0*prm[index++]);
	PersonInitSingle("EG_ENEMY_SIDE_MOB", EG_ENEMY_SIDE_MOB, 100.0*prm[index++]);

	PersonInitTable(1,"OP_KNIGHT_MOB_1", OP_KNIGHT_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"EG_KNIGHT_MOB_1", EG_KNIGHT_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"OP_BISHOP_MOB_1", OP_BISHOP_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"EG_BISHOP_MOB_1", EG_BISHOP_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"OP_ROOK_MOB_1", OP_ROOK_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"EG_ROOK_MOB_1", EG_ROOK_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"OP_QUEEN_MOB_1", OP_QUEEN_MOB_1, prm[index]*(pow(i, prm[index+1])), 2);
	PersonInitTable(1,"OP_QUEEN_MOB_2", OP_QUEEN_MOB_2, prm[index]*i, 1);
	PersonInitTable(1,"EG_QUEEN_MOB_2", EG_QUEEN_MOB_2, prm[index]*i, 1);
	
	PersonInitSingle("OP_ROOK_ON_7TH", OP_ROOK_ON_7TH, prm[index++]);
	PersonInitSingle("EG_ROOK_ON_7TH", EG_ROOK_ON_7TH, prm[index++]);
	PersonInitSingle("OP_QUEEN_ON_7TH", OP_QUEEN_ON_7TH, prm[index++]);
	PersonInitSingle("EG_QUEEN_ON_7TH", EG_QUEEN_ON_7TH, prm[index++]);

	PersonInitSingle("OP_ROOK_HALF_OPEN_FILE", OP_ROOK_HALF_OPEN_FILE, prm[index++]);
	PersonInitSingle("EG_ROOK_HALF_OPEN_FILE", EG_ROOK_HALF_OPEN_FILE, prm[index++]);
	PersonInitSingle("OP_ROOK_OPEN_FILE", OP_ROOK_OPEN_FILE, prm[index++]);
	PersonInitSingle("EG_ROOK_OPEN_FILE", EG_ROOK_OPEN_FILE, prm[index++]);
	PersonInitSingle("OP_ROOK_FILE_ATT_KING_1", OP_ROOK_FILE_ATT_KING_1, prm[index++]);
	PersonInitSingle("OP_ROOK_FILE_ATT_KING_2", OP_ROOK_FILE_ATT_KING_2, prm[index++]);
	PersonInitSingle("OP_ROOK_ATT_WEAK_PAWN", OP_ROOK_ATT_WEAK_PAWN, prm[index++]);
	PersonInitSingle("OP_PAWNS_BEHIND_ROOK_PENALTY", OP_PAWNS_BEHIND_ROOK_PENALTY, prm[index++]);
	PersonInitSingle("TRAPPED_PENALTY_1", TRAPPED_PENALTY_1, prm[index++]);
	PersonInitSingle("TRAPPED_PENALTY_2", TRAPPED_PENALTY_2, prm[index++]);
	PersonInitSingle("BLOCKED_PENALTY", BLOCKED_PENALTY, prm[index++]);

	PersonInitTable(0,"PawnOpening", PawnOpening, PawnFile[File(i)]*prm[index] + PawnRank[Rank(RANK_MIRROR_INIT(i))]*prm[index+1], 2);
	PersonInitTable(0,"PawnEndgame", PawnEndgame, PawnFile[File(i)]*prm[index] + PawnRank[Rank(RANK_MIRROR_INIT(i))]*prm[index+1], 2);
	PersonInitTable(1,"KnightOpening", KnightOpening, KnightLine[File(i)]*prm[index] +
                                     KnightLine[Rank(RANK_MIRROR_INIT(i))]*prm[index] +
                                     KnightRank[Rank(RANK_MIRROR_INIT(i))]*prm[index+1]
									 ;if(RANK_MIRROR_INIT(i) == a8)		KnightOpening[i] -= KnightTrapped;
									 ;if(RANK_MIRROR_INIT(i) == h8)		KnightOpening[i] -= KnightTrapped; , 2);
    PersonInitTable(1,"KnightEndgame", KnightEndgame, KnightLine[File(i)]*prm[index] + KnightLine[Rank(RANK_MIRROR_INIT(i))]*prm[index], 1);
	PersonInitTable(1,"BishopOpening", BishopOpening, BishopLine[File(i)]*prm[index] + BishopLine[Rank(RANK_MIRROR_INIT(i))]*prm[index]
									 ;if(Rank(RANK_MIRROR_INIT(i)) == 0)		BishopOpening[i] -= prm[index+1];
									 ;if(Rank(i) == 7 - File(i))				BishopOpening[i] += prm[index+2];
									 ;if(Rank(i) == File(i))					BishopOpening[i] += prm[index+2]; , 3);
    PersonInitTable(1,"BishopEndgame", BishopEndgame, BishopLine[File(i)]*prm[index] + BishopLine[Rank(RANK_MIRROR_INIT(i))]*prm[index], 1);
	PersonInitTable(1,"RookOpening", RookOpening, RookFile[File(i)]*prm[index] - PawnRank[Rank(RANK_MIRROR_INIT(i))]*prm[index+1], 2);
	PersonInitTable(1,"RookEndgame", RookEndgame, 0, 0);
	PersonInitTable(1,"QueenOpening", QueenOpening, QueenLine[File(i)]*prm[index] + QueenLine[Rank(RANK_MIRROR_INIT(i))]*prm[index]
									 ;if(Rank(RANK_MIRROR_INIT(i)) == 0)		QueenOpening[i] -= prm[index+1]; , 2);
    PersonInitTable(1,"QueenEndgame", QueenEndgame, QueenLine[File(i)]*prm[index] + QueenLine[Rank(RANK_MIRROR_INIT(i))]*prm[index], 1);
	PersonInitTable(1,"KingOpening", KingOpening, KingFile[File(i)]*prm[index] + KingRank[Rank(RANK_MIRROR_DOWN(i))]*prm[index+1], 2);
	PersonInitTable(1,"KingEndgame",KingEndgame,(KingLine[File(i)]+KingLine[Rank(i)])*prm[index]-KingRank[Rank(RANK_MIRROR_DOWN(i))]*prm[index+1],2);
	PersonInitTable(0,"KnightOutpostOpening", KnightOutpostOpening, KnightOutpostFile[File(FILE_MIRROR_LEFT(i))]*prm[index] +
									 KnightOutpostRank[Rank(RANK_MIRROR_INIT(i))]*prm[index+1], 2);
	// new block	
	PersonInitSingle("CONNECTED_ROOKS", CONNECTED_ROOKS, prm[index++]);		
	PersonInitSingle("EG_KING_ZONE_PENALTY", EG_KING_ZONE_PENALTY, prm[index++]);	
	PersonInitSingle("ATTACKED_PIECE_BONUS", ATTACKED_PIECE_BONUS, prm[index++]);
	PersonInitSingle("ATTACKED_PAWN_BONUS", ATTACKED_PAWN_BONUS, prm[index++]);	
	PersonInitSingle("EG_SNEAKER", EG_SNEAKER, prm[index++]);
	PersonInitSingle("ATTACKED_WEAK_PAWN", ATTACKED_WEAK_PAWN, prm[index++]);

	PersonInitSingle("PINNED_KING", PINNED_KING, prm[index++]);
	PersonInitSingle("UNDEFENDED_PINNED_KING", UNDEFENDED_PINNED_KING, prm[index++]);
	PersonInitSingle("PINNED_QUEEN", PINNED_QUEEN, prm[index++]);
	PersonInitSingle("UNDEFENDED_PINNED_QUEEN", UNDEFENDED_PINNED_QUEEN, prm[index++]);
	PersonInitSingle("X_RAY_KING", X_RAY_KING, prm[index++]);
	PersonInitSingle("X_RAY_QUEEN", X_RAY_QUEEN, prm[index++]);
	PersonInitSingle("OP_DOUBLE_STORM_BONUS", OP_DOUBLE_STORM_BONUS, prm[index++]);
	PersonInitSingle("OP_SINGLE_STORM_BONUS", OP_SINGLE_STORM_BONUS, prm[index++]);
	PersonInitSingle("OP_BLOCKED_STORM_PENALTY", OP_BLOCKED_STORM_PENALTY, prm[index++]);
							
	if(PERSON_DEBUG)	fprintf(output, "index = %d", index);
	index = 0;
}