CPW-Engine eval init

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 =
 * 1) include "stdafx.h"
 * 2) 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                             *
 * - 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                          *
 * - 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                *
 * - 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                              *
 * - 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     *
 * - 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. *
 * 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); } Up one Level