#include "sjeng.h"
#include "extvars.h"
#include "protos.h"
#include "squares.h"
static int sbishop[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0,
0,0,-2,8,5,5,5,5,8,-2,0,0,
0,0,-2,3,3,5,5,3,3,-2,0,0,
0,0,-2,2,5,4,4,5,2,-2,0,0,
0,0,-2,2,5,4,4,5,2,-2,0,0,
0,0,-2,3,3,5,5,3,3,-2,0,0,
0,0,-2,8,5,5,5,5,8,-2,0,0,
0,0,-2,-2,-2,-2,-2,-2,-2,-2,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int sknight[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0,
0,0,-10,0,0,3,3,0,0,-10,0,0,
0,0,-10,0,5,5,5,5,0,-10,0,0,
0,0,-10,0,5,10,10,5,0,-10,0,0,
0,0,-10,0,5,10,10,5,0,-10,0,0,
0,0,-10,0,5,5,5,5,0,-10,0,0,
0,0,-10,0,0,3,3,0,0,-10,0,0,
0,0,-20,-10,-10,-10,-10,-10,-10,-20,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int32_t swhite_pawn[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,2,3,10,10,3,2,1,0,0,
0,0,2,4,6,12,12,6,4,2,0,0,
0,0,3,6,9,14,14,9,6,3,0,0,
0,0,4,8,12,16,16,12,8,4,0,0,
0,0,5,10,15,20,20,15,10,5,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int sblack_pawn[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,5,10,15,20,20,15,10,5,0,0,
0,0,4,8,12,16,16,12,8,4,0,0,
0,0,3,6,9,14,14,9,6,3,0,0,
0,0,2,4,6,12,12,6,4,2,0,0,
0,0,1,2,3,10,10,3,2,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int swhite_king[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,2,14,0,0,0,9,14,2,0,0,
0,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0,
0,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0,
0,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0,
0,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0,
0,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0,
0,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0,
0,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int sblack_king[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,-55,-55,-89,-89,-89,-89,-55,-55,0,0,
0,0,-34,-34,-55,-55,-55,-55,-34,-34,0,0,
0,0,-21,-21,-34,-34,-34,-34,-21,-21,0,0,
0,0,-13,-13,-21,-21,-21,-21,-13,-13,0,0,
0,0,-8,-8,-13,-13,-13,-13,-8,-8,0,0,
0,0,-5,-5,-8,-8,-8,-8,-5,-5,0,0,
0,0,-3,-5,-6,-6,-6,-6,-5,-3,0,0,
0,0,2,14,0,0,0,9,14,2,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int send_king[144] = {
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,-5,-3,-1,0,0,-1,-3,-5,0,0,
0,0,-3,10,10,10,10,10,10,-3,0,0,
0,0,-1,10,25,25,25,25,10,-1,0,0,
0,0,0,10,25,30,30,25,10,0,0,0,
0,0,0,10,25,30,30,25,10,0,0,0,
0,0,-1,10,25,25,25,25,10,-1,0,0,
0,0,-3,10,10,10,10,10,10,-3,0,0,
0,0,-5,-3,-1,0,0,-1,-3,-5,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0};
static int srev_rank[9] = {
0,8,7,6,5,4,3,2,1};
const int std_p_tropism[9] =
{ 9999, 15, 10, 7, 2, 0, 0, 0, 9999};
const int std_r_tropism[9] =
{ 9999, 10, 6, 4, 2, 0, 0, 0, 9999};
const int std_n_tropism[9] =
{ 9999, 14, 9, 6, 1, 0, 0, 0, 9999};
const int std_q_tropism[9] =
{ 9999, 16, 12, 7, 2, 0, 0, 0, 9999};
const int std_b_tropism[9] =
{ 9999, 12, 7, 5, 0, 0, 0, 0, 9999};
static int bishop_mobility(int square)
{
register int l;
register int m = 0;
for (l = square-13; board[l] == npiece; l-=13)
m++;
for (l = square-11; board[l] == npiece; l-=11)
m++;
for (l = square+11; board[l] == npiece; l+=11)
m++;
for (l = square+13; board[l] == npiece; l+=13)
m++;
return m;
}
int32_t end_eval (void) {
int i, a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11],
srank, j;
int32_t score = 0;
bool isolated, backwards;
int in_cache;
int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0,
wq = 0, bq = 0, wr = 0, br = 0;
int fwrook, fbrook, rwrook, rbrook;
int wpotential = 0, bpotential = 0, tmp;
in_cache = 0;
checkECache(&score, &in_cache);
if(in_cache)
{
if (white_to_move == 1) return score;
return -score;
}
memset (pawns, 0, sizeof (pawns));
for (i = 0; i < 11; i++) {
white_back_pawn[i] = 7;
black_back_pawn[i] = 2;
}
for (j = 1, a = 1; (a <= piece_count); j++) {
i = pieces[j];
if (!i)
continue;
else
a++;
assert((i > 0) && (i < 145));
pawn_file = file (i)+1;
srank = rank (i);
if (board[i] == wpawn) {
pawns[1][pawn_file]++;
if (srank < white_back_pawn[pawn_file]) {
white_back_pawn[pawn_file] = srank;
}
}
else if (board[i] == bpawn) {
pawns[0][pawn_file]++;
if (srank > black_back_pawn[pawn_file]) {
black_back_pawn[pawn_file] = srank;
}
}
}
for (j = 1, a = 1; (a <= piece_count); j++) {
i = pieces[j];
if (!i)
continue;
else
a++;
pawn_file = file (i)+1;
srank = rank (i);
switch (board[i]) {
case (wpawn):
isolated = FALSE;
backwards = FALSE;
score += 100;
score += swhite_pawn[i];
wp++;
if (white_back_pawn[pawn_file+1] > srank
&& white_back_pawn[pawn_file-1] > srank) {
score -= 8;
backwards = TRUE;
if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) {
score -= 5;
isolated = TRUE;
}
}
if (!pawns[0][pawn_file]) {
if (backwards) score -= 3;
if (isolated) score -= 5;
}
if (pawns[1][pawn_file] > 1)
score -= 3*(pawns[1][pawn_file]-1);
if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] &&
srank >= black_back_pawn[pawn_file+1]) {
score += 30 + 3*swhite_pawn[i];
if (white_to_move)
{
tmp = A8 + file(i) - 1;
if (max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp)))
> (abs(rank(tmp) - rank(i))))
{
wpotential += 800;
}
}
else
{
tmp = A8 + file(i) - 1;
if ((max(abs(file(bking_loc)-file(tmp)), abs(rank(bking_loc)-rank(tmp)))-1)
> (abs(rank(tmp) - rank(i))))
{
wpotential += 800;
}
}
if (file(i) == 1 || file(i) == 8)
score += 12 + 2*swhite_pawn[i];
if (!isolated)
{
score += 12;
if (pawns[1][pawn_file+1])
{
if (!pawns[0][pawn_file+1]
&& white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2])
{
score += 7*rank(i);
if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6)
{
score += 50;
}
}
}
if (pawns[1][pawn_file-1])
{
if (!pawns[0][pawn_file-1]
&& white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2])
{
score += 7*rank(i);
if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6)
{
score += 50;
}
}
}
}
}
if (!pawns[1][pawn_file-1])
score -= 7;
break;
case (bpawn):
isolated = FALSE;
backwards = FALSE;
score -= 100;
score -= sblack_pawn[i];
bp++;
if (black_back_pawn[pawn_file+1] < srank
&& black_back_pawn[pawn_file-1] < srank) {
score += 8;
backwards = TRUE;
if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) {
score += 5;
isolated = TRUE;
}
}
if (!pawns[1][pawn_file]) {
if (backwards) score += 3;
if (isolated) score += 5;
}
if (pawns[0][pawn_file] > 1)
score += 3*(pawns[0][pawn_file]-1);
if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] &&
srank <= white_back_pawn[pawn_file+1]) {
score -= 30 + 3*sblack_pawn[i];
if (!white_to_move)
{
tmp = A1 + file(i) - 1;
if (max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp)))
> (abs(rank(tmp) - (rank(i)))))
{
bpotential -= 800;
}
}
else
{
tmp = A1 + file(i) - 1;
if ((max(abs(file(wking_loc)-file(tmp)), abs(rank(wking_loc)-rank(tmp)))-1)
> abs((rank(tmp) - rank(i))))
{
bpotential -= 800;
}
}
if (file(i) == 1 || file(i) == 8)
score -= 12 + 2*sblack_pawn[i];
if (!isolated)
{
score -= 12;
if (pawns[0][pawn_file+1])
{
if (!pawns[1][pawn_file+1]
&& black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2])
{
score -= 7*(9-rank(i));
if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3)
{
score -= 50;
}
}
}
if (pawns[0][pawn_file-1])
{
if (!pawns[1][pawn_file-1]
&& black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2])
{
score -= 7*(9-rank(i));
if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3)
{
score -= 50;
}
}
}
}
}
if (!pawns[0][pawn_file-1])
score += 7;
break;
case (wrook):
score += 500;
wr++;
if (wr == 1)
{
fwrook = file(i);
rwrook = rank(i);
}
if (srank == 7)
{
score += 12;
if (wr == 2 && 7 == rwrook)
{
score += 10;
}
}
if (!pawns[1][pawn_file]) {
score += 5;
if (wr == 2 && file(i) == fwrook)
{
score += 10;
}
if (!pawns[0][pawn_file]) {
score += 3;
}
}
break;
case (brook):
score -= 500;
br++;
if (br == 1)
{
fbrook = file(i);
rbrook = rank(i);
}
if (srank == 2)
{
score -= 12;
if (br == 2 && 2 == rbrook)
{
score -= 10;
}
}
if (!pawns[0][pawn_file])
{
score -= 5;
if (br == 2 && file(i) == fbrook)
{
score -= 10;
}
if (!pawns[1][pawn_file])
{
score -= 3;
}
}
break;
case (wbishop):
score += 325;
score += sbishop[i];
score += (bishop_mobility(i) << 1) - 15;
wb++;
break;
case (bbishop):
score -= 325;
score -= sbishop[i];
score -= (bishop_mobility(i) << 1) - 15;
bb++;
break;
case (wknight):
score += 310;
score += sknight[i];
wn++;
break;
case (bknight):
score -= 310;
score -= sknight[i];
bn++;
break;
case (wqueen):
score += 900;
wq++;
break;
case (bqueen):
score -= 900;
bq++;
break;
}
}
if (!wr && !wq && !wb && !wn)
{
score += bpotential;
}
if (!br && !bq && !bb && !bn)
{
score += wpotential;
}
if (!wp && !bp)
{
if (!wr && !br && !wq && !bq)
{
if (!bb && !wb)
{
if (wn < 3 && bn < 3)
{
score = 0;
}
}
else if (!wn && !bn)
{
if (abs(wb - bb) < 2)
{
score = 0;
}
}
else if ((wn < 3 && !wb) || (wb == 1 && !wn))
{
if ((bn < 3 && !bb) || (bb == 1 && !bn))
{
score = 0;
}
}
}
else if (!wq && !bq)
{
if (wr == 1 && br == 1)
{
if ((wn + wb) < 2 && (bn + bb) < 2)
{
score = 0;
}
}
else if (wr == 1 && !br)
{
if ((wn + wb == 0) && (((bn + bb) == 1) || ((bn + bb) == 2)))
{
score = 0;
}
}
else if (br == 1 && !wr)
{
if ((bn + bb == 0) && (((wn + wb) == 1) || ((wn + wb) == 2)))
{
score = 0;
}
}
}
}
else
{
if ((wn + wb) != (bn + bb))
{
if ((wq + wr) == (bq + br))
{
if ((wn + wb) > (bn + bb))
{
score += 120;
}
else
{
score -= 120;
}
}
else if (abs((wr + wq) - (br + bq)) == 1)
{
if ((wb + wn) > (bb + bn + 1))
{
score += 120;
}
else if ((bb + bn) > (wb + wn + 1))
{
score -= 120;
}
}
else if (abs((wr + wq) - (br + bq)) == 2)
{
if ((wb + wn) > (bb + bn + 2))
{
score += 120;
}
else if ((bb + bn) > (wb + wn + 2))
{
score -= 120;
}
}
}
else if ((wq + wr) == (bq + br))
{
if (wq && !bq)
{
score += 120;
}
else if (!wq && bq)
{
score -= 120;
}
}
}
score += send_king[wking_loc];
score -= send_king[bking_loc];
storeECache(score);
if (white_to_move == 1) {
return score;
}
else {
return -score;
}
}
void check_phase(void)
{
int num_pieces = 0;
int j, a, i;
for (j = 1, a = 1; (a <= piece_count); j++)
{
i = pieces[j];
if (!i)
continue;
else
a++;
if (board[i] != wpawn && board[i] != bpawn &&
board[i] != npiece && board[i] != frame)
{
num_pieces++;
}
};
if ((num_pieces >= 12)
&& (!white_castled || !black_castled)
&& (board[30] == wking || board[114] == bking))
{
phase = Opening;
}
else if (num_pieces <= 6)
{
phase = Endgame;
}
else
phase = Middlegame;
}
int32_t std_eval (void) {
if (phase == Opening) {
return (opn_eval ());
}
else if (phase == Endgame) {
return (end_eval ());
}
else {
return (mid_eval ());
}
}
int32_t mid_eval (void) {
int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11],
srank, wking_pawn_file, bking_pawn_file, j;
int32_t score = 0;
bool isolated, backwards;
int in_cache;
int wp = 0, bp = 0, wn = 0, bn = 0, wb = 0, bb = 0,
wq = 0, bq = 0, wr = 0, br = 0;
int rbrook, fbrook, rwrook,fwrook;
in_cache = 0;
checkECache(&score, &in_cache);
if(in_cache)
{
if (white_to_move == 1) return score;
return -score;
}
memset (pawns, 0, sizeof (pawns));
for (i = 0; i < 11; i++) {
white_back_pawn[i] = 7;
black_back_pawn[i] = 2;
}
for (j = 1, a = 1; (a <= piece_count); j++) {
i = pieces[j];
if (!i)
continue;
else
a++;
assert((i > 0) && (i < 145));
if (board[i] == wpawn) {
pawn_file = file (i)+1;
srank = rank (i);
pawns[1][pawn_file]++;
if (srank < white_back_pawn[pawn_file]) {
white_back_pawn[pawn_file] = srank;
}
}
else if (board[i] == bpawn) {
pawn_file = file (i)+1;
srank = rank (i);
pawns[0][pawn_file]++;
if (srank > black_back_pawn[pawn_file]) {
black_back_pawn[pawn_file] = srank;
}
}
}
for (j = 1, a = 1; (a <= piece_count); j++) {
i = pieces[j];
if (!i)
continue;
else
a++;
pawn_file = file (i)+1;
srank = rank (i);
switch (board[i]) {
case (wpawn):
isolated = FALSE;
backwards = FALSE;
score += 100;
score += swhite_pawn[i];
wp++;
if (white_back_pawn[pawn_file+1] > srank
&& white_back_pawn[pawn_file-1] > srank) {
score -= 5;
backwards = TRUE;
if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) {
score -= 3;
isolated = TRUE;
}
}
score += std_p_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
if (!pawns[0][pawn_file]) {
if (backwards) score -= 4;
if (isolated) score -= 8;
}
if (pawns[1][pawn_file] > 1)
score -= 2*(pawns[1][pawn_file]-1);
if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] &&
srank >= black_back_pawn[pawn_file+1]) {
score += 20 + 2*swhite_pawn[i];
if (!isolated)
{
score += 10;
if (pawns[1][pawn_file+1])
{
if (!pawns[0][pawn_file+1]
&& white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file+2])
{
score += 7*rank(i);
if (rank(i) == 7 && white_back_pawn[pawn_file+1] >= 6)
{
score += 50;
}
}
}
if (pawns[1][pawn_file-1])
{
if (!pawns[0][pawn_file-1]
&& white_back_pawn[pawn_file+1] >= black_back_pawn[pawn_file-2])
{
score += 7*rank(i);
if (rank(i) == 7 && white_back_pawn[pawn_file-1] >= 6)
{
score += 50;
}
}
}
}
}
if (!pawns[1][pawn_file-1])
score -= 5;
break;
case (bpawn):
isolated = FALSE;
backwards = FALSE;
score -= 100;
score -= sblack_pawn[i];
bp++;
if (black_back_pawn[pawn_file+1] < srank
&& black_back_pawn[pawn_file-1] < srank) {
score += 5;
backwards = TRUE;
if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) {
score += 3;
isolated = TRUE;
}
}
score -= std_p_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
if (!pawns[1][pawn_file]) {
if (backwards) score += 4;
if (isolated) score += 8;
}
if (pawns[0][pawn_file] > 1)
score += 2*(pawns[0][pawn_file]-1);
if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] &&
srank <= white_back_pawn[pawn_file+1]) {
score -= 20 + 2*sblack_pawn[i];
if (!isolated)
{
score -= 10;
if (pawns[0][pawn_file+1])
{
if (!pawns[1][pawn_file+1]
&& black_back_pawn[pawn_file+1] <= white_back_pawn[pawn_file+2])
{
score -= 7*(9-rank(i));
if (rank(i) == 2 && black_back_pawn[pawn_file+1] <= 3)
{
score -= 50;
}
}
}
if (pawns[0][pawn_file-1])
{
if (!pawns[1][pawn_file-1]
&& black_back_pawn[pawn_file-1] <= white_back_pawn[pawn_file-2])
{
score -= 7*(9-rank(i));
if (rank(i) == 2 && black_back_pawn[pawn_file-1] <= 3)
{
score -= 50;
}
}
}
}
}
if (!pawns[0][pawn_file-1])
score += 5;
break;
case (wrook):
score += 500;
wr++;
if (wr == 1)
{
fwrook = file(i);
rwrook = rank(i);
}
score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
if (srank == 7)
{
score += 8;
if (wr == 2 && rwrook == 7)
{
score += 10;
}
}
if (!pawns[1][pawn_file]) {
score += 5;
if (wr == 2 && file(i) == fwrook)
{
score += 12;
}
if (!pawns[0][pawn_file]) {
score += 3;
}
}
break;
case (brook):
score -= 500;
br++;
if (br == 1)
{
fbrook = file(i);
rbrook = rank(i);
}
score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
if (srank == 2)
{
score -= 8;
if (wr == 2 && rbrook == 2)
{
score -= 10;
}
}
if (!pawns[0][pawn_file]) {
score -= 5;
if (br == 2 && file(i) == fbrook)
{
score -= 12;
}
if (!pawns[1][pawn_file]) {
score -= 3;
}
}
break;
case (wbishop):
score += 325;
score += sbishop[i];
wb++;
score += std_r_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
score += bishop_mobility(i);
break;
case (bbishop):
score -= 325;
score -= sbishop[i];
bb++;
score -= std_r_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
score -= bishop_mobility(i);
break;
case (wknight):
score += 310;
score += sknight[i];
wn++;
score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
break;
case (bknight):
score -= 310;
score -= sknight[i];
bn++;
score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
break;
case (wqueen):
score += 900;
wq++;
score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
break;
case (bqueen):
score -= 900;
bq++;
score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
break;
case (wking):
score += swhite_king[i];
if (white_castled == wcq)
score += 15;
else if (white_castled == wck)
score += 25;
else if (moved[30]) {
score -= 10;
if (!pawns[1][pawn_file])
score -= 15;
}
if (file(wking_loc) != 4 && file(wking_loc) != 5)
{
if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file])
score -= 9*(white_back_pawn[pawn_file]-srank-1);
else
score -= 22;
if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1])
score -= 8*(white_back_pawn[pawn_file+1]-srank-1);
else
score -= 16;
if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1])
score -= 8*(white_back_pawn[pawn_file-1]-srank-1);
else
score -= 16;
}
else
{
score -= 10;
}
break;
case (bking):
score -= sblack_king[i];
if (black_castled == bcq)
score -= 15;
else if (black_castled == bck)
score -= 25;
else if (moved[114]) {
score += 10;
if (!pawns[0][pawn_file])
score += 15;
}
if (file(bking_loc) != 4 && file(bking_loc) != 5)
{
if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file])
score += 9*(srev_rank[srank-black_back_pawn[pawn_file]-1]);
else
score += 22;
if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1])
score += 8*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]);
else
score += 16;
if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1])
score += 8*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]);
else
score += 16;
}
else
{
score += 10;
}
break;
}
}
if (!moved[41] && board[53] != npiece)
score -= 5;
if (!moved[42] && board[54] != npiece)
score -= 5;
if (!moved[101] && board[89] != npiece)
score += 5;
if (!moved[102] && board[90] != npiece)
score += 5;
wking_pawn_file = file (wking_loc)+1;
bking_pawn_file = file (bking_loc)+1;
if (abs(wking_pawn_file-bking_pawn_file) > 2) {
score -= 3*(srev_rank[black_back_pawn[wking_pawn_file]]-2);
score -= 3*(srev_rank[black_back_pawn[wking_pawn_file+1]]-2);
score -= 3*(srev_rank[black_back_pawn[wking_pawn_file-1]]-2);
score += 3*(white_back_pawn[bking_pawn_file]-2);
score += 3*(white_back_pawn[bking_pawn_file+1]-2);
score += 3*(white_back_pawn[bking_pawn_file-1]-2);
if (!pawns[0][wking_pawn_file])
score -= 8;
if (!pawns[0][wking_pawn_file+1])
score -= 6;
if (!pawns[0][wking_pawn_file-1])
score -= 6;
if (!pawns[1][bking_pawn_file])
score += 8;
if (!pawns[1][bking_pawn_file+1])
score += 6;
if (!pawns[1][bking_pawn_file-1])
score += 6;
}
if ((wn + wb) != (bn + bb))
{
if ((wq + wr) == (bq + br))
{
if ((wn + wb) > (bn + bb))
{
score += 120;
}
else
{
score -= 120;
}
}
else if (abs((wr + wq) - (br + bq)) == 1)
{
if ((wb + wn) > (bb + bn + 1))
{
score += 120;
}
else if ((bb + bn) > (wb + wn + 1))
{
score -= 120;
}
}
else if (abs((wr + wq) - (br + bq)) == 2)
{
if ((wb + wn) > (bb + bn + 2))
{
score += 120;
}
else if ((bb + bn) > (wb + wn + 2))
{
score -= 120;
}
}
}
else if ((wq + wr) == (bq + br))
{
if (wq && !bq)
{
score += 120;
}
else if (!wq && bq)
{
score -= 120;
}
}
storeECache(score);
if (white_to_move == 1) {
return score;
}
else {
return -score;
}
}
int32_t opn_eval (void) {
int i,a, pawn_file, pawns[2][11], white_back_pawn[11], black_back_pawn[11],
srank, wking_pawn_file, bking_pawn_file, j;
int32_t score = 0;
bool isolated, backwards;
int in_cache;
int fwrook = 0, fbrook = 0;
in_cache = 0;
checkECache(&score, &in_cache);
if(in_cache)
{
if (white_to_move == 1) return score;
return -score;
}
memset (pawns, 0, sizeof (pawns));
for (i = 0; i < 11; i++) {
white_back_pawn[i] = 7;
black_back_pawn[i] = 2;
}
for (j = 1, a = 1; (a <= piece_count); j++) {
i = pieces[j];
if (!i)
continue;
else
a++;
if (board[i] == wpawn) {
pawn_file = file (i)+1;
srank = rank (i);
pawns[1][pawn_file]++;
if (srank < white_back_pawn[pawn_file]) {
white_back_pawn[pawn_file] = srank;
}
}
else if (board[i] == bpawn) {
pawn_file = file (i)+1;
srank = rank (i);
pawns[0][pawn_file]++;
if (srank > black_back_pawn[pawn_file]) {
black_back_pawn[pawn_file] = srank;
}
}
}
for (j = 1, a = 1; (a <= piece_count); j++) {
i = pieces[j];
if (!i)
continue;
else
a++;
assert((i > 0) && (i < 145));
pawn_file = file (i)+1;
srank = rank (i);
switch (board[i]) {
case (wpawn):
isolated = FALSE;
backwards = FALSE;
score += 100;
score += swhite_pawn[i];
if (white_back_pawn[pawn_file+1] > srank
&& white_back_pawn[pawn_file-1] > srank) {
if (srank != 2)
score -= 3;
backwards = TRUE;
if (!pawns[1][pawn_file+1] && !pawns[1][pawn_file-1]) {
score -= 2;
isolated = TRUE;
}
}
if (!pawns[0][pawn_file]) {
if (backwards) score -= 3;
if (isolated) score -= 5;
}
if (pawns[1][pawn_file] > 1)
score -= 2*(pawns[1][pawn_file]-1);
if (!pawns[0][pawn_file] && srank >= black_back_pawn[pawn_file-1] &&
srank >= black_back_pawn[pawn_file+1]) {
score += 5 + 2*swhite_pawn[i];
if (!isolated)
score += 10;
}
break;
case (bpawn):
isolated = FALSE;
backwards = FALSE;
score -= 100;
score -= sblack_pawn[i];
if (black_back_pawn[pawn_file+1] < srank
&& black_back_pawn[pawn_file-1] < srank) {
if (srank != 2)
score += 3;
backwards = TRUE;
if (!pawns[0][pawn_file+1] && !pawns[0][pawn_file-1]) {
score += 2;
isolated = TRUE;
}
}
if (!pawns[1][pawn_file]) {
if (backwards) score += 3;
if (isolated) score += 5;
}
if (pawns[0][pawn_file] > 1)
score += 2*(pawns[0][pawn_file]-1);
if (!pawns[1][pawn_file] && srank <= white_back_pawn[pawn_file-1] &&
srank <= white_back_pawn[pawn_file+1]) {
score -= 5 + 2*sblack_pawn[i];
if (!isolated)
score -= 10;
}
break;
case (wrook):
score += 500;
if (!fwrook) fwrook = file(i);
else if (file(i) == fwrook)
{
if (!pawns[1][pawn_file])
score += 10;
}
if (srank == 7)
score += 8;
if (!pawns[1][pawn_file]) {
score += 5;
if (!pawns[0][pawn_file]) {
score += 3;
}
}
break;
case (brook):
score -= 500;
if (!fbrook) fbrook = file(i);
else if (file(i) == fbrook)
{
if (!pawns[0][pawn_file])
score -= 10;
}
if (srank == 2)
score -= 8;
if (!pawns[0][pawn_file]) {
score -= 5;
if (!pawns[1][pawn_file]) {
score -= 3;
}
}
break;
case (wbishop):
score += 325;
score += sbishop[i];
score += std_b_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
score += bishop_mobility(i);
break;
case (bbishop):
score -= 325;
score -= sbishop[i];
score -= std_b_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
score -= bishop_mobility(i);
break;
case (wknight):
score += 310;
score += sknight[i];
score += std_n_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
break;
case (bknight):
score -= 310;
score -= sknight[i];
score -= std_n_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
break;
case (wqueen):
score += 900;
score += std_q_tropism[max(abs(rank(i) - rank(bking_loc)),
abs(file(i) - file(bking_loc)))];
if (i != 29)
if (!moved[28] || !moved[27] || !moved[31] || !moved[32])
score -= 10;
break;
case (bqueen):
score -= 900;
score -= std_q_tropism[max(abs(rank(i) - rank(wking_loc)),
abs(file(i) - file(wking_loc)))];
if (i != 113)
if (!moved[112] || !moved[111] || !moved[115] || !moved[116])
score += 10;
break;
case (wking):
score += swhite_king[i];
if (white_castled == wcq)
score += 12;
else if (white_castled == wck)
score += 20;
else if (moved[30]) {
score -= 15;
if (!pawns[1][pawn_file])
score -= 10;
}
if (file(wking_loc) != 4 && file(wking_loc) != 5)
{
if (srank < white_back_pawn[pawn_file] && pawns[1][pawn_file])
score -= 7*(white_back_pawn[pawn_file]-srank-1);
else
score -= 14;
if (srank < white_back_pawn[pawn_file+1] && pawns[1][pawn_file+1])
score -= 4*(white_back_pawn[pawn_file+1]-srank-1);
else
score -= 8;
if (srank < white_back_pawn[pawn_file-1] && pawns[1][pawn_file-1])
score -= 4*(white_back_pawn[pawn_file-1]-srank-1);
else
score -= 8;
}
else
{
score -= 7;
}
break;
case (bking):
score -= sblack_king[i];
if (black_castled == bcq)
score -= 12;
else if (black_castled == bck)
score -= 20;
else if (moved[114]) {
score += 15;
if (!pawns[0][pawn_file])
score += 10;
}
if (file(bking_loc) != 4 && file(bking_loc) != 5)
{
if (srank > black_back_pawn[pawn_file] && pawns[0][pawn_file])
score += 7*(srev_rank[srank-black_back_pawn[pawn_file]-1]);
else
score += 14;
if (srank > black_back_pawn[pawn_file+1] && pawns[0][pawn_file+1])
score += 4*(srev_rank[srank-black_back_pawn[pawn_file+1]-1]);
else
score += 8;
if (srank > black_back_pawn[pawn_file-1] && pawns[0][pawn_file-1])
score += 4*(srev_rank[srank-black_back_pawn[pawn_file-1]-1]);
else
score += 8;
}
else
{
score += 7;
}
break;
}
}
if (!moved[41] && board[53] != npiece)
score -= 7;
if (!moved[42] && board[54] != npiece)
score -= 7;
if (!moved[101] && board[89] != npiece)
score += 7;
if (!moved[102] && board[90] != npiece)
score += 7;
wking_pawn_file = file[wking_loc]+1;
bking_pawn_file = file[bking_loc]+1;
if (abs(bking_pawn_file-wking_pawn_file) > 2) {
score -= srev_rank[black_back_pawn[wking_pawn_file]] - 2;
score -= srev_rank[black_back_pawn[wking_pawn_file+1]] - 2;
score -= srev_rank[black_back_pawn[wking_pawn_file-1]] - 2;
score += white_back_pawn[bking_pawn_file] - 2;
score += white_back_pawn[bking_pawn_file+1] - 2;
score += white_back_pawn[bking_pawn_file-1] - 2;
if (!pawns[0][wking_pawn_file])
score -= 6;
if (!pawns[0][wking_pawn_file+1])
score -= 4;
if (!pawns[0][wking_pawn_file-1])
score -= 4;
if (!pawns[1][bking_pawn_file])
score += 6;
if (!pawns[1][bking_pawn_file+1])
score += 4;
if (!pawns[1][bking_pawn_file-1])
score += 4;
}
storeECache(score);
if (white_to_move == 1) {
return score;
}
else {
return -score;
}
}