#include "game_logic.h" #include "utils.h" #include #include static void index_to_coords(int index, int cols, int *r, int *c) { *r = index / cols; *c = index % cols; } static int find_adjacent_indices(int idx, int rows, int cols, int *out_indices) { int r = idx / cols; int c = idx % cols; int n = 0; if (r > 0) out_indices[n++] = (r - 1) * cols + c; if (r < rows - 1) out_indices[n++] = (r + 1) * cols + c; if (c > 0) out_indices[n++] = r * cols + (c - 1); if (c < cols - 1) out_indices[n++] = r * cols + (c + 1); return n; } void game_init(game_state_t *state, int rows, int cols, tile_t **tiles) { int num_tiles = rows * cols; int i; state->rows = rows; state->cols = cols; state->moves = 0UL; state->all_tiles = tiles; state->permutation = (int *)malloc(num_tiles * sizeof(int)); if (state->permutation == NULL) { fprintf(stderr, "Erreur: Allocation permutation echouee.\n"); return; } state->permutation[0] = -1; state->empty_index = 0; for (i = 1; i < num_tiles; i++) { state->permutation[i] = i - 1; } state->is_solved = 1; } void game_free(game_state_t *state) { if (state->permutation != NULL) { free(state->permutation); state->permutation = NULL; } } int game_can_move(const game_state_t *state, int index_to_move) { int r_tile, c_tile; int r_empty, c_empty; if (index_to_move == state->empty_index) return 0; if (index_to_move < 0 || index_to_move >= state->rows * state->cols) return 0; index_to_coords(index_to_move, state->cols, &r_tile, &c_tile); index_to_coords(state->empty_index, state->cols, &r_empty, &c_empty); if (abs_val(r_tile - r_empty) + abs_val(c_tile - c_empty) == 1) { return 1; } return 0; } int game_move_tile(game_state_t *state, int index_to_move) { int temp_tile_id; if (!game_can_move(state, index_to_move)) { return 0; } temp_tile_id = state->permutation[index_to_move]; state->permutation[index_to_move] = state->permutation[state->empty_index]; state->permutation[state->empty_index] = temp_tile_id; state->empty_index = index_to_move; state->moves++; state->is_solved = game_is_solved(state); return 1; } int game_is_solved(const game_state_t *state) { int num_tiles = state->rows * state->cols; int i; if (state->permutation[0] != -1) { return 0; } for (i = 1; i < num_tiles; i++) { if (state->permutation[i] != i - 1) { return 0; } } return 1; } void game_shuffle_safe(game_state_t *state, int steps) { int prev_move = -1; int choices[4]; int n_choices; int pick_index; int i; for (i = 0; i < steps; i++) { n_choices = find_adjacent_indices(state->empty_index, state->rows, state->cols, choices); do { pick_index = choices[random_int(n_choices)]; } while (n_choices > 1 && pick_index == prev_move); game_move_tile(state, pick_index); prev_move = pick_index; } state->moves = 0UL; state->is_solved = 0; }