Older Version Newer Version

Pawel_Koziol Pawel_Koziol Dec 30, 2014

**[[Home]] * [[Engines]] * [[CPW-Engine]] * eval_init**

Initialization of the evaluation function. This is used once when the program is started and the values are not changed afterwards. Program supports also reading most of the values from a file. Later version might read piece/square tables in the same way, but that is not strictly necessary.

=Code= 
[[code format="cpp"]]
#include "stdafx.h"
#include "0x88_math.h"


s_eval_data e;

// tables used for translating piece/square tables to internal 0x88 representation

int index_white[64] = {
	A8, B8, C8, D8, E8, F8, G8, H8,
	A7, B7, C7, D7, E7, F7, G7, H7,
	A6, B6, C6, D6, E6, F6, G6, H6,
	A5, B5, C5, D5, E5, F5, G5, H5,
	A4, B4, C4, D4, E4, F4, G4, H4,
	A3, B3, C3, D3, E3, F3, G3, H3,
	A2, B2, C2, D2, E2, F2, G2, H2,
	A1, B1, C1, D1, E1, F1, G1, H1
};

int index_black[64] = {
	A1, B1, C1, D1, E1, F1, G1, H1,
	A2, B2, C2, D2, E2, F2, G2, H2,
	A3, B3, C3, D3, E3, F3, G3, H3,
	A4, B4, C4, D4, E4, F4, G4, H4,
	A5, B5, C5, D5, E5, F5, G5, H5,
	A6, B6, C6, D6, E6, F6, G6, H6,
	A7, B7, C7, D7, E7, F7, G7, H7,
	A8, B8, C8, D8, E8, F8, G8, H8
};

int dist_bonus[64][64];

/*****************************************************************
*                           PAWN PCSQ                            *
*                                                                *
*  Unlike TSCP, CPW generally doesn't want to advance its pawns  *
*  just for the fun of it. It takes into account the following:  *
*                                                                *
*  - file-dependent component, encouraging program to capture    *
*    towards the center                                          *
*  - small bonus for staying on the 2nd rank                     *
*  - small bonus for standing on a3/h3                           *
*  - penalty for d/e pawns on their initial squares              *
*  - bonus for occupying the center                              *
*****************************************************************/

int pawn_pcsq_mg[64] = {
	 0,   0,   0,   0,   0,   0,   0,   0,
	-6,  -4,   1,   1,   1,   1,  -4,  -6,
	-6,  -4,   1,   2,   2,   1,  -4,  -6,
	-6,  -4,   2,   8,   8,   2,  -4,  -6,
	-6,  -4,   5,  10,  10,   5,  -4,  -6,
	-4,  -4,   1,   5,   5,   1,  -4,  -4,
	-6,  -4,   1, -24,  -24,  1,  -4,  -6,
	 0,   0,   0,   0,   0,   0,   0,   0
};

int pawn_pcsq_eg[64] = {
	 0,   0,   0,   0,   0,   0,   0,   0,
	-6,  -4,   1,   1,   1,   1,  -4,  -6,
	-6,  -4,   1,   2,   2,   1,  -4,  -6,
	-6,  -4,   2,   8,   8,   2,  -4,  -6,
	-6,  -4,   5,  10,  10,   5,  -4,  -6,
	-4,  -4,   1,   5,   5,   1,  -4,  -4,
	-6,  -4,   1, -24,  -24,  1,  -4,  -6,
	 0,   0,   0,   0,   0,   0,   0,   0
};

/****************************************************************
*    KNIGHT PCSQ                                                *
*                                                               *
*   - centralization bonus                                      *
*   - penalty for not being developed                           *
****************************************************************/

int knight_pcsq_mg[64] = {
	-8,  -8,  -8,  -8,  -8,  -8,  -8,  -8,
	-8,   0,   0,   0,   0,   0,   0,  -8,
	-8,   0,   4,   4,   4,   4,   0,  -8,
	-8,   0,   4,   8,   8,   4,   0,  -8,
	-8,   0,   4,   8,   8,   4,   0,  -8,
	-8,   0,   4,   4,   4,   4,   0,  -8,
	-8,   0,   1,   2,   2,   1,   0,  -8,
	-8, -12,  -8,  -8,  -8,  -8, -12,  -8
};

int knight_pcsq_eg[64] = {
	-8,  -8,  -8,  -8,  -8,  -8,  -8,  -8,
	-8,   0,   0,   0,   0,   0,   0,  -8,
	-8,   0,   4,   4,   4,   4,   0,  -8,
	-8,   0,   4,   8,   8,   4,   0,  -8,
	-8,   0,   4,   8,   8,   4,   0,  -8,
	-8,   0,   4,   4,   4,   4,   0,  -8,
	-8,   0,   1,   2,   2,   1,   0,  -8,
	-8, -12,  -8,  -8,  -8,  -8, -12,  -8
};


/****************************************************************
*                BISHOP PCSQ                                    *
*                                                               *
*   - centralization bonus, smaller than for knight             *
*   - penalty for not being developed                           *
*   - good squares on the own half of the board                 *
****************************************************************/

int bishop_pcsq_mg[64] = {
	-4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,
	-4,   0,   0,   0,   0,   0,   0,  -4,
	-4,   0,   2,   4,   4,   2,   0,  -4,
	-4,   0,   4,   6,   6,   4,   0,  -4,
	-4,   0,   4,   6,   6,   4,   0,  -4,
	-4,   1,   2,   4,   4,   2,   1,  -4,
	-4,   2,   1,   1,   1,   1,   2,  -4,
	-4,  -4, -12,  -4,  -4, -12,  -4,  -4
};

int bishop_pcsq_eg[64] = {
	-4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,
	-4,   0,   0,   0,   0,   0,   0,  -4,
	-4,   0,   2,   4,   4,   2,   0,  -4,
	-4,   0,   4,   6,   6,   4,   0,  -4,
	-4,   0,   4,   6,   6,   4,   0,  -4,
	-4,   1,   2,   4,   4,   2,   1,  -4,
	-4,   2,   1,   1,   1,   1,   2,  -4,
	-4,  -4, -12,  -4,  -4, -12,  -4,  -4
};

/****************************************************************
*                        ROOK PCSQ                              *
*                                                               *
*    - bonus for 7th and 8th ranks                              *
*    - penalty for a/h columns                                  *
*    - small centralization bonus                               *
*****************************************************************/

int rook_pcsq_mg[64] = {
	 5,   5,   5,   5,   5,   5,   5,   5,
	20,  20,  20,  20,  20,  20,  20,  20,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	 0,   0,   0,   2,   2,   0,   0,   0
};

int rook_pcsq_eg[64] = {
	 5,   5,   5,   5,   5,   5,   5,   5,
	20,  20,  20,  20,  20,  20,  20,  20,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	-5,   0,   0,   0,   0,   0,   0,  -5,
	 0,   0,   0,   2,   2,   0,   0,   0
};

/***************************************************************************
*                     QUEEN PCSQ                                           *
*                                                                          *
* - small bonus for centralization in the endgame                          *
* - penalty for staying on the 1st rank, between rooks in the midgame      *
***************************************************************************/
 
int queen_pcsq_mg[64] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 1, 1, 1, 1, 0, 0,
	0, 0, 1, 2, 2, 1, 0, 0,
	0, 0, 2, 3, 3, 2, 0, 0,
	0, 0, 2, 3, 3, 2, 0, 0,
	0, 0, 1, 2, 2, 1, 0, 0,
	0, 0, 1, 1, 1, 1, 0, 0,
	-5, -5, -5, -5, -5, -5, -5, -5
};

int queen_pcsq_eg[64] = {
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 1, 1, 1, 1, 0, 0,
	0, 0, 1, 2, 2, 1, 0, 0,
	0, 0, 2, 3, 3, 2, 0, 0,
	0, 0, 2, 3, 3, 2, 0, 0,
	0, 0, 1, 2, 2, 1, 0, 0,
	0, 0, 1, 1, 1, 1, 0, 0,
	-5, -5, -5, -5, -5, -5, -5, -5
};

int king_pcsq_mg[64] = {
	-40, -30, -50, -70, -70, -50, -30, -40,
	-30, -20, -40, -60, -60, -40, -20, -30,
	-20, -10, -30, -50, -50, -30, -10, -20,
	-10,   0, -20, -40, -40, -20,   0, -10,
	  0,  10, -10, -30, -30, -10,  10,   0,
	 10,  20,   0, -20, -20,   0,  20,  10,
	 30,  40,  20,   0,   0,  20,  40,  30,
	 40,  50,  30,  10,  10,  30,  50,  40
};

int king_pcsq_eg[64] = {
	-72, -48, -36, -24, -24, -36, -48, -72,
	-48, -24, -12,   0,   0, -12, -24, -48,
	-36, -12,   0,  12,  12,   0, -12, -36,
	-24,   0,  12,  24,  24,  12,   0, -24,
	-24,   0,  12,  24,  24,  12,   0, -24,
	-36, -12,   0,  12,  12,   0, -12, -36,
	-48, -24, -12,   0,   0, -12, -24, -48,
	-72, -48, -36, -24, -24, -36, -48, -72
};

/*****************************************************************
*                     WEAK PAWNS PCSQ                            *
*                                                                *
*  Current version of CPW-engine does not differentiate between  *
*  isolated  and  backward pawns, using one  generic  cathegory  *
*  of  weak pawns. The penalty is bigger in the center, on  the  *
*  assumption  that  weak  central pawns can be  attacked  from  *
*  many  directions. If the penalty seems too low, please  note  *
*  that being on a semi-open file will come into equation, too.  *
*****************************************************************/

int weak_pawn_pcsq[64] = {
	  0,   0,   0,   0,   0,   0,   0,   0,
	-10, -12, -14, -16, -16, -14, -12, -10,
	-10, -12, -14, -16, -16, -14, -12, -10,
	-10, -12, -14, -16, -16, -14, -12, -10,
	-10, -12, -14, -16, -16, -14, -12, -10,
	 -8, -12, -14, -16, -16, -14, -12, -10,
	 -8, -12, -14, -16, -16, -14, -12, -10,
	  0,   0,   0,   0,   0,   0,   0,   0
};

int passed_pawn_pcsq[64] = {
	  0,   0,   0,   0,   0,   0,   0,   0,
	100, 100, 100, 100, 100, 100, 100, 100,
	 80,  80,  80,  80,  80,  80,  80,  80,
	 60,  60,  60,  60,  60,  60,  60,  60,
	 40,  40,  40,  40,  40,  40,  40,  40,
	 20,  20,  20,  20,  20,  20,  20,  20,
	 20,  20,  20,  20,  20,  20,  20,  20,
	  0,   0,   0,   0,   0,   0,   0,   0
};


void setDefaultEval() {

	setBasicValues();
	setSquaresNearKing();
	setPcsq();
	readIniFile();
	correctValues();
}

void setBasicValues() {

	/********************************************************************************
	*  We use material values by IM Larry Kaufman with additional + 10 for a Bishop *
	*  and only +30 for a Bishop pair 	                                            *
	********************************************************************************/

	e.PIECE_VALUE[KING]   = 0;
	e.PIECE_VALUE[QUEEN]  = 975;
	e.PIECE_VALUE[ROOK]   = 500;
	e.PIECE_VALUE[BISHOP] = 335;
	e.PIECE_VALUE[KNIGHT] = 325;
	e.PIECE_VALUE[PAWN]   = 100;

	e.BISHOP_PAIR   = 30;
	e.P_KNIGHT_PAIR = 8;
	e.P_ROOK_PAIR   = 16;

	/*************************************************
	*  Calculate  the  value  of  piece  material    *
	*  at  the  beginning of  the  game,  which  is  *
	*  used for scaling the king tropism evaluation. *
	*  This  way we don't have to update a constant  *
	*  every time we change material values.         *
	*************************************************/

	e.START_MATERIAL = e.PIECE_VALUE[QUEEN]
		+ 2 * e.PIECE_VALUE[ROOK]
		+ 2 * e.PIECE_VALUE[BISHOP]
		+ 2 * e.PIECE_VALUE[KNIGHT];

	/*************************************************
	* Values used for sorting captures are the same  *
	* as normal piece values, except for a king.     *
	*************************************************/

	for (int i = 0; i < 6; ++i) {
		e.SORT_VALUE[i] = e.PIECE_VALUE[i];
	}
	e.SORT_VALUE[KING] = SORT_KING;

	/* trapped and blocked pieces */

	e.P_KING_BLOCKS_ROOK   = 24;
	e.P_BLOCK_CENTRAL_PAWN = 24;
	e.P_BISHOP_TRAPPED_A7  = 150;
	e.P_BISHOP_TRAPPED_A6  = 50;
	e.P_KNIGHT_TRAPPED_A8  = 150;
	e.P_KNIGHT_TRAPPED_A7  = 100;

	/* minor penalties */

	e.P_C3_KNIGHT = 5;
	e.P_NO_FIANCHETTO = 4;

	/* king's defence */
	e.SHIELD_1 = 10;
	e.SHIELD_2 = 5;
	e.P_NO_SHIELD = 10;

	/* minor bonuses */

	e.ROOK_OPEN = 10;
	e.ROOK_HALF = 5;
	e.RETURNING_BISHOP = 20;
	e.FIANCHETTO = 4;
	e.TEMPO = 10;

	e.ENDGAME_MAT = 1300;
}

void setSquaresNearKing() {
	for (int i = 0; i < 128; ++i)
		for (int j = 0; j < 128; ++j)
		{

			e.sqNearK[WHITE][i][j] = 0;
			e.sqNearK[BLACK][i][j] = 0;

			if (IS_SQ(i) &&
				IS_SQ(j)) {

				// squares constituting the ring around both kings

				if (j == i + NORTH || j == i + SOUTH ||
					j == i + EAST || j == i + WEST ||
					j == i + NW || j == i + NE ||
					j == i + SW || j == i + SE) {

					e.sqNearK[WHITE][i][j] = 1;
					e.sqNearK[BLACK][i][j] = 1;
				}

				/* squares in front of the white king ring */

				if (j == i + NORTH + NORTH ||
					j == i + NORTH + NE ||
					j == i + NORTH + NW)
					e.sqNearK[WHITE][i][j] = 1;

				// squares in front og the black king ring

				if (j == i + SOUTH + SOUTH ||
					j == i + SOUTH + SE ||
					j == i + SOUTH + SW)
					e.sqNearK[WHITE][i][j] = 1;
			}

		}
}


void setPcsq() {

	for (int i = 0; i < 64; ++i) {

		e.weak_pawn[WHITE][index_white[i]] = weak_pawn_pcsq[i];
		e.weak_pawn[BLACK][index_black[i]] = weak_pawn_pcsq[i];
		e.passed_pawn[WHITE][index_white[i]] = passed_pawn_pcsq[i];
		e.passed_pawn[BLACK][index_black[i]] = passed_pawn_pcsq[i];

		/* protected passers are considered slightly stronger
		than ordinary passed pawns */

		e.protected_passer[WHITE][index_white[i]] = (passed_pawn_pcsq[i] * 10) / 8;
		e.protected_passer[BLACK][index_black[i]] = (passed_pawn_pcsq[i] * 10) / 8;

		/* now set the piece/square tables for each color and piece type */

		e.mgPst[PAWN][WHITE][index_white[i]] = pawn_pcsq_mg[i];
		e.mgPst[PAWN][BLACK][index_black[i]] = pawn_pcsq_mg[i];
		e.mgPst[KNIGHT][WHITE][index_white[i]] = knight_pcsq_mg[i];
		e.mgPst[KNIGHT][BLACK][index_black[i]] = knight_pcsq_mg[i];
		e.mgPst[BISHOP][WHITE][index_white[i]] = bishop_pcsq_mg[i];
		e.mgPst[BISHOP][BLACK][index_black[i]] = bishop_pcsq_mg[i];
		e.mgPst[ROOK][WHITE][index_white[i]] = rook_pcsq_mg[i];
		e.mgPst[ROOK][BLACK][index_black[i]] = rook_pcsq_mg[i];
		e.mgPst[QUEEN][WHITE][index_white[i]] = queen_pcsq_mg[i];
		e.mgPst[QUEEN][BLACK][index_black[i]] = queen_pcsq_mg[i];
		e.mgPst[KING][WHITE][index_white[i]] = king_pcsq_mg[i];
		e.mgPst[KING][BLACK][index_black[i]] = king_pcsq_mg[i];

		e.egPst[PAWN][WHITE][index_white[i]] = pawn_pcsq_eg[i];
		e.egPst[PAWN][BLACK][index_black[i]] = pawn_pcsq_eg[i];
		e.egPst[KNIGHT][WHITE][index_white[i]] = knight_pcsq_eg[i];
		e.egPst[KNIGHT][BLACK][index_black[i]] = knight_pcsq_eg[i];
		e.egPst[BISHOP][WHITE][index_white[i]] = bishop_pcsq_eg[i];
		e.egPst[BISHOP][BLACK][index_black[i]] = bishop_pcsq_eg[i];
		e.egPst[ROOK][WHITE][index_white[i]] = rook_pcsq_eg[i];
		e.egPst[ROOK][BLACK][index_black[i]] = rook_pcsq_eg[i];
		e.egPst[QUEEN][WHITE][index_white[i]] = queen_pcsq_eg[i];
		e.egPst[QUEEN][BLACK][index_black[i]] = queen_pcsq_eg[i];
		e.egPst[KING][WHITE][index_white[i]] = king_pcsq_eg[i];
		e.egPst[KING][BLACK][index_black[i]] = king_pcsq_eg[i];
	}
}

/* This function is meant to be used in conjunction with the *.ini file.
Its aim is to make sure that all the assumptions made within the program
are met.  */

void correctValues() {
	if (e.PIECE_VALUE[BISHOP] == e.PIECE_VALUE[KNIGHT])
		++e.PIECE_VALUE[BISHOP];
}

void readIniFile() {
	FILE *cpw_init;
	char line[256];

	/* if the cpw.ini file does not exist, then exit */

	if ((cpw_init = fopen("cpw.ini", "r")) == NULL) {
		printf("Cannot open cpw.ini, default settings will be used \n");
		return;
	}

	/* process cpw.ini file line by line */

	while (fgets(line, 250, cpw_init)) {
		if (line[0] == ';') continue; // don't process comment lines
		processIniString(line);
	}
}

void processIniString(char line[250]) {

	/* piece values */
	if (!strncmp(line, "PAWN_VALUE", 10))
		sscanf(line, "PAWN_VALUE %d", &e.PIECE_VALUE[PAWN]);
	else if (!strncmp(line, "KNIGHT_VALUE", 12))
		sscanf(line, "KNIGHT_VALUE %d", &e.PIECE_VALUE[KNIGHT]);
	else if (!strncmp(line, "BISHOP_VALUE", 12))
		sscanf(line, "BISHOP_VALUE %d", &e.PIECE_VALUE[BISHOP]);
	else if (!strncmp(line, "ROOK_VALUE", 10))
		sscanf(line, "ROOK_VALUE %d", &e.PIECE_VALUE[ROOK]);
	else if (!strncmp(line, "QUEEN_VALUE", 11))
		sscanf(line, "QUEEN_VALUE %d", &e.PIECE_VALUE[QUEEN]);

	/* piece pairs */
	else if (!strncmp(line, "BISHOP_PAIR", 11))
		sscanf(line, "BISHOP_PAIR %d", &e.BISHOP_PAIR);
	else if (!strncmp(line, "PENALTY_KNIGHT_PAIR", 19))
		sscanf(line, "PENALTY_KNIGHT_PAIR %d", &e.P_KNIGHT_PAIR);
	else if (!strncmp(line, "PENALTY_ROOK_PAIR", 17))
		sscanf(line, "PENALTY_ROOK_PAIR %d", &e.P_KNIGHT_PAIR);

	/* pawn shield*/
	else if (!strncmp(line, "SHIELD_1", 8))
		sscanf(line, "SHIELD_1 %d", &e.SHIELD_1);
	else if (!strncmp(line, "SHIELD_2", 8))
		sscanf(line, "SHIELD_2 %d", &e.SHIELD_2);
	else if (!strncmp(line, "PENALTY_NO_SHIELD", 17))
		sscanf(line, "PENALTY_NO_SHIELD %d", &e.P_NO_SHIELD);

	/* major penalties */

	else if (!strncmp(line, "PENALTY_BISHOP_TRAPPED_A7", 25))
		sscanf(line, "PENALTY_BISHOP_TRAPPED_A7 %d", &e.P_BISHOP_TRAPPED_A7);
	else if (!strncmp(line, "PENALTY_BISHOP_TRAPPED_A6", 25))
		sscanf(line, "PENALTY_BISHOP_TRAPPED_A6 %d", &e.P_BISHOP_TRAPPED_A6);
	else if (!strncmp(line, "PENALTY_KNIGHT_TRAPPED_A8", 25))
		sscanf(line, "PENALTY_KNIGHT_TRAPPED_A8 %d", &e.P_KNIGHT_TRAPPED_A8);
	else if (!strncmp(line, "PENALTY_KNIGHT_TRAPPED_A7", 25))
		sscanf(line, "PENALTY_KNIGHT_TRAPPED_A7 %d", &e.P_KNIGHT_TRAPPED_A7);
	else if (!strncmp(line, "PENALTY_KING_BLOCKS_ROOK", 24))
		sscanf(line, "PENALTY_KNIGHT_TRAPPED_A7 %d", &e.P_KING_BLOCKS_ROOK);
	else if (!strncmp(line, "PENALTY_BLOCKED_CENTRAL_PAWN", 28))
		sscanf(line, "PENALTY_BLOCKED_CENTRAL_PAWN %d", &e.P_BLOCK_CENTRAL_PAWN);

	/* minor penalties */
	else if (!strncmp(line, "PENALTY_KNIGHT_BLOCKS_C", 23))
		sscanf(line, "PENALTY_KNIGHT_BLOCKS_C %d", &e.P_C3_KNIGHT);
	else if (!strncmp(line, "PENALTY_NO_FIANCHETTO", 21))
		sscanf(line, "PENALTY_NO_FIANCHETTO %d", &e.P_NO_FIANCHETTO);

	/* minor positional bonuses */

	else if (!strncmp(line, "ROOK_OPEN", 9))
		sscanf(line, "ROOK_OPEN %d", &e.ROOK_OPEN);
	else if (!strncmp(line, "ROOK_HALF_OPEN", 14))
		sscanf(line, "ROOK_HALF_OPEN %d", &e.ROOK_HALF);
	else if (!strncmp(line, "FIANCHETTO", 10))
		sscanf(line, "FIANCHETTO %d", &e.FIANCHETTO);
	else if (!strncmp(line, "RETURNING_BISHOP", 16))
		sscanf(line, "RETURNING_BISHOP %d", &e.RETURNING_BISHOP);
	else if (!strncmp(line, "TEMPO", 5))
		sscanf(line, "TEMPO %d", &e.TEMPO);

	/* variables deciding about inner workings of evaluation function */

	else if (!strncmp(line, "ENDGAME_MATERIAL", 16))
		sscanf(line, "ENDGAME_MATERIAL %d", &e.ENDGAME_MAT);
}
[[code]]
**[[CPW-Engine|Up one Level]]**