Long time lurker, first time poster, and all that jazz. Normally I can solve any problem I run into, but I'm a bit stumped trying to implement the counter move heuristic as described in the chess programming wiki. I've got it implemented, but it makes my search worse, sometimes much worse, and never even marginally better. I've tested across a number of board positions and at a number of depths. Search time and number of nodes always goes up. I'm clearly doing something wrong, but I don't know what.
I've tested to ensure that it is matching up the correct moves by printing the board at the top of each search and then having the program tell me when it finds a countermove. The countermove is the current move being scored and the previous move it is matching with aligns with the previous printed board position. So the right values are being scored, I would assume. I've also tried giving the counter moves a variety of different scores. Anything but 0 makes things worse.
My evaluation function right now is just the simplified evaluation, also from the chess programming wiki. I'll attach the relevant code below, in the hopes that someone spots an obvious error and can stop me from banging my head against a wall.
First, the move scoring function in its entirety:
Code: Select all
int Board::ScoreMove(Move move, int piece, int target, int ply)
{
if (move == hash_move1 || move == hash_move2)
return 25000;
if (score_pv && pv_line[ply] == move) {
score_pv = false;
return 20000;
}
if (GetPromotedPiece(move))
return 19000;
if (move == killer_move1[ply])
return 9000;
if (move == killer_move2[ply])
return 8000;
int from = GetFromSquare(previous_move);
int to = GetToSquare(previous_move);
if (move == counter_moves[from][to])
return 7000;
return history_moves[piece][target];
}
Code: Select all
if (score >= beta)
{
ply--;
if (!captured)
{
board.killer_move2[ply] = board.killer_move1[ply];
board.killer_move1[ply] = move;
int from = GetFromSquare(old_previous_move);
int to = GetToSquare(old_previous_move);
board.counter_moves[from][to] = move;
}
board.UnmakeMove(move);
board.game_state = old_game_state;
board.previous_move = old_previous_move;
return beta;
}
Any obvious thing I'm missing would be super helpful.