Erreur de segmentation et test d'existence

Fermé
kenoro Messages postés 2 Date d'inscription dimanche 13 janvier 2013 Statut Membre Dernière intervention 13 janvier 2013 - Modifié par kenoro le 13/01/2013 à 14:09
kenoro Messages postés 2 Date d'inscription dimanche 13 janvier 2013 Statut Membre Dernière intervention 13 janvier 2013 - 13 janv. 2013 à 14:06
Bonjour,
J'ai pour projet de créer un jeu du Same (on élimine des groupes de billes de même couleur, en espérant toutes les éliminer). L'ennui c'est que lorsque j'essaye de supprimer des billes, j'ai quelques fois des erreurs de segmentations et souvent au moment ou mon code est censé replonger dans ma fonction SupprimerVoisins().
J'ai pensé que ça pourrait venir d'un problème d'existence de la bille dont -on compare la couleur.
J'ai donc blindé mon code de tests d'existences avant les comparaisons de couleur pour y palier.... Rien a faire, j'ai toujours des erreurs de segmentation.
J'ai l'impression que mon programme n'effectue pas les tests.

J'aurais besoin de votre aide s'il vous plaît! :)
Quelqu'un aurait-il une autre idée sur l'origine de cette erreur? Et/ou pourrait-il m'expliqué (si j'ai raison) pourquoi mon test n'empêche pas l'erreur de segmentation?

Merci d'avance pour vos réponse,
Cordialement.

Voici mon code (désolé pour l'esthétique):
Fenetre:: Fenetre(){ 
 RenderWindow app(VideoMode(800, 600, 32), "Futur Same! "); 
 Grille* grille= new Grille(); 
    TableDeJeu jeu ; 



    Bille*** tab; 

     //  Creer un tableau de lignes 
  tab = new Bille**[15]; 

  //  Creer chaque ligne 
   for(int ligne = 0; ligne <15; ligne++) 
   { 
    cout<<"Lignes faites"<<endl; 
    tab[ligne]= new Bille*[15]; 
    //  on declare chaque case comme etant vide 
    for(int col = 0; col < 15; col++) 
    tab[ligne][col] = NULL; 

    cout<<"Colonnes faites et mises à 0."<<endl; 
   } 
    nRestant=15*15; 
    Image backgroundImage; 
    Sprite backgroundSprite; 
    if(!backgroundImage.LoadFromFile("background.png")) 
 { 
  cerr << "Erreur pendant le chargement du fond d'ecran" << endl; 
  //return EXIT_FAILURE; // On ferme le programme 
 } 
 else 
 { 
  backgroundSprite.SetImage(backgroundImage); 
  backgroundSprite.Move(200, 100); 
  backgroundSprite.SetScale(0.666666, 1); 
 } 

  for(int ligne= 0; ligne < 15; ligne++) 
  { 
   for(int colon = 0; colon < 15; colon++) 
   { 
    Color couleur=jeu.GetCouleurCase(ligne,colon); 

    if(couleur==Color::Blue){ 
    tab[ligne][colon]=new Bille("Blue.png",ligne,colon); 
    tab[ligne][colon]->mySprite.Move(200+colon*(tab[ligne][colon]->mySprite.GetSize().x),100+ligne*(tab[ligne][colon]->mySprite.GetSize().y)); 
    cout<<"Bille Bleue créée"<<endl;} 
    else if(couleur==Color::Red){ 
    tab[ligne][colon]=new Bille("Red.png",ligne,colon); 
    tab[ligne][colon]->mySprite.Move(200+colon*(tab[ligne][colon]->mySprite.GetSize().x),100+ligne*(tab[ligne][colon]->mySprite.GetSize().y)); 
    cout<<"Bille Rouge créée"<<endl;} 
    else if(couleur==Color::Yellow){ 
    tab[ligne][colon]=new Bille("Yellow.png",ligne,colon); 
    tab[ligne][colon]->mySprite.Move(200+colon*(tab[ligne][colon]->mySprite.GetSize().x),100+ligne*(tab[ligne][colon]->mySprite.GetSize().y)); 
    cout<<"Bille Jaune créée"<<endl;} 
    else{ 
    tab[ligne][colon]=new Bille("Green.png",ligne,colon); 
    tab[ligne][colon]->mySprite.Move(200+colon*(tab[ligne][colon]->mySprite.GetSize().x),100+ligne*(tab[ligne][colon]->mySprite.GetSize().y)); 
    cout<<"Bille Verte créée"<<endl;} 

   } 
  } 


    cout<<"fin"<<endl; 
    // Boucle principale 
    while (app.IsOpened()) 
    { 

       Event event; 

        while(app.GetEvent(event)) // Boucle des évènements 
  { 
   switch(event.Type) 
   { 
    case Event::Closed : // Croix de fermeture 
     app.Close(); 
     break; 

    case Event::KeyPressed : // Appui sur une touche 
    { 
     switch(event.Key.Code) 
     { 
      case Key::Escape : // Touche echap 
       app.Close(); 
       break; 

      case sf::Key::F1 : // Touche F1 
       cout<<"Passer en mode plein écran?"<<endl; 
       break; 
     } 
    } 
    break; 
   } 
  } 

  const Input & input = app.GetInput(); // input : référence constante 

  
  if (input.IsMouseButtonDown(Mouse::Right)) // Bouton droit appuyé 
  { 
   cout<<"Tu as cliqué avec le bouton droit!"<<endl; 
  } 
  if (input.IsMouseButtonDown(Mouse::Left)) // Bouton gauche appuyé 
  { 
   int mouseX = input.GetMouseX(); // Coordonnée X de la souris 
   int mouseY = input.GetMouseY(); // Coordonnée Y de la souris 
   cout<<"Coordonnnées du clic ("<<mouseX<<","<<mouseY<<")."<<endl; 
   cout<<"Tu as cliqué avec le bouton gauche!"<<endl; 
   for(int ligne= 0; ligne < 15; ligne++) 
   { 
    for(int colon = 0; colon < 15; colon++) 
    { 
     if(!tab[ligne][colon]) 
      continue; 
     //Comparaison au niveau des colonnes 
     if(((200+colon*(tab[ligne][colon]->mySprite.GetSize().x))<mouseX) && ((200+(colon+1)*(tab[ligne][colon]->mySprite.GetSize().x))>mouseX)){ 
      //Comparaison au niveau des lignes 
      if((mouseY>(100+ligne*(tab[ligne][colon]->mySprite.GetSize().y))) && (mouseY<(100+(ligne+1)*(tab[ligne][colon]->mySprite.GetSize().y)))){ 
       cout<<"Suppression de la bille ["<<ligne<<","<<colon<<"]"<<endl; 
       Suppression(tab,ligne,colon); 
       cout<<"Suppression de la bille ["<<ligne<<","<<colon<<"] terminée."<<endl; 
      } 
     } 
    } 
   } 
  } 

  app.Clear(); 
  app.Draw(*(grille->carre)); 
  app.Draw(backgroundSprite); 
  for(int lig= 0; lig < 15; lig++) 
  { 
   for(int colo = 0; colo< 15; colo++) 
   { 
    if(tab[lig][colo]) 
     app.Draw(tab[lig][colo]->mySprite); 


   } 
  } 
  String GameWin, GameOver; 
  GameWin.SetText(""); 
  GameOver.SetText(""); 
  GameOver.SetSize(50); 
  GameOver.SetPosition(400,300); 
  GameWin.SetSize(50); 
  GameWin.SetPosition(400,300); 

  if(GagnerOuPas(tab) && nRestant<=4) 
  app.Draw(GameWin); 
  if((!GagnerOuPas(tab)) && nRestant<=4) 
  app.Draw(GameOver); 

  app.Display(); 
  //cout<<"    END  "<<endl; 


 } 


} 


int Fenetre:: Suppression(Bille*** tableau, int lig, int col){ 
     cout<<"Entré dans suppression"<<endl; 
 //  Verifier si la bille existe 
  if(lig < 0 || lig >= 15 || col < 0 || col >= 15){ 
  cout<<"Hors du tableau"<<endl; 
  return -1;} 

  if(!tableau[lig][col]){ 
  cout<<"Pas de bille!"<<endl; 
  return -1;} 
  else{ 
  Color couleur=tableau[lig][col]->couleur; 
   int nSuppr = -1; 
   cout<<"Début de suppression"<<endl; 
   //On vérifie à chaque fois si la bille est dans le tableau, 
   //si son voisin existe ou est de même couleur, 
   //Puis on entre dans la processus de suppresssion. 
    if((lig - 1 >= 0)){ 
     if(tableau[lig - 1][col]){ 
      if(tableau[lig - 1][col]->couleur==couleur){ 
      nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
      nRestant -= nSuppr; 
      } 
     } 
     else{ 
      nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
      nRestant -= nSuppr; 
      } 
    } 
    else if((lig + 1 < 15)){ 
     if(tableau[lig + 1][col]){ 
      if(tableau[lig + 1][col]->couleur==couleur){ 
       nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
       nRestant -= nSuppr;} 
       } 
     else{ 
      nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
      nRestant -= nSuppr; 
      } 
      } 
      else if ((col-1 >=0)){ 
     if(tableau[lig][col-1]){ 
      if(tableau[lig][col - 1]->couleur==couleur){ 
       nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
       nRestant -= nSuppr;} 
       } 
     else{ 
      nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
      nRestant -= nSuppr; 
      } 
      } 
       else if ((col + 1 < 15)){ 
     if(tableau[lig][col+1]){ 
      if(tableau[lig][col + 1]->couleur==couleur){ 
       nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
       nRestant -= nSuppr;} 
       } 
     else{ 
      nSuppr=SuppressionEffective(tableau,lig,col,couleur); 
      nRestant -= nSuppr; 
      } 
      } 
    else 
    cout<<"raté"<<endl; 


    //On tasse le tableau 
    //TasserTableau(tableau); 
    // Soustraction du nombre de supressions au nombre de restants 


 cout<<"Sortie de suppression."<<endl; 
 return nSuppr; 
} 



} 

/* refh'egtro */ 



int Fenetre:: SuppressionVoisins(Bille*** tableau, int lig, int col, Color couleur, string direction){ 
 //  Verifier si la bille est dans la table 
  if(lig < 0 || lig >= 15 || col < 0 || col >= 15){ 
    cout<<"Hors du tableau"<<endl; 
    return 0;} 

  if(!tableau[lig][col]){ 
    return 0;} 
  //  Verifier si elle a la meme couleur 
  if(tableau[lig][col]->couleur== couleur){ 
 int nSuppr = 1; 
 free(tableau[lig][col]); 
 tableau[lig][col]=NULL; 
 //  On verifie la direction interdite et on supprime 
 if(direction != "DIRECTION_UP") 
  nSuppr += SuppressionVoisins(tableau,lig - 1, col, couleur, "DIRECTION_DOWN"); 

 if(direction != "DIRECTION_DOWN") 
  nSuppr += SuppressionVoisins(tableau,lig + 1, col, couleur, "DIRECTION_UP"); 

 if(direction != "DIRECTION_LEFT") 
  nSuppr += SuppressionVoisins(tableau,lig, col-1, couleur, "DIRECTION_RIGHT"); 

 if(direction != "DIRECTION_RIGHT") 
  nSuppr += SuppressionVoisins(tableau,lig, col+1, couleur, "DIRECTION_LEFT"); 
 //  Retourner le nombre total de billes supprimées 
 return nSuppr; 
  } 
  else{cout<<"Voisin n'étant pas de même couleur."<<endl; 
 return 4;} 

} 

int Fenetre:: SuppressionEffective(Bille***tableau,int lig,int col,Color couleur){ 
 int nSuppr; 
  nSuppr = 1; 
     cout<<"fait1"<<endl; 
    free(tableau[lig][col]); 
    tableau[lig][col] = NULL; 
   //Suppression des cases adjacentes 
    //suppression case du dessus 
    if(tableau[lig - 1][col]){ 
    if((lig - 1 >= 0) && (tableau[lig - 1][col]->couleur==couleur) ){ 
    cout<<"fait2"<<endl; 
    nSuppr+= SuppressionVoisins(tableau,lig-1,col,couleur,"DIRECTION_DOWN");}} 
    //suppression case du dessous 
    if(tableau[lig + 1][col]){ 
    if((lig + 1 < sizeof(tableau)) && (tableau[lig + 1][col]->couleur==couleur)){ 
    cout<<"fait3"<<endl; 
    nSuppr+= SuppressionVoisins(tableau,lig+1,col,couleur,"DIRECTION_UP");}} 
    //suppression case de gauche 
    if(tableau[lig][col - 1]){ 
    if((col - 1 >= 0) && (tableau[lig][col - 1]->couleur==couleur)){ 
    cout<<"fait4"<<endl; 
    nSuppr+= SuppressionVoisins(tableau,lig,col-1,couleur,"DIRECTION_RIGHT");}} 
    //suppression case de droite 
    if(tableau[lig][col + 1]){ 
    if((col + 1 < sizeof(tableau)) && (tableau[lig][col + 1]->couleur==couleur)){ 
    cout<<"fait5"<<endl; 
    nSuppr+= SuppressionVoisins(tableau,lig,col+1,couleur,"DIRECTION_LEFT");}} 

 } 

void Fenetre::TasserTableau(Bille*** tab) 
{ 
  //  Deplacer tout en bas 
  for(int col = 0; col < 15; col++) 
  { 
    int nLigneVideSuivante = 14; 
    int nLigneOccupeeSuivante = nLigneVideSuivante; 
    while((nLigneOccupeeSuivante >= 0) && (nLigneVideSuivante >= 0)) 
    { 
      //  Trouver la ligne vide 
      while((nLigneVideSuivante >= 0) && (!tab[nLigneVideSuivante][col])) 
        nLigneVideSuivante--; 
      if(nLigneVideSuivante >= 0) 
      { 
        // Trouver la ligne occupee suivante à partir de la ligne vide suivante 
        nLigneOccupeeSuivante = nLigneVideSuivante - 1; 
        while((nLigneOccupeeSuivante >= 0) && (!tab[nLigneOccupeeSuivante][col])) 
         nLigneOccupeeSuivante--; 
        if(nLigneOccupeeSuivante >= 0) 
        { 
          //  Deplacer la bille de la case occupee à la case vide 
          tab[nLigneVideSuivante][col] = tab[nLigneOccupeeSuivante][col]; 

          if(!tab[nLigneOccupeeSuivante][col]){ 
    free(tab[nLigneOccupeeSuivante][col]); 
          tab[nLigneOccupeeSuivante][col] = NULL;} 
      } 
    } 
  } 
  //  Deplacer tout de droite à gauche 
  int nColonneVideSuivante = 0; 
  int nColonneOccupeeSuivante = nColonneVideSuivante; 
  while((nColonneVideSuivante < 15) && (nColonneOccupeeSuivante < 15)) 
  { 
    //  trouver la prochaine colonne vide 
    while((nColonneVideSuivante < 15) && (!tab[14][nColonneVideSuivante])) 
      nColonneVideSuivante++; 
    if(nColonneVideSuivante <15) 
    { 
      //  On cherche la prochaine colonne avec quelque chose dedans 
      nColonneOccupeeSuivante = nColonneVideSuivante + 1; 
      while((nColonneOccupeeSuivante <15) && !tab[14][nColonneOccupeeSuivante]) 
        nColonneOccupeeSuivante++; 
      if(nColonneOccupeeSuivante < 15) 
      { 
        //  Deplacer la colonne vers la gauche 
        for(int lig = 0; lig < 15; lig++) 
        { 
          tab[lig][nColonneVideSuivante] = 
            tab[lig][nColonneOccupeeSuivante]; 
            if(!tab[lig][nColonneOccupeeSuivante]){ 
          free(tab[lig][nColonneOccupeeSuivante]); 
          tab[lig][nColonneOccupeeSuivante] = NULL;} 
        } 
      } 
    } 
  } 
} 
} 

bool Fenetre :: GagnerOuPas(Bille*** tableau)const{ 

  // On parcourt le tableau colonne par colonne ,de gauche à droite 
  for(int col = 0; col < 15; col++) 
  { 
    //  Ligne par ligne du bas vers le haut 
    for(int lig = 14; lig >= 0; lig--) 
    { 
      Color couleur=tableau[lig][col]->couleur; 

      //  Quand on touche l'arriere plan,cette colonne est faite 
      if(!tableau[lig][col]) 
        break; 
      else 
      { 
        //  Verifier au dessus et à droite 
        if(lig - 1 >= 0 && 
           tableau[lig - 1][col]->couleur == couleur) 
          return false; 
        else if(col + 1 < 15 && tableau[lig][col + 1]->couleur == couleur) 
          return false; 
      } 
    } 
  } 
  //  pas de billes adjacentes de meme couleur 
  return true; 
} 




A voir également:

1 réponse

fouji Messages postés 864 Date d'inscription mardi 8 juin 2010 Statut Membre Dernière intervention 14 septembre 2019 130
13 janv. 2013 à 14:01
Bonjour,

Si vous souhaitez toutefois avoir une réponse, il serai préférable que vous y mettiez un peu de politesse (vous savez les s'il vous plait, les merci etc.....)

Nous ne sommes pas vos chiens !

Cordialement.
0
kenoro Messages postés 2 Date d'inscription dimanche 13 janvier 2013 Statut Membre Dernière intervention 13 janvier 2013
13 janv. 2013 à 14:06
Loin de moi l'idée de prendre quelqu'un pour un chien. Je me suis plus concentré pour être concis et j'en ai donc peut-être oublier les politesse. Pas la peine de s'énerver fouji, je n'exige jamais, ett ce n'est pas aujourd'hui que je commencerai ;).
Je vais tenter de modifier le message.
0