#include "sjeng.h"
#include "extvars.h"
typedef struct
{
int piece;
int square;
} see_data;
see_data see_attackers[2][16];
int see_num_attackers[2];
void setup_attackers (int square) {
static const int rook_o[4] = {12, -12, 1, -1};
static const int bishop_o[4] = {11, -11, 13, -13};
static const int knight_o[8] = {10, -10, 14, -14, 23, -23, 25, -25};
register int a_sq, b_sq, i;
int numw = see_num_attackers[WHITE], numb = see_num_attackers[BLACK];
for (i = 0; i < 4; i++)
{
a_sq = square + rook_o[i];
b_sq = board[a_sq];
if (b_sq == wking)
{
see_attackers[WHITE][numw].piece = b_sq;
see_attackers[WHITE][numw].square = a_sq;
numw++;
break;
}
else if (b_sq == bking)
{
see_attackers[BLACK][numb].piece = b_sq;
see_attackers[BLACK][numb].square = a_sq;
numb++;
break;
}
else
{
while (b_sq != frame)
{
if (b_sq == wrook || b_sq == wqueen)
{
see_attackers[WHITE][numw].piece = b_sq;
see_attackers[WHITE][numw].square = a_sq;
numw++;
break;
}
else if (b_sq == brook || b_sq == bqueen)
{
see_attackers[BLACK][numb].piece = b_sq;
see_attackers[BLACK][numb].square = a_sq;
numb++;
break;
}
else if (b_sq != npiece) break;
a_sq += rook_o [i];
b_sq = board[a_sq];
}
}
}
for (i = 0; i < 4; i++)
{
a_sq = square + bishop_o[i];
b_sq = board[a_sq];
if (b_sq == wpawn && i%2)
{
see_attackers[WHITE][numw].piece = b_sq;
see_attackers[WHITE][numw].square = a_sq;
numw++;
break;
}
else if (b_sq == bpawn && !(i%2))
{
see_attackers[BLACK][numb].piece = b_sq;
see_attackers[BLACK][numb].square = a_sq;
numb++;
break;
}
else if (b_sq == wking)
{
see_attackers[WHITE][numw].piece = b_sq;
see_attackers[WHITE][numw].square = a_sq;
numw++;
break;
}
else if (b_sq == bking)
{
see_attackers[BLACK][numb].piece = b_sq;
see_attackers[BLACK][numb].square = a_sq;
numb++;
break;
}
else
{
while (b_sq != frame) {
if (b_sq == wbishop || b_sq == wqueen)
{
see_attackers[WHITE][numw].piece = b_sq;
see_attackers[WHITE][numw].square = a_sq;
numw++;
break;
}
else if (b_sq == bbishop || b_sq == bqueen)
{
see_attackers[BLACK][numb].piece = b_sq;
see_attackers[BLACK][numb].square = a_sq;
numb++;
break;
}
else if (b_sq != npiece) break;
a_sq += bishop_o [i];
b_sq = board[a_sq];
}
}
}
for (i = 0; i < 8; i++)
{
a_sq = square + knight_o[i];
b_sq = board[a_sq];
if (b_sq == wknight)
{
see_attackers[WHITE][numw].piece = b_sq;
see_attackers[WHITE][numw].square = a_sq;
numw++;
}
else if (b_sq == bknight)
{
see_attackers[BLACK][numb].piece = b_sq;
see_attackers[BLACK][numb].square = a_sq;
numb++;
}
}
see_num_attackers[WHITE] = numw;
see_num_attackers[BLACK] = numb;
}
void findlowest(int color, int next)
{
int lowestp;
int lowestv;
see_data swap;
int i;
lowestp = next;
lowestv = abs(material[see_attackers[color][next].piece]);
for (i = next; i < see_num_attackers[color]; i++)
{
if (abs(material[see_attackers[color][i].piece]) < lowestv)
{
lowestp = i;
lowestv = abs(material[see_attackers[color][i].piece]);
}
}
swap = see_attackers[color][next];
see_attackers[color][next] = see_attackers[color][lowestp];
see_attackers[color][lowestp] = swap;
}
int see(int color, int square, int from)
{
int sside;
int caps[2];
int value;
int origpiece;
int ourbestvalue;
int hisbestvalue;
see_num_attackers[WHITE] = 0;
see_num_attackers[BLACK] = 0;
origpiece = board[from];
board[from] = npiece;
see_num_attackers[color]++;
see_attackers[color][0].piece = origpiece;
see_attackers[color][0].square = from;
setup_attackers(square);
value = abs(material[board[square]]);
if (!see_num_attackers[!color])
{
board[from] = origpiece;
return value;
}
else
{
hisbestvalue = value;
ourbestvalue = -INF;
}
caps[color] = 1;
caps[!color] = 0;
sside = !color;
while (caps[sside] < see_num_attackers[sside])
{
findlowest(sside, caps[sside]);
if (sside == color)
{
value += abs(material[see_attackers[!sside][caps[!sside]-1].piece]);
if (see_num_attackers[!sside] <= caps[!sside] && value > ourbestvalue)
ourbestvalue = value;
if (value < hisbestvalue) hisbestvalue = value;
}
else
{
value -= abs(material[see_attackers[!sside][caps[!sside]-1].piece]);
if (value > ourbestvalue)
{
ourbestvalue = value;
}
if (see_num_attackers[!sside] <= caps[!sside] && value < hisbestvalue)
hisbestvalue = value;
}
caps[sside]++;
sside ^= 1;
}
board[from] = origpiece;
return (ourbestvalue > hisbestvalue) ? hisbestvalue : ourbestvalue;
}