Changes

Jump to: navigation, search

CPW-Engine eval init

18,181 bytes added, 16:16, 18 December 2018
Created page with "'''Home * Engines * CPW-Engine * eval_init''' Initialization of the evaluation function.This is used once when the program is started and the values are..."
'''[[Main Page|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 =
<pre>
#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);
}
</pre>
'''[[CPW-Engine|Up one Level]]'''

Navigation menu