Presque fini
This commit is contained in:
@@ -1,42 +1,28 @@
|
|||||||
# Makefile pour le projet Taquin - SAE S1.02 / S1.04
|
|
||||||
|
|
||||||
# Variables de compilation
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -std=c89
|
CFLAGS = -Wall -Wextra -std=c89
|
||||||
LDFLAGS = -lgraph
|
LDFLAGS = -lgraph
|
||||||
TARGET = taquin
|
TARGET = taquin
|
||||||
|
|
||||||
# Liste de tous les fichiers sources (.c) - INCLUT TOUS LES MODULES
|
|
||||||
SRCS = src/main.c src/menu_view.c src/game_logic.c src/images.c src/utils.c src/game_view.c
|
SRCS = src/main.c src/menu_view.c src/game_logic.c src/images.c src/utils.c src/game_view.c
|
||||||
|
|
||||||
# Liste de tous les fichiers objets (.o) correspondants
|
|
||||||
# (Transforme src/*.c en obj/*.o)
|
|
||||||
OBJS = $(patsubst src/%.c, obj/%.o, $(SRCS))
|
OBJS = $(patsubst src/%.c, obj/%.o, $(SRCS))
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Cibles principales
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Cible par défaut (crée l'exécutable)
|
|
||||||
all: dir $(TARGET)
|
all: dir $(TARGET)
|
||||||
|
|
||||||
# Crée le dossier obj/ si non existant
|
|
||||||
dir:
|
dir:
|
||||||
@mkdir -p obj
|
@mkdir -p obj
|
||||||
|
|
||||||
# Règle de liaison : crée l'exécutable taquin à partir de tous les objets
|
|
||||||
$(TARGET): $(OBJS)
|
$(TARGET): $(OBJS)
|
||||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
# Règle générique pour la compilation de tous les .c en .o
|
|
||||||
obj/%.o: src/%.c
|
obj/%.o: src/%.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
# Exécute le programme
|
|
||||||
run: $(TARGET)
|
run: $(TARGET)
|
||||||
./$(TARGET)
|
./$(TARGET)
|
||||||
|
|
||||||
# Nettoyage
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf obj $(TARGET)
|
@rm -rf obj $(TARGET)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 161 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+59
-60
@@ -6,22 +6,22 @@
|
|||||||
|
|
||||||
static void index_to_coords(int index, int cols, int *r, int *c)
|
static void index_to_coords(int index, int cols, int *r, int *c)
|
||||||
{
|
{
|
||||||
*r = index / cols;
|
*r = index / cols;
|
||||||
*c = index % cols;
|
*c = index % cols;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_adjacent_indices(int idx, int rows, int cols, int *out_indices)
|
static int find_adjacent_indices(int idx, int rows, int cols, int *out_indices)
|
||||||
{
|
{
|
||||||
int r = idx / cols;
|
int r = idx / cols;
|
||||||
int c = idx % cols;
|
int c = idx % cols;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
if (r > 0) out_indices[n++] = (r - 1) * cols + c;
|
if (r > 0) out_indices[n++] = (r - 1) * cols + c;
|
||||||
if (r < rows - 1) 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 > 0) out_indices[n++] = r * cols + (c - 1);
|
||||||
if (c < cols - 1) out_indices[n++] = r * cols + (c + 1);
|
if (c < cols - 1) out_indices[n++] = r * cols + (c + 1);
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +34,6 @@ void game_init(game_state_t *state, int rows, int cols, tile_t **tiles)
|
|||||||
state->rows = rows;
|
state->rows = rows;
|
||||||
state->cols = cols;
|
state->cols = cols;
|
||||||
state->moves = 0UL;
|
state->moves = 0UL;
|
||||||
state->is_solved = 1;
|
|
||||||
state->all_tiles = tiles;
|
state->all_tiles = tiles;
|
||||||
|
|
||||||
state->permutation = (int *)malloc(num_tiles * sizeof(int));
|
state->permutation = (int *)malloc(num_tiles * sizeof(int));
|
||||||
@@ -44,57 +43,59 @@ void game_init(game_state_t *state, int rows, int cols, tile_t **tiles)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_tiles - 1; i++) {
|
state->permutation[0] = -1;
|
||||||
state->permutation[i] = i;
|
state->empty_index = 0;
|
||||||
|
|
||||||
|
for (i = 1; i < num_tiles; i++) {
|
||||||
|
state->permutation[i] = i - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->permutation[num_tiles - 1] = -1;
|
state->is_solved = 1;
|
||||||
state->empty_index = num_tiles - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_free(game_state_t *state)
|
void game_free(game_state_t *state)
|
||||||
{
|
{
|
||||||
if (state->permutation != NULL) {
|
if (state->permutation != NULL) {
|
||||||
free(state->permutation);
|
free(state->permutation);
|
||||||
state->permutation = NULL;
|
state->permutation = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int game_can_move(const game_state_t *state, int index_to_move)
|
int game_can_move(const game_state_t *state, int index_to_move)
|
||||||
{
|
{
|
||||||
int r_tile, c_tile;
|
int r_tile, c_tile;
|
||||||
int r_empty, c_empty;
|
int r_empty, c_empty;
|
||||||
|
|
||||||
if (index_to_move == state->empty_index) return 0;
|
if (index_to_move == state->empty_index) return 0;
|
||||||
if (index_to_move < 0 || index_to_move >= state->rows * state->cols) 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(index_to_move, state->cols, &r_tile, &c_tile);
|
||||||
index_to_coords(state->empty_index, state->cols, &r_empty, &c_empty);
|
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) {
|
if (abs_val(r_tile - r_empty) + abs_val(c_tile - c_empty) == 1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int game_move_tile(game_state_t *state, int index_to_move)
|
int game_move_tile(game_state_t *state, int index_to_move)
|
||||||
{
|
{
|
||||||
int temp_tile_id;
|
int temp_tile_id;
|
||||||
|
|
||||||
if (!game_can_move(state, index_to_move)) {
|
if (!game_can_move(state, index_to_move)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_tile_id = state->permutation[index_to_move];
|
temp_tile_id = state->permutation[index_to_move];
|
||||||
state->permutation[index_to_move] = state->permutation[state->empty_index];
|
state->permutation[index_to_move] = state->permutation[state->empty_index];
|
||||||
state->permutation[state->empty_index] = temp_tile_id;
|
state->permutation[state->empty_index] = temp_tile_id;
|
||||||
|
|
||||||
state->empty_index = index_to_move;
|
state->empty_index = index_to_move;
|
||||||
|
|
||||||
state->moves++;
|
state->moves++;
|
||||||
state->is_solved = game_is_solved(state);
|
state->is_solved = game_is_solved(state);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int game_is_solved(const game_state_t *state)
|
int game_is_solved(const game_state_t *state)
|
||||||
@@ -102,12 +103,12 @@ int game_is_solved(const game_state_t *state)
|
|||||||
int num_tiles = state->rows * state->cols;
|
int num_tiles = state->rows * state->cols;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (state->permutation[num_tiles - 1] != -1) {
|
if (state->permutation[0] != -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_tiles - 1; i++) {
|
for (i = 1; i < num_tiles; i++) {
|
||||||
if (state->permutation[i] != i) {
|
if (state->permutation[i] != i - 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,26 +118,24 @@ int game_is_solved(const game_state_t *state)
|
|||||||
|
|
||||||
void game_shuffle_safe(game_state_t *state, int steps)
|
void game_shuffle_safe(game_state_t *state, int steps)
|
||||||
{
|
{
|
||||||
int prev_move = -1;
|
int prev_move = -1;
|
||||||
int choices[4];
|
int choices[4];
|
||||||
int n_choices;
|
int n_choices;
|
||||||
int pick_index;
|
int pick_index;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < steps; i++) {
|
for (i = 0; i < steps; i++) {
|
||||||
n_choices = find_adjacent_indices(state->empty_index, state->rows, state->cols, choices);
|
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);
|
||||||
|
|
||||||
do {
|
game_move_tile(state, pick_index);
|
||||||
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;
|
||||||
prev_move = pick_index;
|
state->is_solved = 0;
|
||||||
}
|
|
||||||
|
|
||||||
state->moves = 0UL;
|
|
||||||
state->is_solved = 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -8,6 +8,7 @@ extern int _Y;
|
|||||||
#define MARGIN 50
|
#define MARGIN 50
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int is_in_tile_rect(int x_click, int y_click, int tile_x, int tile_y, int tile_w, int tile_h)
|
static int is_in_tile_rect(int x_click, int y_click, int tile_x, int tile_y, int tile_w, int tile_h)
|
||||||
{
|
{
|
||||||
return (x_click >= tile_x && x_click <= tile_x + tile_w &&
|
return (x_click >= tile_x && x_click <= tile_x + tile_w &&
|
||||||
@@ -56,7 +57,6 @@ void game_render(const game_state_t *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (state->all_tiles != NULL && state->all_tiles[0] != NULL) {
|
if (state->all_tiles != NULL && state->all_tiles[0] != NULL) {
|
||||||
tile_t *sample_tile = state->all_tiles[0];
|
tile_t *sample_tile = state->all_tiles[0];
|
||||||
|
|
||||||
@@ -68,11 +68,10 @@ void game_render(const game_state_t *state)
|
|||||||
RemplirRectangle(model_x - 5, model_y - 5, model_size + 10, model_size + 10);
|
RemplirRectangle(model_x - 5, model_y - 5, model_size + 10, model_size + 10);
|
||||||
ChoisirCouleurDessin(CouleurParNom("black"));
|
ChoisirCouleurDessin(CouleurParNom("black"));
|
||||||
|
|
||||||
|
|
||||||
ChargerImage(sample_tile->path,
|
ChargerImage(sample_tile->path,
|
||||||
model_x, model_y,
|
model_x, model_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
model_size, model_size);
|
sample_tile->width * state->cols, sample_tile->height * state->rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
@@ -93,6 +92,7 @@ void game_render(const game_state_t *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void game_loop(game_state_t *state)
|
void game_loop(game_state_t *state)
|
||||||
{
|
{
|
||||||
unsigned long next_update = Microsecondes() + REFRESH_CYCLE;
|
unsigned long next_update = Microsecondes() + REFRESH_CYCLE;
|
||||||
@@ -167,7 +167,7 @@ void game_loop(game_state_t *state)
|
|||||||
if (state->is_solved) {
|
if (state->is_solved) {
|
||||||
game_render(state);
|
game_render(state);
|
||||||
CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
|
CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
|
||||||
printf("BRAVO ! Partie terminee en %lu coups.\n", state->moves);
|
printf("BRAVO ! Partie terminee en %lu coups. Pressez 'N' pour Nouvelle Partie ou 'Q' pour Quitter.\n", state->moves);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (ToucheEnAttente()) {
|
if (ToucheEnAttente()) {
|
||||||
|
|||||||
+11
-8
@@ -4,24 +4,27 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static const char *IMAGE_PATHS[] = {
|
static const char *IMAGE_PATHS[] = {
|
||||||
"assets/image1.png",
|
"assets/spiderman.jpg", /* Index 0 */
|
||||||
"assets/image2.png",
|
"assets/spiderman.jpg", /* Index 1 */
|
||||||
"assets/image3.png"
|
"assets/spiderman.jpg" /* Index 2 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
image_source_t get_image_source(int selected_index)
|
image_source_t get_image_source(int selected_index)
|
||||||
{
|
{
|
||||||
image_source_t src;
|
image_source_t src;
|
||||||
|
|
||||||
|
|
||||||
src.width = 750;
|
|
||||||
src.height = 450;
|
|
||||||
|
|
||||||
if (selected_index >= 0 && selected_index < 3) {
|
if (selected_index >= 0 && selected_index < 3) {
|
||||||
strcpy(src.path, IMAGE_PATHS[selected_index]);
|
strcpy(src.path, IMAGE_PATHS[selected_index]);
|
||||||
} else {
|
} else {
|
||||||
strcpy(src.path, IMAGE_PATHS[0]);
|
strcpy(src.path, IMAGE_PATHS[0]); /* Fallback */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
src.width = 800;
|
||||||
|
src.height = 480;
|
||||||
|
|
||||||
|
(void) selected_index;
|
||||||
|
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-4
@@ -1,7 +1,9 @@
|
|||||||
#include "menu_view.h"
|
#include "menu_view.h"
|
||||||
|
#include "defs.h"
|
||||||
#include <graph.h>
|
#include <graph.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define IMG_PREVIEW_SIZE 150
|
#define IMG_PREVIEW_SIZE 150
|
||||||
#define IMG_START_X 50
|
#define IMG_START_X 50
|
||||||
@@ -37,6 +39,9 @@ void menu_render(const menu_state_t *state)
|
|||||||
couleur C_START = CouleurParNom("green");
|
couleur C_START = CouleurParNom("green");
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
|
|
||||||
|
char path_buffer[30];
|
||||||
|
const char *path_fixed = "assets/spiderman.jpg"; /* FIXE LE CHEMIN */
|
||||||
|
|
||||||
EffacerEcran(C_FOND);
|
EffacerEcran(C_FOND);
|
||||||
ChoisirCouleurDessin(C_TEXTE);
|
ChoisirCouleurDessin(C_TEXTE);
|
||||||
|
|
||||||
@@ -46,11 +51,10 @@ void menu_render(const menu_state_t *state)
|
|||||||
for (i = 0; i < NUM_IMAGES; i++) {
|
for (i = 0; i < NUM_IMAGES; i++) {
|
||||||
int x = IMG_START_X + i * IMG_SPACING;
|
int x = IMG_START_X + i * IMG_SPACING;
|
||||||
int y = IMG_START_Y;
|
int y = IMG_START_Y;
|
||||||
char path[30];
|
|
||||||
|
|
||||||
sprintf(path, "assets/image%d.png", i + 1);
|
strcpy(path_buffer, path_fixed);
|
||||||
|
|
||||||
ChargerImage(path, x, y, 0, 0, IMG_PREVIEW_SIZE, IMG_PREVIEW_SIZE);
|
ChargerImage(path_buffer, x, y, 0, 0, IMG_PREVIEW_SIZE, IMG_PREVIEW_SIZE);
|
||||||
|
|
||||||
if (state->selected_image == i) {
|
if (state->selected_image == i) {
|
||||||
ChoisirCouleurDessin(C_SELECTION);
|
ChoisirCouleurDessin(C_SELECTION);
|
||||||
@@ -107,7 +111,8 @@ void menu_handle_mouse_click(menu_state_t *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_in_rect(x_click, y_click, dim_section_x + button_l_offset, DIM_START_Y + 30, btn_size, btn_size)) {
|
|
||||||
|
if (is_in_rect(x_click, y_click, dim_section_x + button_l_offset, DIM_START_Y + 30, btn_size, btn_size)) {
|
||||||
if (state->rows < MAX_DIMENSION) state->rows++;
|
if (state->rows < MAX_DIMENSION) state->rows++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user