Partage
  • Partager sur Facebook
  • Partager sur Twitter

Suppression d'un element de vector

erase()

Sujet résolu
    11 juin 2008 à 0:26:27

    Bonsoir,

    J'ai un petit problème pour la suppression d'un élément d'un vecteur.

    Pour faire simple. J'ai comme projet à réaliser un jeu de bataille navale.
    J'ai une classe "Joueur", dont hérite "Humain" (pour un joueur géré par un humain) et "Comp" (pour un joueur géré par l'ordi).
    Joueur a un de ses attributs vector<Bateau*> m_liste et vector<Case> m_GrilleCible. ("Bateau" est une classe dont hérite chaque type de bateau : "PorteAvion", "Croiseur" etc)


    Voici la méthode qui me pose problème (le pb se trouve vers la fin de la méthode, j'ai mis un commentaire)
    void Humain::Attaque (Joueur *Joueur_Cible, int nbx, int nby)
    {
        int i; // pour for
        int presence; // variable qui permet de savoir si on a déjà tiré sur la case "cible"
        Case cible; // La case que va sélectionner le joueur qui tire
    
    
        cout<<"Tour d'attaque de "<<m_nom<<endl;
        cout<<"Choisissez la case sur laquelle vous voulez tirer."<<endl;
        // Test pour voir si la case qui va être choisie n'a pas déjà été ciblié
        do
        {
            presence = 0;
            // On vérifie que la case choisie existe bien
            do {    cin>>cible; } while (cible.x <= 0 || cible.x > nbx || cible.y <= 0 || cible.y > nby);
    
            for (i=0;i<m_GrilleCible.size();i++)
            {
                if (cible == m_GrilleCible.at(i))
                {   presence = 1;   break;  }
            }
    
            if (presence)
                cout<<"Vous avez déjà tiré sur cette case, choissisez en une autre"<<endl;
        } while (presence);
    
        m_GrilleCible.push_back (cible); // Ajout de la case à la liste des case déja ciblées
    
        // Vérification si bateau touché
        // On regarde pour chaque bateau qu'il reste au joueur cible
        bool touche;
    
        for (i=0;i<Joueur_Cible->getNbBateaux();i++)
        {
            touche = Joueur_Cible->getListe(i)->Touche(cible,i);
            if (touche) // Si un des bateaux est touché
            {
                cout<<"Bateau touché"<<endl;
    
                Joueur_Cible->getListe(i)->setEtat(); // On retire un "pv" au bateau
                                                      // setEtat fait "m_etat -= m_etat"
                if (Joueur_Cible->getListe(i)->estDetruit()) // Si le bateau n'a plus de pv => détruit
                                                             // estDetruit regarde juste si m_etat est à 0 ou plus
                {
                    cout<<"Bateau coulé"<<endl;
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
                    // Voilà mon problème, mon programme ce termine après ça, alors qu'il reste des instructions
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
                    Joueur_Cible->getListe().erase (Joueur_Cible->getListe().begin()+i); // On retire le bateau de la liste
                    cout<<"Blabla"<<endl; // n'apparait jamais.
                    Joueur_Cible->setNbBateaux (); // On soustraire 1 au nombre de bateaux restant au joueur
                    
                }
    
                break;
            }
        }
    
        if (!touche)
        {   cout<<"Z'êtes une grosse buse vous l'avez raté"<<endl;  }
        cout<<endl;
    }
    


    GetListe est une méthode de joueur, je vous la met :
    std::vector<Bateau*> getListe () {   return m_liste;   }
    


    Je pense que j'ai mis et dit tout ce qu'il fallait savoir pour comprendre cette méthode.
    Si vous voyez pourquoi mon programme se termine, merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      11 juin 2008 à 0:54:43

      getListe(i) ... cela sent la "décapsulation." (ou pourquoi j'ai un discours très négatif à l'encontre des accesseurs)

      Aie confiance en tes objets, et donne leur des responsabilités!
      Ce n'est pas à l'attaquant d'aller bidouiller les données internes de l'attaqué.

      L'algo de l'attaquant se résume à deux choses:
      1- position = déterminer où l'on tire (virtuel)
      2- resultat = cible->prendCa(position)
      resultat == enum { plouf, touché, coulé }

      Et c'est le défendant qui regarde s'il a un bateau à la position bombardée, et si oui, si le tir coule le bateau.


      Après ... je ne suis pas sûr qu'il y ait intérêt à faire des bateaux côté défendant des objets. Côté algo de décision de l'IA, oui. Mais pour le reste, je ne suis pas persuadé de la pertinence.



      Sinon, ton problème vient du fait que tu retournes une copie.
      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        11 juin 2008 à 1:22:37

        Pour getListe (i), voici ce que ça donne :

        Bateau* getListe (int i) {   return m_liste.at(i);   }
        


        "L'algo de l'attaquant se résume à deux choses:
        1- position = déterminer où l'on tire (virtuel)
        2- resultat = cible->prendCa(position)
        resultat == enum { plouf, touché, coulé }"
        En effet me semble même plus logique et moins "bourrin" de faire comme ça, je vais de ce pas modifier.

        "Sinon, ton problème vient du fait que tu retournes une copie."
        Je ne comprends pas bien, tu veux dire que mon return m_liste de getListe () est une copies, et que donc quand je supprime un élément de la liste, ça ne le fait que dans la copie et non dans l'originale? Mais pourquoi ça me termine le programme même si c'est ça, je n'ai pas d'erreur, c'est comme s'il était arrivé au bout de l'exécution.
        • Partager sur Facebook
        • Partager sur Twitter
          11 juin 2008 à 8:44:27

          C'est ça.
          Parce que le begin() et le erase() viennent de deux objets différents (parce que copie), ce qui ne peut provoquer des gros problèmes.
          • Partager sur Facebook
          • Partager sur Twitter
          C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
            11 juin 2008 à 20:15:19

            Merci beaucoup, en modifiant l'algo, tout marche nickel, et c'est beaucoup plus clair au niveau du code en plus (c'est plus "joli" !)

            Bon plus que l'IA et les protections au niveau du placement des bateau et ce sera fini !
            • Partager sur Facebook
            • Partager sur Twitter

            Suppression d'un element de vector

            × 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