diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-08-20 17:02:39 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-08-20 17:02:39 +0300 |
commit | 8efa8499eaae45a2bb2658142f720bb2bcd77088 (patch) | |
tree | e29e054c957ed3f094d8a98c87a1ccd897f7c767 | |
parent | 5deeb35149ca72445b502586c583ea15a4186117 (diff) | |
download | c-chess-8efa8499eaae45a2bb2658142f720bb2bcd77088.tar.gz |
feat: add checkmate
-rw-r--r-- | src/main.c | 62 |
1 files changed, 37 insertions, 25 deletions
@@ -120,6 +120,9 @@ Move input_move() { }; int validate_move(Move move, int color, int* board) { + // Null move means player is checkmated + if (move.origin == -100 && move.destination == -100) return INFINITY; + if ((move.origin & 0x88) || (move.destination & 0x88)) return -1; int piece = board[move.origin]; @@ -543,34 +546,37 @@ void sort_moves(Move* moves, int moves_count, int* board) { Move find_best_move(int* board, int color, int depth, int alpha, int beta, int* metrics) { int is_maximizer = (color == 0); - Move best_move; - best_move.value = is_maximizer ? -INFINITY : INFINITY; + Move best_move = { -100, -100, 0 }; + best_move.value = is_maximizer ? -100 * INFINITY / (depth + 1) : 100 * INFINITY / (depth + 1); - Move available_moves[MAX_AVAILABLE_MOVES]; - int availabel_moves_count = list_available_moves(available_moves, board, color); - sort_moves(available_moves, availabel_moves_count, board); + // You only have available moves if your king hasn't been taken + if (compute_material_advantage(board, color) > -INFINITY / 2) { + Move available_moves[MAX_AVAILABLE_MOVES]; + int availabel_moves_count = list_available_moves(available_moves, board, color); + sort_moves(available_moves, availabel_moves_count, board); - for (int i = 0; i < availabel_moves_count; i++) { - *metrics += 1; - Move move = available_moves[i]; + for (int i = 0; i < availabel_moves_count; i++) { + *metrics += 1; + Move move = available_moves[i]; - int captured_piece = apply_move(move, board); + int captured_piece = apply_move(move, board); - move.value = depth < MAX_DEPTH - ? find_best_move(board, 1 - color, depth + 1, alpha, beta, metrics).value - : compute_score(board); + move.value = depth < MAX_DEPTH + ? find_best_move(board, 1 - color, depth + 1, alpha, beta, metrics).value + : compute_score(board); - reverse_move(move, captured_piece, board); + reverse_move(move, captured_piece, board); - if (is_maximizer) { - if (move.value > best_move.value) best_move = move; - alpha = MAX(best_move.value, alpha); - } else { - if (move.value < best_move.value) best_move = move; - beta = MIN(best_move.value, beta); - } + if (is_maximizer) { + if (move.value > best_move.value) best_move = move; + alpha = MAX(best_move.value, alpha); + } else { + if (move.value < best_move.value) best_move = move; + beta = MIN(best_move.value, beta); + } - if (beta <= alpha) break; + if (beta <= alpha) break; + } } return best_move; @@ -598,19 +604,25 @@ int main() { start = clock(); move = find_best_move(board, color, 0, -INFINITY, +INFINITY, &metrics); end = clock(); - char move_in_notation[] = "xy XY"; - index_to_notation(move.origin, move_in_notation); - index_to_notation(move.destination, move_in_notation + 3); printf("[%i positions analyzed in %f seconds]\n", metrics, (double)(end - start) / CLOCKS_PER_SEC); - printf("Best move for black is %s with score %i in #%i moves\n", move_in_notation, move.value, MAX_DEPTH); } int error = validate_move(move, color, board); if (error < 0) { printf("Invalid move: %s!\n", VALIDATION_ERRORS[-1 - error]); + } else if (error == INFINITY) { + printf("Checkmate, %s is victorious!\n", COLORS[1 - color]); + break; } else { apply_move(move, board); + print_board(board); + + char move_in_notation[] = "xy XY"; + index_to_notation(move.origin, move_in_notation); + index_to_notation(move.destination, move_in_notation + 3); + printf("%s: %s with score %i in #%i moves\n", COLORS[color], move_in_notation, move.value, MAX_DEPTH); + color ^= 1; } } |