Partage
  • Partager sur Facebook
  • Partager sur Twitter

zDemineur

Exercice pour débutants

    13 mars 2012 à 14:06:06

    <= Retourner à la liste des exercices

    Mois : Mars
    Sujet : Tableaux et aléatoire

    zDemineur


    Compétences minimales requises : Partie 2 : [Théorie] Techniques avancées

    Pour continuer, voici un petit topic d'exercice : le démineur !
    Ce jeu va générer un terrain miné (>0 : sur, -1 : mine) et va demander au joueur de le déminer.

    Lorsqu'un joueur découvre une case non piégée, si aucune mine n'est à côté, les cases autour sont découvertes, sinon, la case indique le nombre de mines à côté (diagonales et côtés)

    On joue tant que l'on a pas marqué toutes les mines et tant que nous avons pas découvert une case minée.

    Les niveaux du topic vous proposent de créer le jeu par étape

    Niveau 1 : Generation et affichage d'une grille



    Notion mise à l'épreuve : Les tableaux et l'aléatoire en C

    Vous allez fixer le nombre de cases maximales en hauteur et largeur.
    Le programme va devoir générer la grille en demandant à l'utilisateur :
    • La hauteur de la grille
    • La largeur de la grille
    • Le nombre de mines

    Ici : on ne joue pas, on va juste afficher la grille.

    Hint : Vous pouvez inscrire directement dans le tableau le nombre de mines aux alentours.

    le plus : Vous pouvez allouer dynamiquement le tableau (et donc enlever le maximum)
    (Notion + : l'allocation dynamique)

    le plus plus : Vous pouvez ajouter de la couleur, pour rendre plus classe
    (Notion ++ : la gestion de la console et du terminal en C, et les macros pour rendre votre code portable)

    Voici un exemple d'execution :
    ** zDemineur (niveau 1) **
    
    Ce programme génére une grille de démineur !
    
    Paramètres :
        - lignes   : 6
        - colonnes : 8
        - mines    : 4
    
    Grille :
    
        +---+---+---+---+---+---+---+---+
        |   |   | 1 | 1 | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
        |   |   | 1 | x | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
        | 1 | 1 | 1 | 2 | 2 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
        | x | 2 | 1 | 1 | x | 1 |   |   |
        +---+---+---+---+---+---+---+---+
        | 2 | x | 1 | 1 | 1 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
        | 1 | 1 | 1 |   |   |   |   |   |
        +---+---+---+---+---+---+---+---+


    Niveau 2 : Le jeu



    Objet mis à l'épreuve : votre cerveau

    Ce niveau vous propose de créer le jeu en soi :
    Le plateau est caché, le jeu vous propose d'entrer des coordonées et demande si vous voulez découvrir ou marquer la case correspondante.

    Hint : Vous pouvez tricher pour débugger !

    Le plus : Vous pouvez gérer le temps de choix
    (Notion + : La gestion du temps en C)

    Le plus plus : Au lieu de demander, vous pouvez gerer le clavier afin de se déplacer sur la grille et choisir
    (Notion ++ : La gestion de la console et du terminal; et les macros pour rendre portable votre code)

    ** zDemineur (niveau 2) **
    
    Regles : Vous voila en face d'un terrain qu'il vous faut déminer.
             Pour ce faire, vous allez devoir poser des drapeaux sur chaque mine.
             Chaque case découverte vous indiquant le nombre de mines adjacentes.
             Si vous tentez de découvrir une case minée, vous perdez.
    
    Paramètres :
        - lignes   : 6
        - colonnes : 8
        - mines    : 4
    
    Grille (débug) :
    
        +---+---+---+---+---+---+---+---+
        |   |   | 1 | 1 | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
        |   |   | 1 | x | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
        | 1 | 1 | 1 | 2 | 2 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
        | x | 2 | 1 | 1 | x | 1 |   |   |
        +---+---+---+---+---+---+---+---+
        | 2 | x | 1 | 1 | 1 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
        | 1 | 1 | 1 |   |   |   |   |   |
        +---+---+---+---+---+---+---+---+
    _________________________________________________
    
    Grille :
    
          1   2   3   4   5   6   7   8
        +---+---+---+---+---+---+---+---+
      1 | ? | ? | ? | ? | ? | ? | ? | ? |
        +---+---+---+---+---+---+---+---+
      2 | ? | ? | ? | ? | ? | ? | ? | ? |
        +---+---+---+---+---+---+---+---+
      3 | ? | ? | ? | ? | ? | ? | ? | ? |
        +---+---+---+---+---+---+---+---+
      4 | ? | ? | ? | ? | ? | ? | ? | ? |
        +---+---+---+---+---+---+---+---+
      5 | ? | ? | ? | ? | ? | ? | ? | ? |
        +---+---+---+---+---+---+---+---+
      6 | ? | ? | ? | ? | ? | ? | ? | ? |
        +---+---+---+---+---+---+---+---+
    
    Il devrait rester 4/4 mines.
    
    Que faire :
        - (0) Abandonner
        - (1) Poser un drapeau
        - (2) Découvrir une case
        
    Choix : 2
    
    Quelle case :
        - x : 8
        - y : 6
    _________________________________________________
    
    Grille :
    
          1   2   3   4   5   6   7   8
        +---+---+---+---+---+---+---+---+
      1 | ? | ? | ? | ? | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
      2 | ? | ? | ? | ? | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
      3 | ? | ? | ? | ? | 2 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
      4 | ? | ? | ? | ? | ? | 1 |   |   |
        +---+---+---+---+---+---+---+---+
      5 | ? | ? | 1 | 1 | 1 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
      6 | ? | ? | 1 |   |   |   |   |   |
        +---+---+---+---+---+---+---+---+
    
    Il devrait rester 4/4 mines.
    
    Que faire :
        - (0) Abandonner
        - (1) Poser un drapeau
        - (2) Découvrir une case
        
    Choix : 1
    
    Quelle case :
        - x : 5
        - y : 4
    _________________________________________________
    
    Grille :
    
          1   2   3   4   5   6   7   8
        +---+---+---+---+---+---+---+---+
      1 | ? | ? | ? | ? | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
      2 | ? | ? | ? | ? | 1 |   |   |   |
        +---+---+---+---+---+---+---+---+
      3 | ? | ? | ? | ? | 2 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
      4 | ? | ? | ? | ? | P | 1 |   |   |
        +---+---+---+---+---+---+---+---+
      5 | ? | ? | 1 | 1 | 1 | 1 |   |   |
        +---+---+---+---+---+---+---+---+
      6 | ? | ? | 1 |   |   |   |   |   |
        +---+---+---+---+---+---+---+---+
    
    Il devrait rester 3/4 mines.
    
    Que faire :
        - (0) Abandonner
        - (1) Poser un drapeau
        - (2) Découvrir une case
        
    Choix : 0



    Niveau 3 : la sauvegarde



    Notion mise à l'épreuve : La gestion des fichiers en C

    Il s'agit là d'ajouter au jeu un moyen de sauvegarder une partie et de la recharger à tout moment.

    Exemple :
    6 8
     0  0  1  1  1  0  0  0
     0  0  1 -1  1  0  0  0
     1  1  1  2  2  1  0  0
    -1  2  1  1 -1  1  0  0
     2 -1  1  1  1  1  0  0
     1  1  1  0  0  0  0  0
    
     0  0  0  0  1  1  1  1 
     0  0  0  0  1  1  1  1
     0  0  0  0  1  1  1  1
     0  0  0  0  2  1  1  1
     0  0  1  1  1  1  1  1
     0  0  1  1  1  1  1  1

    Le plus : Vous pouvez, au lieu d'y inscrire le contenu de deux tableau, une sorte de format compressé n'indiquant que le strict minimum.
    (Objet + : Votre cerveau)

    Exemple :
    6 8 4 1 1 4 2 1 4 5 1 2 5 8 6 5 4


    Le plus plus : ne pas compresser mais gérer le fichier en binaire
    (Notion ++ : Les fichiers, en mode binaire)

    Exemple :
    00000110 00000100 
    00 00 00 00 10 10 10 10
    00 00 00 01 10 10 10 10
    00 00 00 00 10 10 10 10
    01 00 00 00 11 10 10 10
    00 01 10 10 10 10 10 10
    00 00 10 10 10 10 10 10


    Pour aller plus loin



    Vous pouvez utiliser la SDL pour rendre le jeu un peu plus beau.
    (Vous pourrez alors vous amuser à faire des animations, si vous le voulez;
    Jouer des sons, et inscrire le score (temps))

    Bonne chance à tous ! :)

    (Edit : ajout du plus plus du niveau 3)
    • Partager sur Facebook
    • Partager sur Twitter
    perror(const char * str); will save your life !
      13 mars 2012 à 14:28:13

      :) c'est un concours que tu nous propose la ? :)
      • Partager sur Facebook
      • Partager sur Twitter
        13 mars 2012 à 14:31:20

        Bonjour,

        Non, c'est un (très bon) exercice.
        Je l'avais fait sur un TI-82, y'avais même pas de tableau, 26 variable max a disposition ...
        Que de souvenir :')

        Cordialement.
        • Partager sur Facebook
        • Partager sur Twitter
          13 mars 2012 à 15:46:27

          Non (pour un concours j'aurais mis un truc plus compliqué XD)

          Bien sûr, les "plus" sont assez sympas pour ceux qui viennent plus ici pour aider ^^

          Juste un exercice pour débutants, pour le topic de paraze

          Edit : grilled (prof ^^).
          La TI 82 contient des listes, moi aussi je codais dessus en maths :p
          • Partager sur Facebook
          • Partager sur Twitter
          perror(const char * str); will save your life !
            13 mars 2012 à 16:02:53

            Des liste ?
            J'avais utiliser les matrice, mais ca avait la facheuse habitude de defoncer celle utiliser par le jeu sans retour possible des valeurs (enfin, a moins de faire encore plein de developpement).
            Par contre, c'était en philosophie/Français que je codais :x (les p'tit jeune, prenez pas exemple de ça !)

            Bon, on va finir le petit HS, sinon j'ai pas finit d'en parler. En tous cas, c'est largement faisable et assez fendar a faire ;)

            J’espère que cet exo aura vent en poupe.

            Bon courage a tous.

            edit : omg ! prennait -> prenez
            qT_Tp
            • Partager sur Facebook
            • Partager sur Twitter
              13 mars 2012 à 17:02:35

              Merci pour cet exo !

              Cet un excellent exercice je trouve.

              Citation

              (les p'tit jeune, prennait pas exemple de ça !)


              Bien sûr. :lol:
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                13 mars 2012 à 18:17:50

                super un nouvel exercice je finis zArithmetic niveau 4 et j'arrive :D
                • Partager sur Facebook
                • Partager sur Twitter
                  13 mars 2012 à 22:25:20

                  Reste des fautes :p

                  Des listes ?
                  J'avais utilisér les matrices, mais ça avait la fâcheuse habitude de défoncer celle utilisée par le jeu sans retour possible des valeurs (enfin, à moins de faire encore plein de développements).
                  Par contre, c'était en philosophie/Français que je codais :x (les p'tits jeunes, prenez pas exemple de ça !)

                  Bon, on va finir le petit HS, sinon j'ai pas finit d'en parler. En tous cas, c'est largement faisable et assez fendar à faire ;)

                  J’espère que cet exo aura vent en poupe.

                  Bon courage a tous.


                  Bon, pour ma part : niveau 1 fini :)
                  Je vais ajouter la couleur ^^
                  • Partager sur Facebook
                  • Partager sur Twitter
                  perror(const char * str); will save your life !
                    14 mars 2012 à 9:04:55

                    J'aime pas trop les « plus plus » en général. On n'arrivera jamais à un truc 100% portable avec des compilations conditionnelles.

                    Citation

                    J'avais utiliser les matrice, mais ca avait la facheuse habitude de defoncer celle utiliser par le jeu sans retour possible des valeurs (enfin, a moins de faire encore plein de developpement).
                    Par contre, c'était en philosophie/Français que je codais :x (les p'tit jeune, prenez pas exemple de ça !)



                    Tiens, je ne me sens plus seul. :-°

                    Bon, vu que personne n'a posté de code pour le moment, je poste le mien pour le niveau 1 (sans le « plus plus ») :

                    grid.c :


                    #include <stdio.h>
                    #include <stdlib.h>
                    #include "grid.h"
                    
                    /* ----- Gère les voisins ----- */
                    static void countNeighbours (grid_s * p_grid, int x, int y)
                    {
                       if (y > 0 && p_grid->pp_grid[y - 1][x].value != -1)
                          ++p_grid->pp_grid[y - 1][x].value;
                       if (y > 0 && x > 0 && p_grid->pp_grid[y - 1][x - 1].value != -1)
                          ++p_grid->pp_grid[y - 1][x - 1].value;
                       if (y > 0 && x < p_grid->width - 1
                           && p_grid->pp_grid[y - 1][x + 1].value != -1)
                          ++p_grid->pp_grid[y - 1][x + 1].value;
                       if (x > 0 && p_grid->pp_grid[y][x - 1].value != -1)
                          ++p_grid->pp_grid[y][x - 1].value;
                       if (x > 0 && y < p_grid->hight - 1
                           && p_grid->pp_grid[y + 1][x - 1].value != -1)
                          ++p_grid->pp_grid[y + 1][x - 1].value;
                       if (x < p_grid->width - 1 && p_grid->pp_grid[y][x + 1].value != -1)
                          ++p_grid->pp_grid[y][x + 1].value;
                       if (x < p_grid->width - 1 && y < p_grid->hight - 1
                           && p_grid->pp_grid[y + 1][x + 1].value != -1)
                          ++p_grid->pp_grid[y + 1][x + 1].value;
                       if (y < p_grid->hight - 1 && p_grid->pp_grid[y + 1][x].value != -1)
                          ++p_grid->pp_grid[y + 1][x].value;
                    }
                    
                    /* ----- Affiche une ligne pour la grille ----- */
                    static void printLine (unsigned int width)
                    {
                       printf ("\n    ");
                       for (unsigned int i = 0; i < width; ++i)
                          printf ("+---");
                       putchar ('+');
                    }
                    
                    /* ----- Génère une grille ----- */
                    grid_s *generateGrid (void)
                    {
                       grid_s *p_grid = malloc (sizeof *p_grid);
                    
                       if (p_grid == NULL)
                          goto error;
                    
                       printf ("Paramètres :\n\t- lignes : ");
                       scanf ("%u", &p_grid->hight);
                       printf ("\t- colonnes : ");
                       scanf ("%u", &p_grid->width);
                       printf ("\t- mines : ");
                       scanf ("%u", &p_grid->mines);
                    
                       p_grid->pp_grid = malloc (sizeof *p_grid->pp_grid * p_grid->hight);
                    
                       if (p_grid->pp_grid == NULL)
                          goto error;
                    
                       for (unsigned int i = 0; i < p_grid->hight; ++i)
                       {
                          p_grid->pp_grid[i] =
                             malloc (sizeof *p_grid->pp_grid[i] * p_grid->width);
                    
                          if (p_grid->pp_grid[i] == NULL)
                             goto error;
                    
                          for (unsigned int j = 0; j < p_grid->width; ++j)
                          {
                    #ifdef DEBUG
                             p_grid->pp_grid[i][j].isVisible = VISIBLE;
                    #else
                             p_grid->pp_grid[i][j].isVisible = HIDE;
                    #endif
                             p_grid->pp_grid[i][j].value = 0;
                          }
                       }
                    
                       for (unsigned int i = 0; i < p_grid->mines; ++i)
                       {
                          int x = rand () % p_grid->width;
                          int y = rand () % p_grid->hight;
                    
                          if (p_grid->pp_grid[y][x].value != -1)
                          {
                             p_grid->pp_grid[y][x].value = -1;
                             countNeighbours (p_grid, x, y);
                          }
                          else
                             --i;
                       }
                    
                       return p_grid;
                    
                     error:
                       deleteGrid (&p_grid);
                       return NULL;
                    }
                    
                    /* ----- Détruit une grille ----- */
                    void deleteGrid (grid_s ** pp_grid)
                    {
                       if (pp_grid != NULL)
                       {
                          for (unsigned int i = 0; i < (*pp_grid)->hight; ++i)
                             free ((*pp_grid)->pp_grid[i]);
                          free ((*pp_grid)->pp_grid);
                          free (*pp_grid);
                       }
                    }
                    
                    /* ----- Affiche une grille ----- */
                    void printGrid (grid_s * p_grid)
                    {
                       if (p_grid != NULL && p_grid->pp_grid != NULL)
                       {
                          printf ("\n   ");
                          for (unsigned int i = 1; i <= p_grid->width; ++i)
                             printf ("   %d", i);
                          printLine (p_grid->width);
                          for (unsigned int i = 0; i < p_grid->hight; ++i)
                          {
                             printf (i < 9 ? "\n  %d | " : "\n %d | ", i + 1);
                             for (unsigned int j = 0; j < p_grid->width; ++j)
                             {
                                if (p_grid->pp_grid[i][j].isVisible == VISIBLE)
                                   switch (p_grid->pp_grid[i][j].value)
                                   {
                                   case -1:
                                      putchar ('x');
                                      break;
                                   case 0:
                                      putchar (' ');
                                      break;
                                   default:
                                      printf ("%d", p_grid->pp_grid[i][j].value);
                                      break;
                                   }
                                else
                                   putchar ('?');
                                printf (" | ");
                             }
                             printLine (p_grid->width);
                          }
                       }
                    }
                    


                    grid.h :

                    #ifndef H_LP_GRID_20120314134737
                    #define H_LP_GRID_20120314134737
                    
                    typedef enum
                    {
                       VISIBLE,
                       HIDE
                    } visible_e;
                    
                    typedef struct
                    {
                       visible_e isVisible;
                       int value;
                    } case_s;
                    
                    typedef struct
                    {
                       unsigned int hight;
                       unsigned int width;
                       unsigned int mines;
                       case_s **pp_grid;
                    } grid_s;
                    
                    grid_s *generateGrid (void);
                    void deleteGrid (grid_s ** pp_grid);
                    void printGrid (grid_s * p_grid);
                    
                    #endif
                    


                    Et un main.c pour le test :


                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <time.h>
                    #include "grid.h"
                    
                    int main (void)
                    {
                       srand (time (NULL));
                       grid_s *p = generateGrid ();
                       printGrid (p);
                       deleteGrid (&p);
                       return 0;
                    }
                    
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Staff désormais retraité.
                      14 mars 2012 à 15:34:52

                      Voici mon code pour le niveau 1 :

                      #include <stdio.h>
                      #include <stdlib.h>
                      #include <time.h>
                      
                      #define VIDE 0
                      #define BOMBE -1
                      
                      typedef struct
                      {
                          int **tab;
                          int larg;
                          int haut;
                          int nb_mine;
                      }Dem; /*Structure du Demineur*/
                      
                      void init(Dem *dem);
                      void options(Dem *dem);
                      int get_param(const char *s);
                      void affiche(Dem *dem);
                      void generer_tab(Dem *dem);
                      void cases(Dem *dem, int x, int y);
                      void liberer(Dem *dem);
                      
                      int main(void)
                      {
                          Dem dem;
                      
                          srand((unsigned int)time(NULL));
                      
                          printf("** zDemineur (niveau 1) **\n\n");
                          printf("Ce programme genere une grille de demineur !\n\n");
                      
                          init(&dem);
                          options(&dem);
                          generer_tab(&dem);
                          affiche(&dem);
                          liberer(&dem);
                      
                          return EXIT_SUCCESS;
                      }
                      
                      void init(Dem *dem)
                      {
                          dem->larg = 0;
                          dem->haut = 0;
                          dem->nb_mine = 0;
                          dem->tab = NULL;
                      }
                      
                      void liberer(Dem *dem)
                      {
                          int i;
                      
                          /*Liberation du tablea 2D*/
                          for (i = 0; i < dem->larg; i++)
                          {
                              free(dem->tab[i]);
                              dem->tab[i] = NULL;
                          }
                      
                          free(dem->tab);
                      
                          dem->tab = NULL;
                      }
                      
                      void options(Dem *dem)
                      {
                          int i;
                      
                          printf("Parametres :\n");
                          dem->larg = get_param("lignes");
                          dem->haut = get_param("colonnes");
                      
                          do
                          {
                              dem->nb_mine = get_param("mine");
                          }while(dem->nb_mine > dem->larg * dem->haut);
                      
                          /*Allocation dynamique d'un tableau 2D*/
                          dem->tab = malloc((size_t)dem->larg * sizeof(*dem->tab));
                          
                          if(dem->tab == NULL)    
                          {
                              printf("Erreur malloc !");
                              exit(EXIT_FAILURE);
                          }
                      
                          for(i = 0; i < dem->larg; i++)
                          {
                              dem->tab[i] = malloc((size_t)dem->haut * sizeof(*dem->tab[i]));
                              
                              if(dem->tab[i] == NULL)
                              {
                                  printf("Erreur malloc !");
                                  exit(EXIT_FAILURE);
                              }
                          } 
                      }
                      
                      /*Economise quelques lignes en verifiant vite-fait l'entree*/
                      int get_param(const char *s)
                      {
                          int n = 0;
                      
                          do
                          {
                              printf("\t --> %s : ", s);
                              scanf("%d", &n);
                          }while(n <= 0);
                      
                          return n;
                      }
                      
                      void generer_tab(Dem *dem)
                      {
                          int x, y;
                          int booleen = 1;
                          int i, j;
                      
                          /*On le replit de "VIDE"*/
                          for(i = 0; i < dem->larg; i++)
                          {
                              for(j = 0; j < dem->haut; j++)
                              {
                                  dem->tab[i][j] = VIDE;
                              }
                          }
                          
                          /*On ajoute les bombes*/
                          for(i = 0; i < dem->nb_mine; i++)
                          {
                              do
                              {
                                  booleen = 1;
                      
                                  x = rand() % dem->larg;
                                  y = rand() % dem->haut;
                                  if(dem->tab[x][y] != VIDE)
                                  {
                                      booleen = 0;
                                  }
                      
                                  else
                                  {
                                      dem->tab[x][y] = BOMBE;
                                  }
                              }while(!booleen);
                      
                              /*Le tout en comptant les cases voisines*/
                              cases(dem, x, y);
                           }
                      
                      
                      }
                      
                      /*Compte les cases voisines*/
                      void cases(Dem *dem, int x, int y)
                      {
                          if(x + 1 < dem->larg && dem->tab[x + 1][y] != BOMBE)
                             dem->tab[x + 1][y]++;
                          if(x - 1 >= 0 && dem->tab[x - 1][y] != BOMBE)
                             dem->tab[x - 1][y]++;
                          if(y + 1 < dem->haut && dem->tab[x][y + 1] != BOMBE)
                             dem->tab[x][y + 1]++;
                          if(y - 1 >= 0 && dem->tab[x][y - 1] != BOMBE)
                             dem->tab[x][y - 1]++;
                          if(x + 1 < dem->larg && y + 1 < dem->haut &&
                             dem->tab[x + 1][y + 1] != BOMBE)
                             dem->tab[x + 1][y + 1]++;
                          if(x - 1 >= 0 && y - 1 >= 0 && dem->tab[x - 1][y - 1] != BOMBE)
                             dem->tab[x - 1][y - 1]++;
                          if(x + 1 < dem->larg && y - 1 >= 0 && dem->tab[x + 1][y - 1] != BOMBE)
                             dem->tab[x + 1][y - 1]++;
                          if(x - 1 >= 0 && y + 1 < dem->haut && dem->tab[x - 1][y + 1] != BOMBE)
                             dem->tab[x - 1][y + 1]++;
                      }
                      
                      void affiche(Dem *dem)
                      {
                          int i, j;
                      
                          for(i = 0; i < dem->larg; i++)
                          {
                              for(j = 0; j < dem->haut; j++)
                              {
                                  if(dem->tab[i][j] == VIDE)
                                      printf("-  ");
                                  else if(dem->tab[i][j] == BOMBE)
                                      printf("X  ");
                                  else
                                      printf("%d  ", dem->tab[i][j]);
                              }
                      
                              printf("\n\n");
                          }
                      }
                      



                      @lucas-84 : Ah le C99...

                      grid.c: In function 'countNeighbours':
                      grid.c:12:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                      grid.c:17:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                      grid.c:20:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                      grid.c:22:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                      grid.c:22:35: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                      grid.c:25:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
                      grid.c: In function 'generateGrid':
                      grid.c:79:20: warning: conversion to 'unsigned int' from 'int' may change the sign of the result [-Wsign-conversion]
                      grid.c:79:23: warning: conversion to 'int' from 'unsigned int' may change the sign of the result [-Wsign-conversion]
                      grid.c:80:20: warning: conversion to 'unsigned int' from 'int' may change the sign of the result [-Wsign-conversion]
                      grid.c:80:23: warning: conversion to 'int' from 'unsigned int' may change the sign of the result [-Wsign-conversion]
                      
                      main.c: In function 'main':
                      main.c:8:16: warning: conversion to 'unsigned int' from 'time_t' may alter its value [-Wconversion]


                      Sinon c'est un très belle présentation que tu nous a fait là. :p

                      Moi, ça donne ceci :

                      1  2  1  1  -  
                      
                      X  2  X  1  -  
                      
                      1  2  1  1  -  
                      
                      1  1  -  -  -  
                      
                      X  1  -  -  -
                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 mars 2012 à 15:38:37

                        Attend t'as pas encore vu avec les couleurs. :p (si il y a un windowsien parmi nous, pourrait-t-il confirmer que cela marche chez lui, vu que j'ai fait au feeling là...)

                        Bon j'ai corrigé tes warnings normalement.


                        main.c

                        #include <stdio.h>
                        #include <stdlib.h>
                        #include <time.h>
                        #include "grid.h"
                        #include "color.h"
                        
                        int main (void)
                        {
                           grid_s *p;
                           srand ((unsigned int) time (NULL));
                           clear ();
                           puts ("** zDemineur (niveau 2) **\nRegles : Vous voila en face d'un terrain"
                                 " qu'il vous faut déminer. Pour ce faire, vous allez devoir poser des"
                                 " drapeaux sur chaque mine. Chaque case découverte vous indiquant le "
                                 "nombre de mines adjacentes. Si vous tentez de découvrir une case min"
                                 "ée, vous perdez.");
                           p = generateGrid ();
                           printGrid (p);
                           deleteGrid (&p);
                           return 0;
                        }
                        


                        grid.c

                        #include <stdio.h>
                        #include <stdlib.h>
                        #include "color.h"
                        #include "grid.h"
                        
                        /* ----- Gère les voisins ----- */
                        static void countNeighbours (grid_s * p_grid, int x, int y)
                        {
                           if (y > 0 && p_grid->pp_grid[y - 1][x].value != -1)
                              ++p_grid->pp_grid[y - 1][x].value;
                           if (y > 0 && x > 0 && p_grid->pp_grid[y - 1][x - 1].value != -1)
                              ++p_grid->pp_grid[y - 1][x - 1].value;
                           if (y > 0 && x < p_grid->width - 1
                               && p_grid->pp_grid[y - 1][x + 1].value != -1)
                              ++p_grid->pp_grid[y - 1][x + 1].value;
                           if (x > 0 && p_grid->pp_grid[y][x - 1].value != -1)
                              ++p_grid->pp_grid[y][x - 1].value;
                           if (x > 0 && y < p_grid->hight - 1
                               && p_grid->pp_grid[y + 1][x - 1].value != -1)
                              ++p_grid->pp_grid[y + 1][x - 1].value;
                           if (x < p_grid->width - 1 && p_grid->pp_grid[y][x + 1].value != -1)
                              ++p_grid->pp_grid[y][x + 1].value;
                           if (x < p_grid->width - 1 && y < p_grid->hight - 1
                               && p_grid->pp_grid[y + 1][x + 1].value != -1)
                              ++p_grid->pp_grid[y + 1][x + 1].value;
                           if (y < p_grid->hight - 1 && p_grid->pp_grid[y + 1][x].value != -1)
                              ++p_grid->pp_grid[y + 1][x].value;
                        }
                        
                        /* ----- Affiche une ligne pour la grille ----- */
                        static void printLine (int width)
                        {
                           printf ("\n    ");
                           for (int i = 0; i < width; ++i)
                              printf ("+---");
                           putchar ('+');
                        }
                        
                        /* ----- Génère une grille ----- */
                        grid_s *generateGrid (void)
                        {
                           grid_s *p_grid = malloc (sizeof *p_grid);
                        
                           if (p_grid == NULL)
                              goto error;
                        
                           printf ("Paramètres :\n\t- lignes : ");
                           scanf ("%u", &p_grid->hight);
                           printf ("\t- colonnes : ");
                           scanf ("%u", &p_grid->width);
                           printf ("\t- mines : ");
                           scanf ("%u", &p_grid->mines);
                        
                           p_grid->pp_grid = malloc (sizeof *p_grid->pp_grid * (size_t) p_grid->hight);
                        
                           if (p_grid->pp_grid == NULL)
                              goto error;
                        
                           for (int i = 0; i < p_grid->hight; ++i)
                           {
                              p_grid->pp_grid[i] =
                                 malloc (sizeof *p_grid->pp_grid[i] * (size_t) p_grid->width);
                        
                              if (p_grid->pp_grid[i] == NULL)
                                 goto error;
                        
                              for (int j = 0; j < p_grid->width; ++j)
                              {
                        #ifdef DEBUG
                                 p_grid->pp_grid[i][j].isVisible = VISIBLE;
                        #else
                                 p_grid->pp_grid[i][j].isVisible = HIDE;
                        #endif
                                 p_grid->pp_grid[i][j].value = 0;
                              }
                           }
                        
                           for (int i = 0; i < p_grid->mines; ++i)
                           {
                              int x = rand () % p_grid->width;
                              int y = rand () % p_grid->hight;
                        
                              if (p_grid->pp_grid[y][x].value != -1)
                              {
                                 p_grid->pp_grid[y][x].value = -1;
                                 countNeighbours (p_grid, x, y);
                              }
                              else
                                 --i;
                           }
                        
                           return p_grid;
                        
                         error:
                           deleteGrid (&p_grid);
                           return NULL;
                        }
                        
                        /* ----- Détruit une grille ----- */
                        void deleteGrid (grid_s ** pp_grid)
                        {
                           if (pp_grid != NULL)
                           {
                              for (int i = 0; i < (*pp_grid)->hight; ++i)
                                 free ((*pp_grid)->pp_grid[i]);
                              free ((*pp_grid)->pp_grid);
                              free (*pp_grid);
                           }
                        }
                        
                        /* ----- Affiche une grille ----- */
                        void printGrid (grid_s * p_grid)
                        {
                           if (p_grid != NULL && p_grid->pp_grid != NULL)
                           {
                              putchar('\n');
                              color (GREEN_FG, WHITE_BG);
                              printf ("     ");
                              for (int i = 1; i <= p_grid->width; ++i)
                                 printf (" %d  ", i);
                              color (BLACK_FG, WHITE_BG);
                              printLine (p_grid->width);
                              for (int i = 0; i < p_grid->hight; ++i)
                              {
                                 color (GREEN_FG, WHITE_BG);
                                 printf (i < 9 ? "\n  %d" : "\n %d", i + 1);
                                 color (BLACK_FG, WHITE_BG);
                                 printf (" |");
                                 for (int j = 0; j < p_grid->width; ++j)
                                 {
                                    if (p_grid->pp_grid[i][j].isVisible == VISIBLE)
                                       switch (p_grid->pp_grid[i][j].value)
                                       {
                                       case -1:
                                          color (BLACK_FG, RED_BG);
                                          printf (" x ");
                                          break;
                                       case 0:
                                          printf ("   ");
                                          break;
                                       default:
                                          if (p_grid->pp_grid[i][j].value == 1)
                                             color (YELLOW_FG, WHITE_BG);
                                          else if (p_grid->pp_grid[i][j].value == 2)
                                             color (CYAN_FG, WHITE_BG);
                                          else
                                             color (BLUE_FG, WHITE_BG);
                                          printf (" %d ", p_grid->pp_grid[i][j].value);
                                          break;
                                       }
                                    else
                                    {
                                       color (WHITE_FG, WHITE_BG);
                                       printf (" ? ");
                                    }
                                    color (BLACK_FG, WHITE_BG);
                                    printf ("|");
                                 }
                                 printLine (p_grid->width);
                              }
                           }
                           putchar('\n');
                           color (DEFAULT, DEFAULT);
                        }
                        


                        grid.h

                        #ifndef H_LP_GRID_20120314134737
                        #define H_LP_GRID_20120314134737
                        
                        typedef enum
                        {
                           VISIBLE,
                           HIDE
                        } visible_e;
                        
                        typedef struct
                        {
                           visible_e isVisible;
                           int value;
                        } case_s;
                        
                        typedef struct
                        {
                           int hight;
                           int width;
                           int mines;
                           case_s **pp_grid;
                        } grid_s;
                        
                        grid_s *generateGrid (void);
                        void deleteGrid (grid_s ** pp_grid);
                        void printGrid (grid_s * p_grid);
                        
                        #endif
                        


                        Oui, je n'ai aucun goût en ce qui concerne les couleurs.
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Staff désormais retraité.
                          14 mars 2012 à 15:49:23

                          Où est le fichier "color.h" ? ^^
                          • Partager sur Facebook
                          • Partager sur Twitter
                            14 mars 2012 à 15:50:12

                            Oups. :p

                            #ifndef H_LP_COLOR_20120314142325
                            #define H_LP_COLOR_20120314142325
                            
                            #include <stdlib.h>
                            
                            #ifdef _WIN32
                            #define BLACK_FG   '0'
                            #define BLUE_FG    '1'
                            #define GREEN_FG   'A'
                            #define CYAN_FG    'B'
                            #define RED_FG	   'C'
                            #define YELLOW_FG  'E'
                            #define WHITE_FG   'F'
                            #define BLACK_BG   BLACK_FG
                            #define BLUE_BG    BLUE_BG
                            #define GREEN_BG   GREEN_BG
                            #define CYAN_BG    CYAN_BG
                            #define RED_BG	   RED_BG
                            #define YELLOW_BG  YELLOW_BG
                            #define WHITE_BG   WHITE_BG
                            #else
                            #define DEFAULT    "0"
                            #define BLACK_FG   "30"
                            #define RED_FG     "31"
                            #define GREEN_FG   "32"
                            #define YELLOW_FG  "33"
                            #define BLUE_FG    "34"
                            #define CYAN_FG    "36"
                            #define WHITE_FG   "37"
                            #define BLACK_BG   "40"
                            #define RED_BG     "41"
                            #define GREEN_BG   "42"
                            #define YELLOW_BG  "43"
                            #define BLUE_BG    "44"
                            #define CYAN_BG    "46"
                            #define WHITE_BG   "47"
                            #endif
                            
                            #ifdef _WIN32
                            #define color(a, b) system ("color %c%c", (a), (b))
                            #define clear()     system ("cls")
                            #else
                            #include <stdio.h>
                            #define color(a, b) printf ("\033[%s;%sm", (a), (b))
                            #define clear()     system ("clear")
                            #endif
                            
                            #endif
                            


                            Edit : en fait ça ne compilera même pas sous Windows, car default ne sera pas déclaré. Faut que je revois ça.
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Staff désormais retraité.
                              14 mars 2012 à 15:53:51

                              Woua... c'est moche (désolé). ×D

                              Mais bon franchement, on s'en fiche un peu.
                              Sinon, enlève toutes les couleurs de fond (le surlignage quoi).
                              • Partager sur Facebook
                              • Partager sur Twitter
                                14 mars 2012 à 18:49:05

                                @lucas-84: Vive les balises <secret> </secret> !
                                • Partager sur Facebook
                                • Partager sur Twitter

                                🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles  - ♡ Copying is an act of love.

                                  14 mars 2012 à 18:53:26

                                  Tu l'auras voulu. :p

                                  main.c

                                  #include <stdio.h>
                                  #include <stdlib.h>
                                  #include <time.h>
                                  #include "game.h"
                                  #include "grid.h"
                                  #include "color.h"
                                  
                                  int main (void)
                                  {
                                     grid_s *p_grid;
                                     stats_s *p_stats;
                                     srand ((unsigned int) time (NULL));
                                     clear ();
                                     puts
                                        ("** zDemineur (niveau 2) **\n\nRègles : Vous voilà en face d'un terra"
                                         "in qu'il vous faut déminer. Pour ce faire, vous allez devoir poser d"
                                         "es drapeaux sur chaque mine. Chaque case découverte vous indiquant l"
                                         "e nombre de mines adjacentes. Si vous tentez de découvrir une case m"
                                         "inée, vous perdez.\n\n");
                                     p_grid = generateGrid ();
                                     p_stats = play (p_grid);
                                     if (p_stats->isWinner == WIN)
                                        printf ("Bravo - Vous avez mis %.0f secondes.\n", p_stats->t);
                                     else
                                        printf ("*BOUM* Dommage - Une prochaine fois peut-être ?\n");
                                     deleteGrid (&p_grid);
                                     return EXIT_SUCCESS;;
                                  }
                                  


                                  grid.c

                                  #include <stdio.h>
                                  #include <stdlib.h>
                                  #include "color.h"
                                  #include "game.h"
                                  #include "grid.h"
                                  
                                  /* ----- Gère les voisins ----- */
                                  static void countNeighbours (grid_s * p_grid, int x, int y)
                                  {
                                     if (y > 0 && p_grid->pp_grid[y - 1][x].value != -1)
                                        ++p_grid->pp_grid[y - 1][x].value;
                                     if (y > 0 && x > 0 && p_grid->pp_grid[y - 1][x - 1].value != -1)
                                        ++p_grid->pp_grid[y - 1][x - 1].value;
                                     if (y > 0 && x < p_grid->width - 1
                                         && p_grid->pp_grid[y - 1][x + 1].value != -1)
                                        ++p_grid->pp_grid[y - 1][x + 1].value;
                                     if (x > 0 && p_grid->pp_grid[y][x - 1].value != -1)
                                        ++p_grid->pp_grid[y][x - 1].value;
                                     if (x > 0 && y < p_grid->hight - 1
                                         && p_grid->pp_grid[y + 1][x - 1].value != -1)
                                        ++p_grid->pp_grid[y + 1][x - 1].value;
                                     if (x < p_grid->width - 1 && p_grid->pp_grid[y][x + 1].value != -1)
                                        ++p_grid->pp_grid[y][x + 1].value;
                                     if (x < p_grid->width - 1 && y < p_grid->hight - 1
                                         && p_grid->pp_grid[y + 1][x + 1].value != -1)
                                        ++p_grid->pp_grid[y + 1][x + 1].value;
                                     if (y < p_grid->hight - 1 && p_grid->pp_grid[y + 1][x].value != -1)
                                        ++p_grid->pp_grid[y + 1][x].value;
                                  }
                                  
                                  /* ----- Affiche une ligne pour la grille ----- */
                                  static void printLine (int width)
                                  {
                                     printf ("\n    ");
                                     for (int i = 0; i < width; ++i)
                                        printf ("+---");
                                     putchar ('+');
                                  }
                                  
                                  /* ----- Génère une grille ----- */
                                  grid_s *generateGrid (void)
                                  {
                                     grid_s *p_grid = malloc (sizeof *p_grid);
                                  
                                     if (p_grid == NULL)
                                        goto error;
                                  
                                     printf ("Paramètres :\n\t- lignes : ");
                                     while (scanf ("%u", &p_grid->hight) != 1)
                                        cleanStdin ();
                                     printf ("\t- colonnes : ");
                                     while (scanf ("%u", &p_grid->width) != 1)
                                        cleanStdin ();
                                     printf ("\t- mines : ");
                                     while (scanf ("%u", &p_grid->mines) != 1)
                                        cleanStdin ();
                                  
                                     p_grid->pp_grid =
                                        malloc (sizeof *p_grid->pp_grid * (size_t) p_grid->hight);
                                  
                                     if (p_grid->pp_grid == NULL)
                                        goto error;
                                  
                                     for (int i = 0; i < p_grid->hight; ++i)
                                     {
                                        p_grid->pp_grid[i] =
                                           malloc (sizeof *p_grid->pp_grid[i] * (size_t) p_grid->width);
                                  
                                        if (p_grid->pp_grid[i] == NULL)
                                           goto error;
                                  
                                        for (int j = 0; j < p_grid->width; ++j)
                                        {
                                  #ifdef DEBUG
                                           p_grid->pp_grid[i][j].isVisible = VISIBLE;
                                  #else
                                           p_grid->pp_grid[i][j].isVisible = HIDE;
                                  #endif
                                           p_grid->pp_grid[i][j].value = 0;
                                        }
                                     }
                                  
                                     for (int i = 0; i < p_grid->mines; ++i)
                                     {
                                        int x = rand () % p_grid->width;
                                        int y = rand () % p_grid->hight;
                                  
                                        if (p_grid->pp_grid[y][x].value != -1)
                                        {
                                           p_grid->pp_grid[y][x].value = -1;
                                           countNeighbours (p_grid, x, y);
                                        }
                                        else
                                           --i;
                                     }
                                  
                                     return p_grid;
                                  
                                   error:
                                     deleteGrid (&p_grid);
                                     return NULL;
                                  }
                                  
                                  /* ----- Détruit une grille ----- */
                                  void deleteGrid (grid_s ** pp_grid)
                                  {
                                     if (pp_grid != NULL)
                                     {
                                        for (int i = 0; i < (*pp_grid)->hight; ++i)
                                           free ((*pp_grid)->pp_grid[i]);
                                        free ((*pp_grid)->pp_grid);
                                        free (*pp_grid);
                                     }
                                  }
                                  
                                  /* ----- Affiche une grille ----- */
                                  void printGrid (grid_s * p_grid)
                                  {
                                     if (p_grid != NULL && p_grid->pp_grid != NULL)
                                     {
                                        putchar ('\n');
                                        color (GREEN_FG);
                                        printf ("     ");
                                        for (int i = 1; i <= p_grid->width; ++i)
                                           printf (" %d  ", i);
                                        color (BLACK_FG);
                                        printLine (p_grid->width);
                                        for (int i = 0; i < p_grid->hight; ++i)
                                        {
                                           color (GREEN_FG);
                                           printf (i < 9 ? "\n  %d" : "\n %d", i + 1);
                                           color (BLACK_FG);
                                           printf (" |");
                                           for (int j = 0; j < p_grid->width; ++j)
                                           {
                                              if (p_grid->pp_grid[i][j].isVisible == VISIBLE)
                                                 switch (p_grid->pp_grid[i][j].value)
                                                 {
                                                 case -1:
                                                    color (RED_FG);
                                                    printf (" x ");
                                                    break;
                                                 case 0:
                                                    printf ("   ");
                                                    break;
                                                 default:
                                                    if (p_grid->pp_grid[i][j].value == 1)
                                                       color (YELLOW_FG);
                                                    else if (p_grid->pp_grid[i][j].value == 2)
                                                       color (CYAN_FG);
                                                    else
                                                       color (BLUE_FG);
                                                    printf (" %d ", p_grid->pp_grid[i][j].value);
                                                    break;
                                                 }
                                              else if (p_grid->pp_grid[i][j].isVisible == FLAG)
                                                 printf (" P ");
                                              else
                                              {
                                                 color (WHITE_FG);
                                                 printf (" ? ");
                                              }
                                              color (BLACK_FG);
                                              printf ("|");
                                           }
                                           printLine (p_grid->width);
                                        }
                                     }
                                     putchar ('\n');
                                     color (DEFAULT);
                                  }
                                  


                                  grid.h

                                  #ifndef H_LP_GRID_20120314134737
                                  #define H_LP_GRID_20120314134737
                                  
                                  typedef enum
                                  {
                                     VISIBLE,
                                     HIDE,
                                     FLAG
                                  } visible_e;
                                  
                                  typedef struct
                                  {
                                     visible_e isVisible;
                                     int value;
                                  } case_s;
                                  
                                  typedef struct
                                  {
                                     int hight;
                                     int width;
                                     int mines;
                                     case_s **pp_grid;
                                  } grid_s;
                                  
                                  grid_s *generateGrid (void);
                                  void deleteGrid (grid_s ** pp_grid);
                                  void printGrid (grid_s * p_grid);
                                  
                                  #endif
                                  


                                  game.c

                                  #include <stdio.h>
                                  #include <time.h>
                                  #include "color.h"
                                  #include "game.h"
                                  #include "grid.h"
                                  
                                  /* ----- Demande les coordonnées à l'utilisateur ----- */
                                  static void askCoor (grid_s * p_grid, int *x, int *y)
                                  {
                                     puts ("Quelle case ?");
                                  
                                     do
                                     {
                                        printf ("\t- y : ");
                                        while (scanf ("%d", y) != 1)
                                           cleanStdin ();
                                     }
                                     while (*y < 0 && *y > p_grid->hight);
                                  
                                     do
                                     {
                                        printf ("\t- x : ");
                                        while (scanf ("%d", x) != 1)
                                           cleanStdin ();
                                     }
                                     while (*x < 0 && *x > p_grid->width);
                                  }
                                  
                                  /* ----- Teste la fin du jeu ----- */
                                  static userState_e testWin (grid_s * p_grid, stats_s * p_stats, int mines)
                                  {
                                     userState_e ret = WIN;
                                  
                                     if (p_stats->isWinner == LOST)
                                     {
                                        ret = -1;
                                        goto end;
                                     }
                                  
                                     for (int i = 0; i < p_grid->hight; ++i)
                                     {
                                        for (int j = 0; j < p_grid->width; ++j)
                                        {
                                           if (p_grid->pp_grid[i][j].value == -1
                                               && p_grid->pp_grid[i][j].isVisible != FLAG)
                                           {
                                              ret = NONE;
                                              goto end;
                                           }
                                        }
                                     }
                                  
                                   end:
                                     return ret;
                                  }
                                  
                                  /* ----- Vide le flux d'entrée standard ----- */
                                  void cleanStdin (void)
                                  {
                                     int c;
                                  
                                     while ((c = getchar ()) != '\n' && c != EOF);
                                  }
                                  
                                  /* ----- Fonction de jeu ----- */
                                  stats_s *play (grid_s * p_grid)
                                  {
                                     stats_s *p_stats = malloc (sizeof *p_stats);
                                  
                                     if (p_grid != NULL && p_grid->pp_grid != NULL && p_stats != NULL)
                                     {
                                        time_t t;
                                        int mines = p_grid->mines;
                                        int choice;
                                  
                                        p_stats->isWinner = NONE;
                                  
                                        time (&t);
                                  
                                        do
                                        {
                                           clear ();
                                           printGrid (p_grid);
                                           printf
                                              ("Il devrait rester %d/%d mines.\n\nQue faire :\n\t- (0) Abandonne"
                                               "r\n\t- (1) Poser un drapeau\n\t- (2) Découvrir une case\nChoix :"
                                               " ", mines, p_grid->mines);
                                  
                                           while (scanf ("%d", &choice) != 1)
                                              cleanStdin ();
                                  
                                           if (choice == 1 || choice == 2)
                                           {
                                              int x, y;
                                              askCoor (p_grid, &x, &y);
                                  
                                              if (choice == 1)
                                              {
                                                 p_grid->pp_grid[y - 1][x - 1].isVisible = FLAG;
                                                 --mines;
                                              }
                                              else
                                              {
                                                 if (p_grid->pp_grid[y - 1][x - 1].value == -1)
                                                    p_stats->isWinner = LOST;
                                                 p_grid->pp_grid[y - 1][x - 1].isVisible = VISIBLE;
                                              }
                                           }
                                           p_stats->isWinner = testWin (p_grid, p_stats, mines);
                                        }
                                        while (choice != 0 && p_stats->isWinner == NONE);
                                  
                                        clear ();
                                        printGrid (p_grid);
                                  
                                        p_stats->t = difftime (time (NULL), t);
                                     }
                                  
                                     return p_stats;
                                  
                                  error:
                                     free (p_stats);
                                     return NULL;
                                  }
                                  


                                  game.h

                                  #ifndef H_LP_GAME_20120314155754
                                  #define H_LP_GAME_20120314155754
                                  
                                  #include "grid.h"
                                  
                                  typedef enum
                                  {
                                     RESIGNATION,
                                     WIN,
                                     LOST,
                                     NONE
                                  } userState_e;
                                  
                                  typedef struct
                                  {
                                     double t;
                                     int isWinner;
                                  } stats_s;
                                  
                                  void cleanStdin (void);
                                  stats_s *play (grid_s * p_grid);
                                  
                                  #endif
                                  


                                  color.h

                                  #ifndef H_LP_COLOR_20120314142325
                                  #define H_LP_COLOR_20120314142325
                                  
                                  #include <stdlib.h>
                                  
                                  #ifdef _WIN32
                                  #define BLACK_FG   '0'
                                  #define BLUE_FG    '1'
                                  #define GREEN_FG   'A'
                                  #define CYAN_FG    'B'
                                  #define RED_FG	   'C'
                                  #define YELLOW_FG  'E'
                                  #define WHITE_FG   'F'
                                  #else
                                  #define DEFAULT    "0"
                                  #define BLACK_FG   "30"
                                  #define RED_FG     "31"
                                  #define GREEN_FG   "32"
                                  #define YELLOW_FG  "33"
                                  #define BLUE_FG    "34"
                                  #define CYAN_FG    "36"
                                  #define WHITE_FG   "37"
                                  #endif
                                  
                                  #ifdef _WIN32
                                  #define color(a) system ("color %c", (a))
                                  #define clear()     system ("cls")
                                  #else
                                  #include <stdio.h>
                                  #define color(a) printf ("\033[%sm", (a))
                                  #define clear()     system ("clear")
                                  #endif
                                  
                                  #endif
                                  


                                  Je décline toute responsabilité en cas de migraines violentes causées par les horreurs que contient ce code.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Staff désormais retraité.
                                    14 mars 2012 à 22:31:19

                                    Bonsoir

                                    Une version SDL, pour le niveau 2(sans gestion du temps pour le moment).
                                    Image utilisateur

                                    Reste à faire:
                                    • -Gestion du temps(justement). :-°
                                    • -Amélioration de l'affichage.
                                    • -configurer la taille de la grille et le nombre de bombes.


                                    Le code est standard C99(je sais que Paraze apprécie. :-° )
                                    #include <SDL.h>
                                    #include <stdbool.h>
                                    
                                    #define MAX(a, b)((a) >= (b) ? (a) : (b))
                                    
                                    #define CHECK(cond)                                                             \
                                        do{                                                                         \
                                            if (!(cond))                                                            \
                                                fprintf(stderr, "%s line : %u\n %s\n",                              \
                                                        __FILE__,                                                   \
                                                        __LINE__,                                                   \
                                                        SDL_GetError()),                                            \
                                                exit(EXIT_FAILURE);                                                 \
                                        }while(0);
                                    
                                    
                                    #define OFFSET_X    0
                                    #define OFFSET_Y    0
                                    #define GRID_W      16
                                    #define GRID_H      16
                                    #define N_MINES     40
                                    #define TILE_SIZE   16
                                    #define W           (GRID_W * TILE_SIZE)
                                    #define H           (GRID_H * TILE_SIZE)
                                    #define BPP         16
                                    #define MINE        -1
                                    #define MINE_RED    -2
                                    #define EMPTY       0
                                    
                                    enum
                                    {
                                        e_STATE_START,
                                        e_STATE_PLAY,
                                        e_STATE_WIN,
                                        e_STATE_LOST,
                                    };
                                    
                                    
                                    
                                    enum
                                    {
                                        e_TILE_COVER,
                                        e_TILE_BOMB1,
                                        e_TILE_BOMB2,
                                        e_TILE_FLAG,
                                        e_TILE_0
                                    };
                                    
                                    typedef struct
                                    {
                                        int data;
                                        bool cover;
                                        bool mark;
                                    } Square;
                                    
                                    
                                    
                                    typedef struct
                                    {
                                        int n_col, n_row;
                                        int n_mines;
                                        int n_squares;
                                        Square **squares;
                                    } Grid;
                                    
                                    
                                    typedef struct
                                    {
                                        int row, col;
                                    } Coord;
                                    
                                    typedef struct
                                    {
                                        SDL_Surface *scr;       /* Surface principale               */
                                        SDL_Surface *srf_tiles; /* tiles                            */
                                        bool redraw;            /* doit on redessiner le plateau?   */
                                        bool done;              /* while running...                 */
                                        Uint8 button;           /* Bouton pressé(gauche ? droit?    */
                                        Coord crt_coords;       /* Coordonnée de la cae cliquée     */
                                        int state;              /* Etat du jeu                      */
                                        Grid grid;             /* plateau de jeu                   */
                                        char msg[256];         /* Messages                         */
                                    } Game;
                                    
                                    
                                    #define XMALLOC(sz)(xmalloc((sz), __FILE__, __LINE__))
                                    void* xmalloc(size_t sz, char const *file, int line)
                                    {
                                        void *p = malloc(sz);
                                        if(!p)
                                        {
                                            fprintf(stderr, "Error : Not enough memory!\n File : %s\n Line : %d\n",
                                                    file,
                                                    line);
                                            exit(EXIT_FAILURE);
                                        }
                                        return p;
                                    }
                                    
                                    
                                    
                                    void Grid_Alloc(Grid *grid, int n_col, int n_row, int n_mines)
                                    {
                                        grid->squares = XMALLOC(n_row * sizeof *grid->squares);
                                    
                                        for(int i = 0; i < n_row; i++)
                                            grid->squares[i] = XMALLOC(n_col * sizeof *grid->squares[i]);
                                    
                                        grid->n_col = n_col;
                                        grid->n_row = n_row;
                                        grid->n_mines = n_mines;
                                    }
                                    
                                    
                                    void Grid_Free(Grid *p_grid)
                                    {
                                        for(int i = 0; i < p_grid->n_row; i++)
                                            free(p_grid->squares[i]), p_grid->squares[i] = NULL;
                                        free(p_grid->squares), p_grid->squares = NULL;
                                    }
                                    
                                    
                                    void Grid_Clear(Grid *p_grid)
                                    {
                                        p_grid->n_squares = (p_grid->n_row * p_grid->n_col) - p_grid->n_mines;
                                        for(int i = 0; i < p_grid->n_row; i++)
                                            for(int j = 0; j < p_grid->n_col; j++)
                                            {
                                                p_grid->squares[i][j].data = EMPTY;
                                                p_grid->squares[i][j].cover = true;
                                                p_grid->squares[i][j].mark = false;
                                            }
                                    }
                                    
                                    
                                    int Grid_IsValid(Grid *p_grid, Coord *coord)
                                    {
                                        return coord->row >= 0 && coord->row < p_grid->n_row
                                               && coord->col >= 0 && coord->col < p_grid->n_col;
                                    
                                    }
                                    
                                    void Grid_ToogleFlag(Grid *p_grid, Coord *coord)
                                    {
                                        p_grid->squares[coord->row][coord->col].mark = 1 - p_grid->squares[coord->row][coord->col].mark;
                                    }
                                    
                                    int Grid_DFS(Grid *p_grid, Coord *crt_coord)
                                    {
                                        Coord a_dir[8] =
                                        {
                                            {-1, -1}, {-1, 0}, {-1, 1}, {0, 1},
                                            {1, 1}, {1, 0}, {1, -1}, {0, -1}
                                        };
                                        p_grid->squares[crt_coord->row][crt_coord->col].cover = false;
                                        p_grid->n_squares--;
                                        if(p_grid->squares[crt_coord->row][crt_coord->col].data == MINE)
                                        {
                                            p_grid->squares[crt_coord->row][crt_coord->col].data = MINE_RED;
                                            return 1;
                                        }
                                        if(p_grid->squares[crt_coord->row][crt_coord->col].data != EMPTY)
                                            return 0;
                                    
                                        int ret = 0;
                                        for(int i = 0; i < 8 ; i++)
                                        {
                                            Coord adj_coord;
                                            adj_coord.row = crt_coord->row + a_dir[i].row;
                                            adj_coord.col = crt_coord->col + a_dir[i].col;
                                            if(Grid_IsValid(p_grid, &adj_coord))
                                                if(p_grid->squares[adj_coord.row][adj_coord.col].cover)
                                                    ret = MAX(ret, Grid_DFS(p_grid, &adj_coord));
                                        }
                                        return ret;
                                    }
                                    
                                    
                                    
                                    void Grid_Update(Grid *p_grid, Coord *crt_coord)
                                    {
                                        Coord a_dir[8] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}};
                                        for(int i = 0; i < 8; i++)
                                        {
                                            Coord adj_coord;
                                            adj_coord.row = crt_coord->row + a_dir[i].row;
                                            adj_coord.col = crt_coord->col + a_dir[i].col;
                                            if(Grid_IsValid(p_grid, &adj_coord))
                                                if(p_grid->squares[adj_coord.row][adj_coord.col].data != MINE)
                                                    p_grid->squares[adj_coord.row][adj_coord.col].data++;
                                        }
                                    
                                    }
                                    
                                    void Grid_Init(Grid *p_grid)
                                    {
                                        Grid_Clear(p_grid);
                                        for(int i = 0; i < p_grid->n_mines; i++)
                                        {
                                            int c = rand() % (p_grid->n_row * p_grid->n_col - 1 - i);
                                            Coord crt_coord = {c / p_grid->n_col, c % p_grid->n_col};
                                    
                                            while(p_grid->squares[crt_coord.row][crt_coord.col].data == MINE)
                                            {
                                                if(++crt_coord.col == p_grid->n_col)
                                                {
                                                    crt_coord.col = 0;
                                                    ++crt_coord.row;
                                                }
                                            }
                                    
                                            p_grid->squares[crt_coord.row][crt_coord.col].data = MINE;
                                            Grid_Update(p_grid, &crt_coord);
                                        }
                                    }
                                    
                                    void Game_DisplayInfo(Game *game)
                                    {
                                        switch(game->state)
                                        {
                                             case e_STATE_START:
                                                sprintf(game->msg, " ");
                                                break;
                                            case e_STATE_PLAY:
                                                sprintf(game->msg, "Reste : %d", game->grid.n_squares);
                                                break;
                                            case e_STATE_WIN:
                                                sprintf(game->msg, "YOU WIN ! :(");
                                                break;
                                            case e_STATE_LOST:
                                                sprintf(game->msg, "YOU LOSE ! :(");
                                                break;
                                            default:
                                                break;
                                        }
                                        SDL_WM_SetCaption(game->msg, NULL);
                                    }
                                    
                                    
                                    void Game_Display(Game *game)
                                    {
                                        Grid p_grid = game->grid;
                                        Game_DisplayInfo(game);
                                        for(int row = 0; row < p_grid.n_row; row++)
                                            for(int col = 0; col < p_grid.n_col; col++)
                                            {
                                                SDL_Rect src, dst;
                                                Square square = p_grid.squares[row][col];
                                                int tile;
                                                if(square.cover)
                                                {
                                                    if(square.mark)
                                                        tile = e_TILE_FLAG;
                                                    else
                                                        tile = e_TILE_COVER;
                                                }
                                                else
                                                {
                                                    if(square.data == MINE)
                                                        tile = e_TILE_BOMB1;
                                                    else if(square.data == MINE_RED)
                                                        tile = e_TILE_BOMB2;
                                                    else
                                                        tile = e_TILE_0 + square.data;
                                    
                                                }
                                    
                                                dst.x = OFFSET_X + col * TILE_SIZE;
                                                dst.y = OFFSET_Y + row * TILE_SIZE;
                                                dst.w = TILE_SIZE;
                                                dst.h = TILE_SIZE;
                                                src.x = tile * TILE_SIZE;
                                                src.y = 0;
                                                src.w = TILE_SIZE;
                                                src.h = TILE_SIZE;
                                                SDL_BlitSurface(game->srf_tiles, &src, game->scr, &dst);
                                            }
                                    }
                                    
                                    
                                    
                                    
                                    
                                    void Game_Quit(Game *game)
                                    {
                                        SDL_FreeSurface(game->srf_tiles), game->srf_tiles = NULL;
                                        Grid_Free(&game->grid);
                                    }
                                    
                                    
                                    void Game_ProcessEvents(Game *game)
                                    {
                                        SDL_Event ev;
                                        int x, y;
                                        game->button = 0;
                                        while(SDL_PollEvent(&ev))
                                        {
                                            switch(ev.type)
                                            {
                                            case SDL_QUIT:
                                                game->done = true;
                                                break;
                                            case SDL_MOUSEBUTTONDOWN:
                                                game->button = SDL_GetMouseState(&x, &y);
                                                game->crt_coords.row = (y - OFFSET_Y) / TILE_SIZE;
                                                game->crt_coords.col = (x - OFFSET_X) / TILE_SIZE;
                                                break;
                                            }
                                        }
                                    }
                                    
                                    
                                    void Game_Init(Game *game)
                                    {
                                        CHECK(SDL_Init(SDL_INIT_VIDEO) == 0);
                                        CHECK(game->scr = SDL_SetVideoMode(W, H, BPP, SDL_SWSURFACE));
                                        CHECK(game->srf_tiles = SDL_LoadBMP("tiles.bmp"));
                                        Grid_Alloc(&game->grid, GRID_W, GRID_H, N_MINES);
                                        game->state = e_STATE_START;
                                        game->done = false;
                                    }
                                    
                                    
                                    void Game_Start(Game *game)
                                    {
                                        Grid_Init(&game->grid);
                                        game->state = e_STATE_PLAY;
                                        game->redraw = true;
                                    }
                                    
                                    
                                    void Game_Play(Game *game)
                                    {
                                        if(game->button & SDL_BUTTON(1))
                                        {
                                            /* Clic gauche */
                                            if(Grid_IsValid(&game->grid, &game->crt_coords))
                                                if(Grid_DFS(&game->grid, &game->crt_coords))
                                                    game->state = e_STATE_LOST;
                                        }
                                        else if(game->button & SDL_BUTTON(3))
                                        {
                                            /* Clic droit */
                                            if(Grid_IsValid(&game->grid, &game->crt_coords))
                                                Grid_ToogleFlag(&game->grid, &game->crt_coords);
                                        }
                                    
                                        if(game->grid.n_squares == 0)
                                            game->state = e_STATE_WIN;
                                    }
                                    
                                    
                                    
                                    void Game_Win(Game *game)
                                    {
                                        if(game->button & SDL_BUTTON(1))
                                            game->state = e_STATE_START;
                                    }
                                    
                                    
                                    void Game_Lost(Game *game)
                                    {
                                        if(game->button & SDL_BUTTON(1))
                                            game->state = e_STATE_START;
                                    }
                                    
                                    
                                    
                                    void Game_Run(Game *game)
                                    {
                                        while(!game->done)
                                        {
                                            Game_ProcessEvents(game);
                                            switch (game->state)
                                            {
                                            case e_STATE_START:
                                                Game_Start(game);
                                                break;
                                            case e_STATE_PLAY:
                                                Game_Play(game);
                                                break;
                                            case e_STATE_WIN:
                                                Game_Win(game);
                                                break;
                                            case e_STATE_LOST:
                                                Game_Lost(game);
                                                break;
                                            default:
                                                break;
                                            }
                                    
                                            SDL_Delay(10);
                                            if(game->button || game->redraw)
                                            {
                                                Game_Display(game);
                                                SDL_Flip(game->scr);
                                                game->redraw = false;
                                            }
                                        }
                                    }
                                    
                                    
                                    int main(int argc, char *argv[])
                                    {
                                        Game game;
                                        Game_Init(&game);
                                        atexit(SDL_Quit);
                                        Game_Run(&game);
                                        Game_Quit(&game);
                                    
                                        return 0;
                                    }
                                    

                                    Testé uniquement sous Windows xp pour le moment. Je colle un lien vers le tiles.bmp dès que possible.

                                    edit:
                                    Image utilisateur
                                    Bon on ne peut pas uploader sur le sdz en .bmp.
                                    Il vous faudra convertir en .bmp. Ou, je vais reposter une version qui utilise SDL_Image. :-°
                                    edit2:
                                    modification pour n'afficher que lorsque nécessaire...
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Zeste de Savoir, le site qui en a dans le citron !
                                      15 mars 2012 à 6:56:57

                                      Bonjour,

                                      Code proposé pour « feu » le concours SDL (pour participation uniquement) :

                                      http://www.siteduzero.com/forum-83-610 [...] html#r5928594
                                      [Linuxiens : ne téléchargez que les sources les plus récentes sur GitHub, elles corrigent un bug assez bizarre lié à l'appel de SDL_WM_SetCaption() depuis un callback. Et pour les autres aussi, c'est recommandé (correction d'un bug de performance).]

                                      Sinon, ce serait sympa de parler un peu algo, genre quel algo utilisez vous pour le comptage de cases voisines (il y en a 2 typiquement), ou autres trucs.

                                      @ GurneyH : je crois que je vais te piquer tes tiles, ils sont plus jolis que les miens. ;)
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        15 mars 2012 à 7:54:34

                                        Citation : Yoch


                                        Sinon, ce serait sympa de parler un peu algo, genre quel algo utilisez vous pour le comptage de cases voisines (il y en a 2 typiquement), ou autres trucs.


                                        Hum, tu parles du comptage des cases voisines au moment de la pose des bombes?

                                        Pour mon code, à chaque fois que je pose une bombe et pour chacune des 8 cases adjacentes(s'il ne s'agit pas d'une bombe), j'incrémente un compteur.
                                        Je vois pas la seconde solution! :-°

                                        Niveau algo, c'est plus le dfs pour découvrir les cases que je trouve sympa!

                                        Citation : Yoch


                                        @ GurneyH : je crois que je vais te piquer tes tiles, ils sont plus jolis que les miens. ;)


                                        Pas de soucis, moi je les trouve laids!(ce sont les tiles du démineur de WIndows Xp!).
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Zeste de Savoir, le site qui en a dans le citron !
                                          15 mars 2012 à 8:37:59

                                          Citation : GurneyH

                                          Pour mon code, à chaque fois que je pose une bombe et pour chacune des 8 cases adjacentes(s'il ne s'agit pas d'une bombe), j'incrémente un compteur.
                                          Je vois pas la seconde solution! :-°


                                          C'est normal, tu as la bonne (l'autre solution est moins bonne). ;)

                                          Citation : GurneyH

                                          Niveau algo, c'est plus le dfs pour découvrir les cases que je trouve sympa!


                                          Ouais, c'est sympa aussi, mais il n'y a pas de piège là dessus. Enfin bon, le démineur, ce n'est pas non plus le gros truc d'algo de la mort, bref...

                                          Niveau fonctionnalités :
                                          Une fonction intéressante à implémenter serait la fonction "double-clic" du démineur Windows : effectue les découvrements "immédiats" automatiquement. Perso, je l'ai mise. En revanche, je n'ai pas ajouté de possibilité de sauvegarde.

                                          Citation : GurneyH

                                          Citation : Yoch


                                          @ GurneyH : je crois que je vais te piquer tes tiles, ils sont plus jolis que les miens. ;)


                                          Pas de soucis, moi je les trouve laids!(ce sont les tiles du démineur de WIndows Xp!).


                                          Moi, je les ai fait à la main, donc forcément c'est pire...
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            15 mars 2012 à 17:51:41

                                            J'ai fait le niveau 2 (pas encore géré la gestion du clavier)

                                            Main


                                            main.c


                                            #include "header.h"
                                            #include <stdlib.h>
                                            #include <stdio.h>
                                            #include <time.h>
                                            
                                            int main(void) {
                                            
                                                Grille grille;
                                                Choix choix;
                                                position_t x, y;
                                                int nbMines;
                                            
                                                srand(time(NULL));
                                            
                                                printf("** zDemineur (niveau 2) **\n\n");
                                            
                                                afficherRegles();
                                            
                                                printf("Paramètres :\n");
                                                
                                                printf("    - lignes   : "); scanf("%d", &y);     
                                                while(y < 0 || y > MAX_Y) {
                                                    fprintf(stderr, "Erreur : le nombre de lignes doit être positif et inférieur à %d\n", MAX_Y);
                                                    printf("    - lignes   : "); scanf("%d", &y); 
                                                }
                                                
                                                printf("    - colonnes : "); scanf("%d", &x);
                                                while(y < 0 || y > MAX_Y) {
                                                    fprintf(stderr, "Erreur : le nombre de colonnes doit être positif et inférieur à %d\n", MAX_X);
                                                    printf("    - colonnes   : "); scanf("%d", &x); 
                                                }
                                                   
                                                printf("    - mines    : "); scanf("%d", &nbMines);
                                                while(nbMines > x*y) {
                                                    fprintf(stderr, "Erreur : le nombre de mines doit être inférieur (ou égal) au nombre de cases (%d)\n", x*y);
                                                    printf("    - mines   : "); scanf("%d", &nbMines); 
                                                }
                                                
                                                printf("\n");
                                            
                                                initGrille(&grille, x, y, nbMines);
                                            
                                                #ifdef DEBUG
                                                    printf("Grille (debug) :\n\n");
                                                    afficherGrilleClaire(&grille);
                                                #endif
                                                
                                                bool aGagne = false, aPerdu = false;
                                                
                                                do
                                                {
                                            
                                                    afficherSeparateur();
                                                    printf("Grille :\n\n");
                                                    afficherGrille(&grille);
                                            
                                                    if(grille.nbDrapeaux < grille.nbMines) {
                                                        printf("\nIl devrait rester %d/%d mines\n\n", 
                                                               grille.nbMines - grille.nbDrapeaux, 
                                                               grille.nbMines);
                                                    }
                                                    else if(grille.nbDrapeaux == grille.nbMines) {
                                                        printf("\nHum.. le compte de drapeaux est bon, mais sont-ils au bon endroit ?\n\n");
                                                    }
                                                    else {
                                                        printf("\nIl y a %d drapeaux en trop (%d/%d)\n\n", 
                                                               grille.nbDrapeaux - grille.nbMines,
                                                               grille.nbDrapeaux,
                                                               grille.nbMines);
                                                    }
                                            
                                                    printf("Que faire :\n");
                                                    printf("    - (%d) Abandonner\n", ABANDONNER);
                                                    printf("    - (%d) Poser/Enlever un drapeau\n", MARQUER);
                                                    printf("    - (%d) Découvrir une case \n", DECOUVRIR);
                                                    
                                                    printf("\nChoix : "); scanf("%d", (int*)&choix);
                                                    switch(choix) {        
                                                        case ABANDONNER:
                                                        break;
                                                        case MARQUER:
                                                        
                                                            printf("Quelle case :\n");
                                                            printf("    - x : "); scanf("%d", (int*)&x);
                                                            printf("    - y : "); scanf("%d", (int*)&y);
                                                            printf("\n");
                                                            
                                                            x--;
                                                            y = grille.nbLignes - (y-1) -1;
                                                            
                                                            if(x > 0 && x < grille.nbColonnes && y > 0 && y < grille.nbLignes) {
                                                                marquer(&grille, x, y);
                                                                aGagne = gagne(&grille);
                                                            }
                                                        
                                                        break;
                                                        case DECOUVRIR:
                                                        
                                                            printf("Quelle case :\n");
                                                            printf("    - x : "); scanf("%d", (int*)&x);
                                                            printf("    - y : "); scanf("%d", (int*)&y);
                                                            printf("\n");
                                                            
                                                            x--;
                                                            y = grille.nbLignes - (y-1) - 1;
                                                            
                                                            if(x > 0 && x < grille.nbColonnes && y > 0 && y < grille.nbLignes) {
                                                                decouvrir(&grille, x, y);
                                                                aPerdu = (grille.grille[x][y].indication == MINE);
                                                            }
                                                        
                                                        break;        
                                                    }
                                                    
                                                } while(!aGagne && !aPerdu && choix != ABANDONNER);
                                                
                                                afficherSeparateur();
                                                
                                                if(aPerdu || choix == ABANDONNER) {
                                                    printf("Perdu !\n\n");
                                                }
                                                else {
                                                    printf("Gagné !\n\n");
                                                }
                                                
                                                afficherGrilleClaire(&grille);
                                            
                                                return 0;
                                            }
                                            


                                            Header


                                            header.h


                                            #ifndef HEADER_H_INCLUDED
                                            #define HEADER_H_INCLUDED
                                            
                                                // #define DEBUG
                                            
                                                // La valeur qui désigne une mine (/!\ ne doit pas valoir entre 1 et 8)
                                                #define MINE -1
                                                
                                                typedef int position_t;   //< type d'une position
                                                typedef int indication_t; //< type d'un indice
                                            
                                                /** Etat d'une case (jeu) */
                                                typedef enum eEtat {
                                                    INCONNUE, DECOUVERTE, DRAPEAU
                                                } Etat ;
                                            
                                                /** Une case */
                                                typedef struct sCase {
                                                    indication_t indication; // MINE si minée, 0 - 8 sinon.
                                                    Etat etat;               // Etat au cours de la partie
                                                } Case ;
                                            
                                                // Taille maximale d'un tableau
                                                #define MAX_X 9
                                                #define MAX_Y 9
                                            
                                                /** Une grille */
                                                typedef struct sGrille {
                                                    Case grille[MAX_X][MAX_Y];  // Notre grille
                                                    position_t nbLignes;        // hauteur
                                                    position_t nbColonnes;      // largeur
                                            
                                                    char nbMines;    // (Calculable)
                                                    char nbDrapeaux; // (Calculable)
                                                } Grille ;
                                            
                                                /** Couleur */
                                                typedef enum eColor {
                                                    NOIR, ROUGE, VERT, ORANGE, BLEU, MAJENTA, CYAN, BLANC
                                                } Color ;
                                            
                                                /** Choix (menu de jeu) */
                                                typedef enum eChoix {
                                                    ABANDONNER, MARQUER, DECOUVRIR   
                                                } Choix ;
                                                
                                                /** booléen */
                                                typedef enum eBool {
                                                    false = 0, true = 1
                                                } bool;
                                            
                                                // --------------------------------------------------------- //
                                            
                                                /** Ecrit l'indice passé en paramètre (en couleur) */
                                                void ecrireIndice(indication_t c);
                                            
                                                /** Change la couleur du terminal */
                                                void setColor(Color c);
                                            
                                                /** Remet la couleur du terminal à zéro */
                                                void resetColor(void);
                                            
                                                // --------------------------------------------------------- //
                                                
                                                /** Tire un nombre aléatoire entre min et max */
                                                int aleatoire(int min, int max);
                                            
                                                // --------------------------------------------------------- //
                                                
                                                /** 
                                                    Initialise notre grille 
                                                    @param g
                                                        La grille
                                                    @param nbC
                                                        Le nombre de colonnes
                                                    @param nbL
                                                        Le nombre de lignes
                                                    @param nbMines
                                                        Le nombre de mines
                                                */
                                                void initGrille(Grille * g, position_t nbC, position_t nbL, int nbMines);
                                                
                                                /** Ajoute une mine en (x, y) */
                                                void ajouterMine(Grille *, position_t x, position_t y);
                                            
                                                /** Ajoute nbMines mines aléatoirement */
                                                void ajouterMines(Grille *, int nbMines);
                                            
                                                // --------------------------------------------------------- //
                                            
                                                /** Affiche les règles du jeu */
                                                void afficherRegles(void);
                                            
                                                /** Affiche un séparateur (ou efface l'ecran) */
                                                void afficherSeparateur(void);
                                            
                                                /** Affiche la grille decouverte */
                                                void afficherGrilleClaire(const Grille *);
                                            
                                                /** Affiche la grille */
                                                void afficherGrille(const Grille *);
                                            
                                                // --------------------------------------------------------- //
                                            
                                                /** Indique si les drapeaux sont ou il faut */
                                                bool gagne(const Grille *);
                                            
                                                /** Plante un drapeau */
                                                void marquer(Grille *, position_t x, position_t y);
                                            
                                                /** Decouvrons une case */
                                                void decouvrir(Grille *, position_t x, position_t y);
                                            
                                            
                                            #endif//HEADER_H_INCLUDED
                                            


                                            Fonctions


                                            fonctions.c


                                            #include "header.h"
                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            
                                            int aleatoire(int min, int max) {
                                                return ((int)((double)rand()/RAND_MAX*(max-min)))+min;
                                             // return (rand()%(max-min+1))+min;
                                            }
                                            
                                            void setColor(Color c) {
                                                // Si on est sous linux
                                                #ifdef __linux__
                                                    printf("\033[3%dm", c);
                                                    if(c == NOIR) {
                                                        printf("\033[7%dm", BLANC);
                                                    }
                                                    if(c == BLANC) {
                                                        printf("\033[7%dm", NOIR);
                                                    }
                                                #endif
                                            
                                                // Si on est sous windows
                                                #ifdef __WIN32__
                                                    switch(c) {
                                                        case NOIR:    system("COLOR 0F"); break;
                                                        case ROUGE:   system("COLOR C0"); break;
                                                        case VERT:    system("COLOR 20"); break;
                                                        case ORANGE:  system("COLOR E0"); break;
                                                        case BLEU:    system("COLOR 90"); break;
                                                        case MAJENTA: system("COLOR D0"); break;
                                                        case CYAN:    system("COLOR B0"); break;
                                                        case BLANC:   system("COLOR F0"); break;
                                                    }
                                                #endif
                                            }
                                            
                                            void resetColor(void) {
                                                // Si on est sous linux
                                                #ifdef __linux__
                                                    printf("\033[0m");
                                                #endif
                                            
                                                // Si on est sous windows
                                                #ifdef __WIN32__
                                                    setColor(BLANC);
                                                #endif
                                            }
                                            


                                            grille.c


                                            #include "header.h"
                                            
                                            void initGrille(Grille * g, position_t nbC, position_t nbL, int nbMines) {
                                            
                                                g->nbLignes = nbL;
                                                g->nbColonnes = nbC;
                                                g->nbMines = 0;
                                                g->nbDrapeaux = 0;
                                            
                                                int x, y;
                                                for(x = 0; x < g->nbColonnes; x++) {
                                                    for(y = 0; y < g->nbLignes; y++) {
                                                        g->grille[x][y].indication = 0;
                                                        g->grille[x][y].etat = INCONNUE;
                                                    }
                                                }
                                            
                                                ajouterMines(g, nbMines);
                                            }
                                            
                                            void ajouterMines(Grille * g, int N) {
                                            
                                                int n;
                                                const int nbCases = g->nbLignes * g->nbColonnes;
                                            
                                                for(n = 0; n < N; n++) {
                                            
                                                    int c = aleatoire(0, nbCases-1 - g->nbMines)+1;
                                                    int i = 0;
                                            
                                                    char x = 0;
                                                    char y = 0;
                                            
                                                    if(g->grille[x][y].indication != MINE)
                                                        i++;
                                            
                                                    while(i < c) {
                                            
                                                        x++;
                                                        if(x >= g->nbColonnes) {
                                                            x = 0;
                                                            y++;
                                            
                                                            if(y >= g->nbLignes) {
                                                                y = 0;
                                                            }
                                                        }
                                            
                                                        if(g->grille[x][y].indication != MINE)
                                                            i++;
                                                    }
                                            
                                                    ajouterMine(g, x, y);
                                                }
                                            }
                                            
                                            void ajouterMine(Grille * g, position_t x, position_t y) {
                                                // Ajoute la mine
                                                g->grille[x][y].indication = MINE;
                                                g->nbMines++;
                                            
                                                // Incrémente les indices des cases alentours (si ce ne sont pas des mines, ou du vide)
                                            
                                                // A gauche
                                                if(x > 0) {
                                                    // En haut
                                                    if(y > 0) {
                                                        if(g->grille[x-1][y-1].indication != MINE) {
                                                            g->grille[x-1][y-1].indication++;
                                                        }
                                                    }
                                            
                                                    // Au milieu
                                                    if(g->grille[x-1][y].indication != MINE) {
                                                        g->grille[x-1][y].indication++;
                                                    }
                                            
                                                    // En bas
                                                    if(y < g->nbLignes - 1) {
                                                        if(g->grille[x-1][y+1].indication != MINE) {
                                                            g->grille[x-1][y+1].indication++;
                                                        }
                                                    }
                                                }
                                            
                                                // Au milieu
                                                    // En haut
                                                    if(y > 0) {
                                                        if(g->grille[x][y-1].indication != MINE) {
                                                            g->grille[x][y-1].indication++;
                                                        }
                                                    }
                                            
                                                    // En bas
                                                    if(y < g->nbLignes - 1) {
                                                        if(g->grille[x][y+1].indication != MINE) {
                                                            g->grille[x][y+1].indication++;
                                                        }
                                                    }
                                            
                                                // A droite
                                                if(x < g->nbColonnes - 1) {
                                                    // En haut
                                                    if(y > 0) {
                                                        if(g->grille[x+1][y-1].indication != MINE) {
                                                            g->grille[x+1][y-1].indication++;
                                                        }
                                                    }
                                            
                                                    // Au milieu
                                                    if(g->grille[x+1][y].indication != MINE) {
                                                        g->grille[x+1][y].indication++;
                                                    }
                                            
                                                    // En bas
                                                    if(y < g->nbLignes - 1) {
                                                        if(g->grille[x+1][y+1].indication != MINE) {
                                                            g->grille[x+1][y+1].indication++;
                                                        }
                                                    }
                                                }
                                            
                                            }
                                            


                                            affichage.c


                                            #include "header.h"
                                            #include <stdio.h>
                                            
                                            void afficherRegles(void) {
                                            
                                                printf("Regles : Vous voila en face d'un terrain qu'il vous faut déminer.\n");
                                                printf("         Pour ce faire, vous allez devoir poser des drapeaux sur chaque mine.\n");
                                                printf("         Chaque case découverte vous indiquant le nombre de mines adjacentes.\n");
                                                printf("         Si vous tentez de découvrir une case minée, vous perdez.\n\n");
                                            }
                                            
                                            void afficherSeparateur(void) {
                                                printf("____________________________________\n\n");
                                            }
                                            
                                            void afficherGrilleClaire(const Grille * g) {
                                            
                                                char x, y;
                                                for(y = 0; y < g->nbLignes; y++) {
                                            
                                                    // Affiche une ligne
                                                    printf("    +");
                                                    for(x = 0; x < g->nbColonnes; x++) {
                                                        printf("---+");
                                                    }
                                                    printf("\n    |");
                                            
                                                    // Affiche une liste de cases
                                                    for(x = 0; x < g->nbColonnes; x++) {
                                                        printf(" ");
                                                        if(g->grille[x][y].indication == MINE) {
                                                            printf("x");
                                                        }
                                                        else if(g->grille[x][y].indication == 0) {
                                                            printf(" ");
                                                        }
                                                        else {
                                                            ecrireIndice(g->grille[x][y].indication);
                                                        }
                                                        printf(" |");
                                                    }
                                                    printf("\n");
                                                }
                                            
                                                // Affiche une ligne
                                                printf("    +");
                                                for(x = 0; x < g->nbColonnes; x++) {
                                                    printf("---+");
                                                }
                                                printf("\n");
                                            }
                                            
                                            void afficherGrille(const Grille * g) {
                                            
                                                char x, y;
                                                for(y = 0; y < g->nbLignes; y++) {
                                            
                                                    // Affiche une ligne
                                                    printf("    +");
                                                    for(x = 0; x < g->nbColonnes; x++) {
                                                        printf("---+");
                                                    }
                                                    printf("\n    |");
                                            
                                                    // Affiche une liste de cases
                                                    for(x = 0; x < g->nbColonnes; x++) {
                                                        printf(" ");
                                                        if(g->grille[x][y].etat == INCONNUE) {
                                                            printf("?");
                                                        }
                                                        else if(g->grille[x][y].etat == DRAPEAU) {
                                                            printf("P");
                                                        }
                                                        else if(g->grille[x][y].indication == MINE) {
                                                            printf("x");
                                                        }
                                                        else if(g->grille[x][y].indication == 0) {
                                                            printf(" ");
                                                        }
                                                        else {
                                                            ecrireIndice(g->grille[x][y].indication);
                                                        }
                                                        printf(" |");
                                                    }
                                                    printf("\n");
                                                }
                                            
                                                // Affiche une ligne
                                                printf("    +");
                                                for(x = 0; x < g->nbColonnes; x++) {
                                                    printf("---+");
                                                }
                                                printf("\n");
                                            }
                                            
                                            void ecrireIndice(indication_t c) {
                                                switch(c) {
                                                    case 1: setColor(BLEU); break;
                                                    case 2: setColor(ROUGE); break;
                                                    case 3: setColor(VERT); break;
                                                    case 4: setColor(ORANGE); break;
                                                    case 5: setColor(MAJENTA); break;
                                                    case 6: setColor(CYAN); break;
                                                    case 7: setColor(BLANC); break;
                                                    case 8: setColor(NOIR); break;
                                                }
                                                printf("%d", (int)c);
                                                resetColor();
                                            }
                                            


                                            jeu.c


                                            #include "header.h"
                                            
                                            bool gagne(const Grille * g) {
                                            
                                                if(g->nbDrapeaux != g->nbMines)
                                                    return false;
                                            
                                                int x, y;
                                                for(x = 0; x < g->nbColonnes; x++) {
                                                    for(y = 0; y < g->nbLignes; y++) {
                                                        if(g->grille[x][y].indication == MINE && g->grille[x][y].etat != DRAPEAU) {
                                                            return false;
                                                        }
                                            
                                                        if(g->grille[x][y].indication != MINE && g->grille[x][y].etat == DRAPEAU) {
                                                            return false;
                                                        }
                                                    }
                                                }
                                            
                                                return true;
                                            }
                                            
                                            void marquer(Grille * g, position_t x, position_t y) {
                                                if(g->grille[x][y].etat == DECOUVERTE)
                                                    return;
                                            
                                                if(g->grille[x][y].etat == DRAPEAU) {
                                                    g->grille[x][y].etat = INCONNUE;
                                                    g->nbDrapeaux--;
                                                }
                                                else {
                                                    g->grille[x][y].etat = DRAPEAU;
                                                    g->nbDrapeaux++;
                                                }
                                            }
                                            
                                            void decouvrir(Grille * g, position_t x, position_t y) {
                                                if(g->grille[x][y].etat == DECOUVERTE) {
                                                    return;
                                                }
                                            
                                                if(g->grille[x][y].etat == DRAPEAU) {
                                                    g->nbDrapeaux--;
                                                }
                                            
                                                g->grille[x][y].etat = DECOUVERTE;
                                                if(g->grille[x][y].indication == 0) {
                                                    // A gauche
                                                    if(x > 0) {
                                                        // En haut
                                                        if(y > 0) {
                                                            decouvrir(g, x-1, y-1);
                                                        }
                                            
                                                        // Au milieu
                                                        decouvrir(g, x-1, y);
                                            
                                                        // En bas
                                                        if(y < g->nbLignes - 1) {
                                                            decouvrir(g, x-1, y+1);
                                                        }
                                                    }
                                            
                                                    // Au milieu
                                                        // En haut
                                                        if(y > 0) {
                                                            decouvrir(g, x, y-1);
                                                        }
                                            
                                                        // En bas
                                                        if(y < g->nbLignes - 1) {
                                                            decouvrir(g, x, y+1);
                                                        }
                                            
                                                    // A droite
                                                    if(x < g->nbColonnes - 1) {
                                                        // En haut
                                                        if(y > 0) {
                                                            decouvrir(g, x+1, y-1);
                                                        }
                                            
                                                        // Au milieu
                                                        decouvrir(g, x+1, y);
                                            
                                                        // En bas
                                                        if(y < g->nbLignes - 1) {
                                                            decouvrir(g, x+1, y+1);
                                                        }
                                                    }
                                                }
                                            }
                                            


                                            Bonus


                                            Makefile


                                            CC=gcc
                                            CFLAGS=-O3 -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Werror-implicit-function-declaration -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings -Wconversion -Wsign-compare -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wmissing-noreturn -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wunreachable-code
                                            PROG=demineur
                                            
                                            objets=main.o grille.o jeu.o affichage.o fonctions.o
                                            headers=header.h
                                            
                                            $(PROG) : $(objets) $(headers)
                                                    $(CC) $(objets) -o $(PROG) 
                                            
                                            %.o : %.c $(headers)
                                                    $(CC) -c $< -o $@ $(CFLAGS)
                                            
                                            clean:
                                                    rm -rf $(objets) $(PROG)
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            perror(const char * str); will save your life !
                                              17 mars 2012 à 12:44:53

                                              Bonjour,

                                              Ca ne répond pas tout à fait au sujet, mais lire tout ça m'a donné envie de bricoler un petit démineur.

                                              J'ai donc fait ceci :
                                              http://oldschoolprg.x10.mx/downloads/zDemineur0.rar

                                              C'est une version naïve de la chose, commencée from scratch hier soir.

                                              Je suis bien conscient que le réaffichage de la totalité à chaque frame n'est pas super adapté à un démineur, que c'est la version lente du compte de mines, tout ça, mais bon, c'était pour me détendre un peu (révisions intensives et pas de code).

                                              Contrôles :
                                              F5 pour relancer une partie.
                                              LMB : Démine.
                                              RMB : Flag / interrogation / unflag.

                                              (Et un jour, je ferai peut-être ce qui manque ! :p )

                                              Clément.

                                              Edit :
                                              Je viens de jeter un oeil au code de GurneyH (qui est plus propre que le mien d'ailleurs), et je précise que la similitude sur les noms de fonctions, les enums, et autres choses ressemblantes est vraiment une coïncidence !

                                              Edit 2 :
                                              Et une petite upgrade pour voir les bombes quand on perd. (+ suppression de valeurs en dur, mais je ne suis pas sûr que ça aide à la compréhension).
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                18 mars 2012 à 13:42:53

                                                J'ai du mal à m'y retrouver dans ton code X)
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                perror(const char * str); will save your life !
                                                  18 mars 2012 à 19:30:30

                                                  Citation : yoch

                                                  Niveau fonctionnalités :
                                                  Une fonction intéressante à implémenter serait la fonction "double-clic" du démineur Windows : effectue les découvrements "immédiats" automatiquement. Perso, je l'ai mise.


                                                  Heuu, je suis pas sûr d'avoir saisi le double clic. ^^
                                                  Tu pourrais être un peu plus explicite ? :)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    18 mars 2012 à 19:56:11

                                                    Citation : Pouet_forever

                                                    Heuu, je suis pas sûr d'avoir saisi le double clic. ^^
                                                    Tu pourrais être un peu plus explicite ? :)


                                                    Suppose que j'ai marqué 2 cases d'un drapeau comme ci-dessous.

                                                    Image utilisateur

                                                    Il est immédiat que certaines cases peuvent être déminées sans risque (et sans "calcul"), puisque la case marquée de [2] est déjà en contact avec 2 mines. Si je double clic sur la case [2], j'obtiens :

                                                    Image utilisateur

                                                    Ça permet d'accélérer un peu le jeu. Et si mes drapeaux étaient mauvais, je peux perdre en faisant cela.

                                                    Il me semble que certains jeux sous Linux implémentent aussi cette fonction (chercher dans les options).
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      18 mars 2012 à 20:41:25

                                                      Ouais, donc en fait ça découvre simplement les cases adjacentes si le nombre de mines est 'rempli' ? :)
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                      Anonyme
                                                        18 mars 2012 à 20:45:01

                                                        juste une question à quoi servent tous les chiffres (de 1 à 8) ?et pour la console que représente 1 et que représente 2 ( 1 = sur et 2 = drapeau) ?
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          18 mars 2012 à 20:47:36

                                                          Citation : tib92

                                                          juste une question à quoi servent tous les chiffres (de 1 à 8) ?et pour la console que représente 1 et que représente 2 ( 1 = sur et 2 = drapeau) ?


                                                          c'est le nombre de mines adjacentes à la case.
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Zeste de Savoir, le site qui en a dans le citron !
                                                          Anonyme
                                                            18 mars 2012 à 20:50:13

                                                            merci mais alors pourquoi avoir 1 et 2 et pas tout simplement 1 ?
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            zDemineur

                                                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                            • Editeur
                                                            • Markdown