diff --git a/Makefile b/Makefile index 4fceb3d..9a52d92 100644 --- a/Makefile +++ b/Makefile @@ -2,18 +2,15 @@ # Variables de compilation CC = gcc -CFLAGS = -Wall -Wextra -std=c89 +CFLAGS = -Wall -Wextra -std=c89 LDFLAGS = -lgraph TARGET = taquin -<<<<<<< HEAD # Liste de tous les fichiers sources (.c) - INCLUT TOUS LES MODULES -======= -# Liste de tous les fichiers sources (.c) - INCLUT game_view.c ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c 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)) # ---------------------------------------------------------------------- @@ -25,26 +22,22 @@ all: dir $(TARGET) # Crée le dossier obj/ si non existant dir: - @mkdir -p obj + @mkdir -p obj # Règle de liaison : crée l'exécutable taquin à partir de tous les objets $(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 - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -c $< -o $@ # Exécute le programme run: $(TARGET) - ./$(TARGET) + ./$(TARGET) # Nettoyage clean: -<<<<<<< HEAD @rm -rf obj $(TARGET) -======= - @rm -rf obj $(TARGET) ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c .PHONY : all clean run diff --git a/obj/game_logic.o b/obj/game_logic.o index ca3442c..cf48cf8 100644 Binary files a/obj/game_logic.o and b/obj/game_logic.o differ diff --git a/obj/game_view.o b/obj/game_view.o index 413c49e..f3bd048 100644 Binary files a/obj/game_view.o and b/obj/game_view.o differ diff --git a/obj/images.o b/obj/images.o index 7daa184..7da2903 100644 Binary files a/obj/images.o and b/obj/images.o differ diff --git a/obj/main.o b/obj/main.o index 9e8a3b2..cd27842 100644 Binary files a/obj/main.o and b/obj/main.o differ diff --git a/obj/menu_view.o b/obj/menu_view.o index 306e829..dd99200 100644 Binary files a/obj/menu_view.o and b/obj/menu_view.o differ diff --git a/obj/utils.o b/obj/utils.o index d61a19d..ca15542 100644 Binary files a/obj/utils.o and b/obj/utils.o differ diff --git a/src/game_view.c b/src/game_view.c index 1d989b7..94c4ca9 100644 --- a/src/game_view.c +++ b/src/game_view.c @@ -1,44 +1,27 @@ -<<<<<<< HEAD /* src/game_view.c * Implémentation du rendu graphique du plateau et de la boucle d'interaction. */ -======= ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c #include "game_view.h" #include #include #include -<<<<<<< HEAD -/* Constantes et variables globales (définies dans d'autres modules ou par l'IUT) */ -======= -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 - ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c extern int _X; extern int _Y; #define MARGIN 50 /* Marge autour du plateau */ -<<<<<<< HEAD /* --- Fonctions Utilitaires Privées --- */ /* Vérifie si un clic est sur une tuile donnée */ -======= -/* Fonction utilitaire : vérifie si un clic est sur une tuile donnée */ ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c 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 && y_click >= tile_y && y_click <= tile_y + tile_h); } -<<<<<<< HEAD /* --- Fonctions de Rendu et de Logique --- */ -======= ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c /* Dessine le plateau de jeu */ void game_render(const game_state_t *state) @@ -46,7 +29,6 @@ void game_render(const game_state_t *state) int i, r, c; couleur C_FOND = CouleurParNom("gray"); couleur C_BORDURE = CouleurParNom("black"); -<<<<<<< HEAD EffacerEcran(C_FOND); @@ -56,38 +38,18 @@ void game_render(const game_state_t *state) ChoisirCouleurDessin(C_BORDURE); -======= - - EffacerEcran(C_FOND); - - /* Calcul de la taille de chaque tuile pour l'affichage (utilise la taille de la première tuile) */ - int tile_display_w = state->all_tiles[0]->width; - int tile_display_h = state->all_tiles[0]->height; - - - ChoisirCouleurDessin(C_BORDURE); - ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c /* Boucle sur toutes les cases du plateau */ for (i = 0; i < state->rows * state->cols; i++) { int tile_id = state->permutation[i]; int x_pos, y_pos; -<<<<<<< HEAD r = i / state->cols; c = i % state->cols; -======= - - r = i / state->cols; - c = i % state->cols; - ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c /* Position d'affichage sur l'écran */ x_pos = MARGIN + c * tile_display_w; y_pos = MARGIN + r * tile_display_h; -<<<<<<< HEAD if (tile_id != -1) { /* C'est une tuile (non vide) */ tile_t *current_tile = state->all_tiles[tile_id]; @@ -102,49 +64,22 @@ void game_render(const game_state_t *state) } else { /* Dessine la case vide en couleur distincte (jaune) */ -======= - if (tile_id != -1) { /* Ne dessine pas si c'est la case vide */ - tile_t *current_tile = state->all_tiles[tile_id]; - - /* ChargerImage(fichier, x_dst, y_dst, x_src, y_src, l, h) */ - ChargerImage(current_tile->path, - x_pos, y_pos, - current_tile->src_x, current_tile->src_y, - tile_display_w, tile_display_h); - - /* Dessine une fine bordure autour de la tuile */ - DessinerRectangle(x_pos, y_pos, tile_display_w, tile_display_h); - - } else { - /* Dessine la case vide en jaune (ou couleur distincte) */ ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c ChoisirCouleurDessin(CouleurParNom("yellow")); RemplirRectangle(x_pos, y_pos, tile_display_w, tile_display_h); ChoisirCouleurDessin(C_BORDURE); DessinerRectangle(x_pos, y_pos, tile_display_w, tile_display_h); } } -<<<<<<< HEAD -======= - ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c /* Affichage du compteur de coups */ char buffer[100]; sprintf(buffer, "Coups: %lu", state->moves); EcrireTexte(MARGIN, WINDOW_HEIGHT - 30, buffer, 1); -<<<<<<< HEAD /* Affichage de la victoire */ if (state->is_solved) { ChoisirCouleurDessin(CouleurParNom("red")); EcrireTexte(WINDOW_WIDTH / 2 - 100, WINDOW_HEIGHT / 2, "BRAVO ! PRESSEZ UNE TOUCHE.", 2); -======= - - /* Affichage de la victoire si résolu */ - if (state->is_solved) { - /* TODO: Afficher un grand BRAVO */ ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c } } @@ -152,29 +87,17 @@ void game_render(const game_state_t *state) /* Gère les entrées (clic/clavier) et la boucle principale du jeu */ void game_loop(game_state_t *state) { -<<<<<<< HEAD unsigned long next_update = Microsecondes() + REFRESH_CYCLE; int go_on = 1; while (go_on && !state->is_solved) -======= - unsigned long next_update = Microsecondes() + 50000L; - int go_on = 1; - - while (go_on && !state->is_solved) ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c { /* Rendu et rafraîchissement */ if (Microsecondes() > next_update) { game_render(state); -<<<<<<< HEAD CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); next_update = Microsecondes() + REFRESH_CYCLE; -======= - CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); - next_update = Microsecondes() + 50000L; ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c } /* Gestion des événements Souris */ @@ -185,29 +108,17 @@ void game_loop(game_state_t *state) int y_click = _Y; int tile_w = state->all_tiles[0]->width; int tile_h = state->all_tiles[0]->height; -<<<<<<< HEAD -======= - ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c /* Parcourir toutes les tuiles pour voir laquelle a été cliquée */ for (i = 0; i < state->rows * state->cols; i++) { int r = i / state->cols; int c = i % state->cols; -<<<<<<< HEAD -======= - ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c int x_pos = MARGIN + c * tile_w; int y_pos = MARGIN + r * tile_h; if (is_in_tile_rect(x_click, y_click, x_pos, y_pos, tile_w, tile_h)) { -<<<<<<< HEAD /* Tenter de déplacer la tuile cliquée (indice i) */ -======= - /* Tenter de déplacer la tuile cliquée */ ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c game_move_tile(state, i); break; } @@ -217,7 +128,6 @@ void game_loop(game_state_t *state) /* Gestion des événements Clavier */ if (ToucheEnAttente()) { int key = Touche(); -<<<<<<< HEAD int target_index = -1; int empty_r = state->empty_index / state->cols; @@ -226,19 +136,19 @@ void game_loop(game_state_t *state) if (key == XK_Escape) { go_on = 0; } - /* CORRECTION FINALE : Inverse le mapping de commande pour la perception intuitive */ + /* CORRECTION FINALE : Inverse le mapping pour la perception intuitive */ else if (key == XK_Up) { - /* Le joueur appuie HAUT (monte) -> la tuile en BAS (r+1) doit monter */ + /* Flèche HAUT : Déplace la tuile en BAS (r + 1) vers le vide (r) */ target_index = (empty_r + 1) * state->cols + empty_c; } else if (key == XK_Down) { - /* Le joueur appuie BAS (descend) -> la tuile en HAUT (r-1) doit descendre */ + /* Flèche BAS : Déplace la tuile en HAUT (r - 1) vers le vide (r) */ target_index = (empty_r - 1) * state->cols + empty_c; } else if (key == XK_Left) { - /* Le joueur appuie GAUCHE -> la tuile à DROITE (c+1) va à gauche */ + /* Flèche GAUCHE : Déplace la tuile de DROITE (c + 1) vers le vide (c) */ target_index = empty_r * state->cols + (empty_c + 1); } else if (key == XK_Right) { - /* Le joueur appuie DROITE -> la tuile à GAUCHE (c-1) va à droite */ + /* Flèche DROITE : Déplace la tuile de GAUCHE (c - 1) vers le vide (c) */ target_index = empty_r * state->cols + (empty_c - 1); } @@ -269,20 +179,3 @@ void game_loop(game_state_t *state) } } } -======= - if (key == XK_Escape) { - go_on = 0; /* Quitter la boucle de jeu */ - } - /* TODO: Ajouter les flèches pour les déplacements clavier */ - } - } - - /* Si la boucle est terminée par la victoire, on affiche le BRAVO */ - if (state->is_solved) { - game_render(state); /* Dernière mise à jour pour montrer l'image complète */ - CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); - printf("BRAVO ! Partie terminee en %lu coups.\n", state->moves); - Touche(); /* Attend une touche avant de nettoyer */ - } -} ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c diff --git a/src/game_view.h b/src/game_view.h index 89a7079..ba9b6b7 100644 --- a/src/game_view.h +++ b/src/game_view.h @@ -1,4 +1,3 @@ -<<<<<<< HEAD /* src/game_view.h * Définitions du module de la vue du plateau de jeu. */ @@ -6,13 +5,7 @@ #define GAME_VIEW_H #include "game_logic.h" -#include "defs.h" /* Nécessaire pour les constantes de fenêtre */ -======= -#ifndef GAME_VIEW_H -#define GAME_VIEW_H - -#include "game_logic.h" /* Nécessaire pour connaître la structure game_state_t */ ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c +#include "defs.h" /* Dessine le plateau de jeu, les tuiles à leur position actuelle, et le compteur de coups. */ void game_render(const game_state_t *state); @@ -20,8 +13,4 @@ void game_render(const game_state_t *state); /* Gère la boucle principale du jeu, les événements (clics/clavier) et les rafraîchissements. */ void game_loop(game_state_t *state); -<<<<<<< HEAD #endif /* GAME_VIEW_H */ -======= -#endif /* GAME_VIEW_H */ ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c diff --git a/src/main.c b/src/main.c index dafc663..6c7eab2 100644 --- a/src/main.c +++ b/src/main.c @@ -2,13 +2,12 @@ * Point d'entrée du programme Taquin. * Gère la boucle principale des événements et la transition de vue (Menu -> Jeu). */ -#include "game_view.h" #include "menu_view.h" #include "game_logic.h" #include "images.h" -#include "game_view.h" /* NOUVEAU: Pour la boucle de jeu */ -#include "defs.h" /* NOUVEAU: Pour les constantes de fenêtre */ +#include "game_view.h" +#include "defs.h" #include #include #include @@ -18,66 +17,81 @@ int main(void) { menu_state_t menu_state; unsigned long next_update; + int play_again = 1; /* 1. Initialisation de l'environnement IUT */ InitialiserGraphique(); CreerFenetre(10, 10, WINDOW_WIDTH, WINDOW_HEIGHT); srand((unsigned int)time(NULL)); - menu_init(&menu_state); - next_update = Microsecondes() + REFRESH_CYCLE; + /* Grande boucle pour rejouer (retourne au menu) */ + do { + play_again = 0; /* Réinitialisation pour cette tentative */ - /* 2. Boucle du Menu */ - while (menu_state.ready_to_play == 0) - { - if (Microsecondes() > next_update) + /* 2. Phase de Configuration (Menu) */ + menu_init(&menu_state); + next_update = Microsecondes() + REFRESH_CYCLE; + + while (menu_state.ready_to_play == 0 && menu_state.ready_to_play != -1) { - menu_render(&menu_state); - CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); - next_update = Microsecondes() + REFRESH_CYCLE; + if (Microsecondes() > next_update) + { + menu_render(&menu_state); + CopierZone(0, 0, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0); + next_update = Microsecondes() + REFRESH_CYCLE; + } + + if (SourisCliquee()) { + menu_handle_mouse_click(&menu_state); + } + menu_handle_key(&menu_state); + } + + /* Sortie du menu par validation */ + if (menu_state.ready_to_play == 1) { + + image_source_t img_src; + tile_t **tiles; + game_state_t game_state; + int num_tiles; + + /* Préparation des données et initialisation du moteur de jeu */ + img_src = get_image_source(menu_state.selected_image); + tiles = images_slice(img_src, menu_state.rows, menu_state.cols); + + if (tiles == NULL) { + fprintf(stderr, "Erreur: Allocation tuiles echouee. Retour au menu.\n"); + continue; + } + + num_tiles = menu_state.rows * menu_state.cols; + game_init(&game_state, menu_state.rows, menu_state.cols, tiles); + game_shuffle_safe(&game_state, 500); + + printf("DEBUG: Jeu prêt. Grille %d x %d melangee.\n", + game_state.rows, game_state.cols); + + /* Lancement de la BOUCLE DE JEU */ + game_loop(&game_state); + + /* Après game_loop (si la boucle est sortie par victoire ou ESC) */ + + /* S'assurer que le joueur veut rejouer */ + if (ToucheEnAttente()) { + int final_key = Touche(); + if (final_key == 'n' || final_key == 'N') { + play_again = 1; /* Remet la grande boucle en marche */ + } + } + + /* Nettoyage des ressources allouées */ + images_free_tiles(tiles, num_tiles); + game_free(&game_state); } - if (SourisCliquee()) - { - menu_handle_mouse_click(&menu_state); - } + } while (play_again == 1); - menu_handle_key(&menu_state); - } - - /* 3. Transition vers le jeu */ - if (menu_state.ready_to_play == 1) { - - image_source_t img_src; - tile_t **tiles; - game_state_t game_state; - int num_tiles = menu_state.rows * menu_state.cols; - - /* Préparation des données et initialisation du moteur de jeu */ - img_src = get_image_source(menu_state.selected_image); - tiles = images_slice(img_src, menu_state.rows, menu_state.cols); - game_init(&game_state, menu_state.rows, menu_state.cols, tiles); - - /* Mélange le plateau */ - game_shuffle_safe(&game_state, 500); - - printf("DEBUG: Jeu prêt. Grille %d x %d melangee. Lancement de la boucle de jeu...\n", - game_state.rows, game_state.cols); - -<<<<<<< HEAD - /* Lancement de la BOUCLE DE JEU */ - game_loop(&game_state); -======= - /* TODO: Boucle de JEU (GRANDE PARTIE 3) */ - game_loop(&game_state); ->>>>>>> 35d0b2d664efc5214a4ffbfd165dbee45dba3a2c - - /* Nettoyage final (après que le joueur a fini de jouer) */ - images_free_tiles(tiles, num_tiles); - game_free(&game_state); - } - FermerGraphique(); return EXIT_SUCCESS; } diff --git a/src/menu_view.h b/src/menu_view.h index 3d34f75..cbead52 100644 --- a/src/menu_view.h +++ b/src/menu_view.h @@ -1,6 +1,4 @@ -/* src/menu_view.h - * Définition de l'état du menu et des prototypes pour le module de configuration. - */ +/* src/menu_view.h */ #ifndef MENU_VIEW_H #define MENU_VIEW_H @@ -15,7 +13,7 @@ typedef struct { int rows; /* Nombre de lignes (3 à 8) */ int cols; /* Nombre de colonnes (3 à 8) */ int ready_to_play; /* 1 si le joueur a validé, -1 si demande de quitter */ -} menu_state_t; +} menu_state_t; /* <--- POINT-VIRGULE CORRECT */ /* Prototypes des fonctions publiques */ void menu_init(menu_state_t *state); diff --git a/taquin b/taquin index ed640ef..b161afa 100755 Binary files a/taquin and b/taquin differ