summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2022-08-20 17:02:39 +0300
committereug-vs <eugene@eug-vs.xyz>2022-08-20 17:02:39 +0300
commit8efa8499eaae45a2bb2658142f720bb2bcd77088 (patch)
treee29e054c957ed3f094d8a98c87a1ccd897f7c767
parent5deeb35149ca72445b502586c583ea15a4186117 (diff)
downloadc-chess-8efa8499eaae45a2bb2658142f720bb2bcd77088.tar.gz
feat: add checkmate
-rw-r--r--src/main.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/src/main.c b/src/main.c
index b446fd6..2b7275f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
}
}