I have a humble help request of more like showing me a path rather than a concrete solution, but still I'll describe the issue.
I've created 30+ youtube video series on creating a simple chess engine from scratch.
I thought I'm so cool... until reached the negamax alphabeta search...
While understanding move generation process really clear (as series shows) I've horribly realized that when it came to the search I always copypasted it...
I know it's a shame... So from now on I really really want to master it and looking for a guidance at this point.
Particular technical issue I encounter: mating score and associated move are not always returned correclty, it seems like it depends on search depth somehow, e.g. at depth 5 it doesn't find mate in 1 while at depth 2 it does.
I have a very very basic negamax failhard framework (copypasted numerous times(((( ):
Code: Select all
// search position
int search_position(int alpha, int beta, int depth)
{
// legal moves
int legal_moves = 0;
// best move
int best_so_far = 0;
// old alpha
int old_alpha = alpha;
// escape condition
if (!depth)
// search for calm position before evaluation
return quiescence_search(alpha, beta);
// create move list variable
moves move_list[1];
// generate moves
generate_moves(move_list);
// loop over the generated moves
for (int move_count = 0; move_count < move_list->count; move_count++)
{
// define board state variable copies
int board_copy[128], king_square_copy[2];
int side_copy, enpassant_copy, castle_copy;
// copy board state
memcpy(board_copy, board, 512);
side_copy = side;
enpassant_copy = enpassant;
castle_copy = castle;
memcpy(king_square_copy, king_square,8);
// make only legal moves
if (!make_move(move_list->moves[move_count], all_moves))
// skip illegal move
continue;
// increment legal moves
legal_moves++;
// recursive call
int score = -search_position(-beta, -alpha, depth - 1);
// restore board position
memcpy(board, board_copy, 512);
side = side_copy;
enpassant = enpassant_copy;
castle = castle_copy;
memcpy(king_square, king_square_copy,8);
// fail hard beta-cutoff
if (score >= beta)
return beta;
// alpha acts like max in MiniMax
if (score > alpha)
{
// set alpha score
alpha = score;
// store current best move
best_so_far = move_list->moves[move_count];
}
}
// if no legal moves
if (!legal_moves)
{
// check mate detection
if (is_square_attacked(king_square[side], side ^ 1))
return -49000;
// stalemate detection
else
return 0;
}
// associate best score with best move
if (alpha != old_alpha)
best_move = best_so_far;
// return alpha score
return alpha;
}
it has timestamps in the description pointing out where the issue occurs.
I'm not asking for a working solution but I would be very very grateful if you guys kindly point me the right direction. Thanks in advance!