I've been trying to implement SEE in QS. After 20k games played it looks like the non-see is 13 elo better, not good.
I don't see what I'm doing wrong here. Maybe any of you?
Code: Select all
To reduce the number of variables that need to be pushed on the stack, I've put the ones that stay the same in a structure that is passed as a parameter.
Scene *s is an object that keeps the board structure, the chess piece info, etc
MoveList *mls[2] are the lists of moves for white and for black
mlIndex[2] is, for white and for black, the position in their movelists. That way I don't need to remove the ones I processed from the list.
bool first is magic so that the first move processed is the one in the movelist we're working on in quiesceSearch(). That way the 2nd and so on are again from the beginning of the list.
targetx/y are the field we're working on
typedef struct
{
Scene *s;
MoveList *mls[2];
size_t mlIndex[2];
bool first;
int targetx, targety;
} see_pars_t;
int see(see_pars_t *const sp, const PlayerColor c)
{
// get a pointer to the board-structure (8x8)
Board *b = sp -> s -> getBoard();
Move m;
for(;;) {
// get a move from the movelist of the current color (c)
m = sp -> mls[c] -> at(sp -> mlIndex[c]);
sp -> mlIndex[c]++;
if (sp -> first) {
sp -> mlIndex[c] = 0;
sp -> first = false;
}
// if it is not a capture move (or end of list reached) then stop going through the
// movelist. the lists are sorted, captures (and promotions) first
if (m.isCatchMove == false || sp -> mlIndex[c] >= sp -> mls[c] -> size())
return 0;
// if the piece the current move "points to" has already been moved, then we cannot
// use this move
if (b -> getAt(m.fx, m.fy) == NULL)
continue;
// this move targets the move? then use it
const ChessPiece *victim = b -> findVictim(m);
if (victim && victim -> getX() == sp -> targetx && victim -> getY() == sp -> targety)
break;
}
// find the evaluation-value of the piece that's on the target-field
int eval = b -> getAt(sp -> targetx, sp -> targety) -> getEvalVal();
sp -> s -> doMove(m);
// subtract the value of a call to see() for the opponent color
eval -= see(sp, opponentColor(c));
sp -> s -> undoMove();
return eval;
}
int quiesceSearch()
{
for(Move *m : moves) {
bool icm = m -> isCatchMove;
if (ivm) {
sp.first = true;
sp.mlIndex[c] = idx;
sp.mlIndex[opponentColor(c)] = 0;
sp.targetx = m -> tx;
sp.targety = m -> ty;
int seeVal = see(&sp, c);
icm = m -> promoteTo != NONE ? seeVal >= 0 : seeVal > 0;
}
if (icm) {
// do move (doMove() ; quiesceSearch() ; undoMove() and so on)
}
}