Partage
  • Partager sur Facebook
  • Partager sur Twitter

Bataille navale

Sujet résolu
    19 octobre 2019 à 13:31:42

    Comme l'indique le titre du sujet, je cherche à faire un programme de bataille navale. Précision : je débute en c.

    Il y a un problème dans le code, je ne sais pas vraiment lequel.

    Voici le code source :

    #define SIZE 10
    
    void main(){
      int grille[SIZE] [SIZE]=
        {
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0},
          {0,0,0,0,0,0,0,0,0,0}
        };
    
      /* for(int i=0; i<10; i++){
        for(int j=0; j<10; j++){
          printf("%d", grille[i][j]);
        }
        putchar('\n');
        }*/
      srand(time(NULL));
      int x=rand()%10;
      int y=rand()%10;
      grille[x][y]=1;
       for(int i=0; i<10; i++){
        for(int j=0; j<10; j++){
          printf("%d", grille[i][j]);
        }
        putchar('\n');
        }
       putchar('\n');
      int xoy=rand()%2;
      if(xoy==0){
        int z=y+1;
        printf("%d\n", z);
        if(grille[x][z]!=0){      
          z=z-2;	      
          printf("%d\n", z);
          grille[x][z]=1;
        }
        else if(grille[x][z]==0){
          grille[x][z]=1;
        }
      }
      else if(xoy==1){
        int z=x+1;
        printf("%d\n", z);
        if(grille[z][y]!=0){
          z=z-2;
          grille[z][y]=1;
        }
        else if(grille[z][y]==0){
          grille[z][y]=1;
        }
      }
      for(int i=0; i<10; i++){
        for(int j=0; j<10; j++){
          printf("%d", grille[i][j]);
        }
        putchar('\n');
        }
      
    }
    

    Et ce que ça donne au terminal :

    0000000000
    0000000000
    0000000000
    0000000000
    0000000000
    0000000001
    0000000000
    0000000000
    0000000000
    0000000000
    
    10
    0000000000
    0000000000
    0000000000
    0000000000
    0000000000
    0000000001
    1000000000
    0000000000
    0000000000
    0000000000
    




    • Partager sur Facebook
    • Partager sur Twitter
      19 octobre 2019 à 15:02:47

      Bonjour ! Donc ça marche ? Ou pas ?

      Tu devrais préciser 1° ce que le programme est sensé faire (mettre des '1' au hasard sur la grille ? combien ? selon quelles règles ?) et 2° ce qu'il fait (là où il ne fait pas ce qui était prévu).

      • Partager sur Facebook
      • Partager sur Twitter
        19 octobre 2019 à 20:04:16

        Le code est cencé positioner le premier bateau de la bataille navale. Celui-ci occupe deux cases cotes à cotes. Le problème est que quand la première case du bateau (tirée au sort) se trouve sur le bord droit de la grille, la seconde case se met à la première case de la ligne en dessous, alors qu'elle devrait être à la gauche de la première case.
        • Partager sur Facebook
        • Partager sur Twitter
          19 octobre 2019 à 23:07:45

          Ça suggère qu'il faut prévoir ce cas : si la première case n'est pas sur le bord droit, on en ajoute une à droite ; si elle est sur le bord droit, on en ajoute une à gauche.
          • Partager sur Facebook
          • Partager sur Twitter
            20 octobre 2019 à 9:38:27

            C'est ça le problème. IL ne veut pas rajouter la seconde case à gauche lorsque la première est sur le bord droit.
            • Partager sur Facebook
            • Partager sur Twitter
              20 octobre 2019 à 11:32:29

              C'est à quelles lignes que tu crées les deux cases « 1 » ? (N'hésite pas à ajouter des commentaires dans le programme, d'ailleurs, ça peut aider.)

              OK, après examen du programme j'ai compris ! En fait tu fais un test, mais un autre :

                  int z=x+1;
                  if(grille[z][y]!=0){
              

              z est l'abscisse de la 2è case, donc on veut placer la 2è case à droite. Mais pour savoir s'il y a de la place, il faut savoir si on déborde ou pas de la grille. Or ce que tu testes, c'est si grille est != 0 à droite, autrement dit s'il y a déjà une case. C'est un test utile quand la grille contiendra du monde, donc il faut le garder, mais ce n'est pas le test dont je parlais.

              Ce qu'il faut tester, c'est si on est arrivé en bout de grille. Pour ça, il faut regarder la valeur de x : si  x est trop grand, on fait z=x-1, sinon on fait z = x+1.

              (Ensuite, il faudra gérer le cas où on est obligé d'aller à gauche mais il y a quelqu'un... Si tu veux faire ça bien c'est assez compliqué. Est-ce que tu as vu les fonctions ? Je trouve que ce serait une bonne idée de créer une fonction qui vérifie si une case est valide (il n'y a personne dessus et on ne sort pas de la grille). Il y aura trois cas : 1° la case du haut (ou de gauche) et la case du bas (ou de droite) sont valides, on peut alors choisir celle du bas (ou de droite) ; 2° une seule de ces deux est valide, il faut la choisir (par exemple parce qu'on est à la dernière case à droite de la grille, il faut alors ajouter l'autre "1" à gauche) ; 3° aucune n'est valide, que faire ?)

              PS : j'ai compris ce que fait le programme en ajoutant des commentaires (j'ai aussi modifié l'indentation et corrigé la syntaxe du "main"). Pour info, je te montre ce que ça donne. Il y a sûrement un peu trop de commentaires, du coup, mais j'en avais alors besoin. Peux-être que tu peux t'inspirer de ça si tu as besoin de communiquer un programme à quelqu'un ?

              #include <stdio.h>
              #define SIZE 10
               
              int main(void){
                  int grille[SIZE] [SIZE]=
                  {
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0,0}
                  };
               
                  srand(time(NULL));
              
                  /* Le programme définit deux cases (un bateau) qu'il place
                     horizontalement ou verticalement. Pour cela, on tire au
                     sort la position de la première case, et on choisit ensuite
                     celle de la seconde. */
              
                  // Position de la première case
                  int x=rand()%10;
                  int y=rand()%10;
                  grille[x][y]=1;
                 
                  // Affichage de la grille avec 1 case
                  for(int i=0; i<10; i++){
                      for(int j=0; j<10; j++){
                          printf("%d", grille[i][j]);
                      }
                      putchar('\n');
                  }
                  putchar('\n');
              
                  // Choix horizontal ou vertical (1 chance sur 2)
                  int xoy=rand()%2;
              
                  if(xoy==0){
                      // Cas vertical
                      int z=y+1;      // ordonnée de la 2è case : en bas
                      printf("%d\n", z);
                      if(grille[x][z]!=0){     
                          z=z-2;         
                          printf("%d\n", z);
                          grille[x][z]=1;
                      }
                      else if(grille[x][z]==0){
                          grille[x][z]=1;
                      }
                  }
              
                  else {
                      // Cas horizontal
                      int z=x+1;      // abscisse de la 2è case : à droite
                      printf("%d\n", z);
                      if(grille[z][y]!=0){
                          z=z-2;
                          grille[z][y]=1;
                      }
                      else if(grille[z][y]==0){
                          grille[z][y]=1;
                      }
                  }
              
                  // Affichage de la grille avec 2 cases
                  for(int i=0; i<10; i++){
                      for(int j=0; j<10; j++){
                          printf("%d", grille[i][j]);
                      }
                      putchar('\n');
                  }
                 
              }



              -
              Edité par robun 20 octobre 2019 à 12:05:13

              • Partager sur Facebook
              • Partager sur Twitter
                20 octobre 2019 à 14:57:28

                Ok merci. Le seul problème est que je peux pas rester ta solution puisque je suis en vacances en dehors de chez moi pour le reste de la semaine. Je rentre chez moi samedi ou vendredi et je vous tiendrai au courant. En attendant, je propose de mettre ce sujet en résolu ??
                • Partager sur Facebook
                • Partager sur Twitter
                  20 octobre 2019 à 15:37:33

                  Attention, je n'ai pas proposé de solution précise ! (Le code posté était un exemple d'utilisation des commentaires pour nous aider, pas une solution.) J'ai même précisé que ça risque d'être compliqué. Mon but était surtout de voir pourquoi ça ne marche pas. Le plus dur reste à faire.

                  -
                  Edité par robun 20 octobre 2019 à 15:37:58

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 octobre 2019 à 13:15:28

                    Merci robun,

                    grâce à tes conseils, je suis parvenu à résoudre mon problème de débutant.

                    Voici le code source juste :

                    /*Bataille navale*/
                    
                    #include <stdio.h>
                    #include <time.h>
                    #include <stdlib.h>
                    #include <string.h>
                    #include <math.h>
                    
                    #define SIZE 10
                    
                    void main(){
                      int z;
                      int grille[SIZE] [SIZE]=
                        {
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0},
                          {0,0,0,0,0,0,0,0,0,0}
                        };
                    
                      /* for(int i=0; i<10; i++){
                        for(int j=0; j<10; j++){
                          printf("%d", grille[i][j]);
                        }
                        putchar('\n');
                        }*/
                      srand(time(NULL));
                      int x=rand()%10;     //tirage au sort ordonnée case 1
                      int y=rand()%10;     //tirage au sort abscisse case 1
                      grille[x][y]=1;      //placement case 1
                      for(int i=0; i<10; i++){              //boucle d'affichage de la grille
                        for(int j=0; j<10; j++){
                          printf("%d", grille[i][j]);
                        }
                        putchar('\n');
                        }
                       putchar('\n');
                      int xoy=rand()%2;
                      if(xoy==0){                  // on part à l'horizontale
                        if(y==9){      //si la première case est au bord de la ligne 
                          z=y-1;
                        }
                        else{
                          z=y+1;
                        }
                        grille[x][z]=1;    //placement case 2
                      }
                      else if(xoy==1){           //on part à la verticale
                        if(x==9){     //si la première case est au bord de la colonne
                          z=x-1;
                        }
                        else{
                          z=x+1;
                        }
                        grille[z][y]=1;    //placement case 2
                      }
                      for(int i=0; i<10; i++){      //boucle d'affichage de la grille 
                        for(int j=0;j<10;j++){
                          printf("%d", grille[i][j]);
                        }
                        putchar('\n');
                      }
                    }
                        
                    

                    Et ce que ça a donné au terminal (dans le cas où la première case nous embête) :

                    0000000000
                    0000000000
                    0000000000
                    0000000001
                    0000000000
                    0000000000
                    0000000000
                    0000000000
                    0000000000
                    0000000000
                    
                    0000000000
                    0000000000
                    0000000000
                    0000000011
                    0000000000
                    0000000000
                    0000000000
                    0000000000
                    0000000000
                    0000000000
                    




                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 octobre 2019 à 16:59:16

                      Hello,

                      • Pour info, int grillle[....][....]={0}; suffit pour mettre tout le tableau à zéro
                      • tu n'as pas pensé à écrire une fonction pour afficher ton tableau (2 x le même code, lignes 37-42 et 63-68) ?
                      • évite le franglais: grille et SIZE: décide d'une langue une fois pour toute
                      • Partager sur Facebook
                      • Partager sur Twitter

                      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                        18 novembre 2019 à 18:34:34

                        edgarjacobs a écrit:

                        Hello,

                        • Pour info, int grillle[....][....]={0}; suffit pour mettre tout le tableau à zéro
                        • tu n'as pas pensé à écrire une fonction pour afficher ton tableau (2 x le même code, lignes 37-42 et 63-68) ?
                        • évite le franglais: grille et SIZE: décide d'une langue une fois pour toute

                        C'est que je ne maîtrise pas beaucoup l'anglais..........
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Bataille navale

                        × 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