Partage
  • Partager sur Facebook
  • Partager sur Twitter

Modifier une static depuis une classe fille

Sujet résolu
    1 juin 2019 à 15:47:41

    Bonjour,

    Alors voila, je suis en train de faire un jeu d'échec (projet pour un cours) et pour ce faire, j'ai décidé de créer une classe mère "Piece" dont

    hériteront toutes les pièces du jeu. 

    Cependant, je suis face à un problème. J'ai une classe "Pion" qui hérite de "Piece", et je voudrais incrémenter un compteur à chaque fois que je crée un nouvel objet de type "Pion". J'ai donc déclaré ce compteur en temps que static dans la classe mère et je l'incrémente dans le constructeur de la classe fille. Cependant, ça me génère une exception de type "System.TypeInitializationException". 

    J'ai bien essayé de faire l'incrémentation dans un constructeur static, mais ça ne l'appel qu'une seule fois. Auriez-vous une idée? Je n'ai trouvé aucune solution à ce problème, donc je crains que ce ne soit pas possible :(

    Je vous met ci-dessous le constructeur de la classe mère ainsi que la méthode ou j'essaie d'incrémenter le compteur (la classe fille hérite entièrement du constructeur de la classe mère):

    Constructeur de la classe mère:

    /*Compteur de pièces déjà créées (pour la position sur l'échiquier au démarrage):
             de gauche à droite:
             Pion       : {nbBlanc, nbNoir}
             Tour       : {nbBlanc, nbNoir}
             Cavalier   : {nbBlanc, nbNoir}
             fou        : {nbBlanc, nbNoir}
             Dame       : {nbBlanc, nbNoir}
             Roi        : {nbBlanc, nbNoir}*/
            static protected int[,] countPiece = new int[6, 2] { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
    
            //Paral = Récupération de la Form1
            //Color = Couleur de la pièce(0 = blanc, 1 = noir)
            //Picture = Nom de l'image
            //Ratio = Ratio de la taille de l'image par rapport à sa taille maximale
            //X et Y = Positions en X et en Y
            public Piece(Projet_Echec.Form1 Paral, bool Color, string Picture = "", double Ratio = 0.0, int x = 0, int y = 0)
            {
                //Changement de la taille de la picturebox
                SetPicture(Picture);
                SetSize(Ratio);
                
                ChestPiece.SizeMode = PictureBoxSizeMode.StretchImage;
                ChestPiece.Location = new Point(y, x);
                Paral.Controls.Add(ChestPiece);
    
                //Attache un évènement à la pictureBoxe venant d'être crée
                this.ChestPiece.Click += new System.EventHandler(this.ChestPiece_Click);
                
                //Sauvegarde des paramètres de la Form1
                FormTransfert = Paral;
    
                //Incrémentation du compteur de pièce
                PersonalInit(Color);
            }

    Méthode pour incrémenter le compteur de pion:

            override protected void PersonalInit(bool Couleur)
            {
                int TestCouleur = 0;
    
                //Conversion d'un booléen en int
                TestCouleur = Convert.ToInt32(Couleur);
    
                //Incrémentation du compteur de pion
                countPiece[0, TestCouleur] = 10;
            }



    • Partager sur Facebook
    • Partager sur Twitter
      3 juin 2019 à 15:46:01

      Y'a pas de pièges :

          abstract class Pion
          {
              public static int count = 0;
          }
      
          sealed class Tour : Pion
          {
              public Tour()
              {
                  Pion.count++;
              }
          }

      Pour l'erreur, le debugger t'indique sur quelle ligne ?

      Aussi, as-tu vraiment besoin d'un constructeur pour la classe 'Piece' ?

      Je pense que ton programme est un peu trop brouillon. L'architecture est étrange.

      -
      Edité par LilyKianii 3 juin 2019 à 15:57:08

      • Partager sur Facebook
      • Partager sur Twitter
        3 juin 2019 à 16:36:52

        Il m'indique l'exception sur la fin de la ligne du constructeur de mon Pion

        class Pion : Piece
            {
                public Pion(Projet_Echec.Form1 Paral, bool Color, string Picture = "", double Ratio = 0.0, int x = 0, int y = 0) : base (Paral, Color, Picture, Ratio, x, y)
                {
        
                }
            }

        LilyKianii a écrit:

        Aussi, as-tu vraiment besoin d'un constructeur pour la classe 'Piece' ?

        Je pense que ton programme est un peu trop brouillon. L'architecture est étrange.

        Je veux utiliser un constructeur unique pour toutes mes pièces, donc je fais le constructeur de la classe mère et je le fais hériter aux autres classe de pièces

        -
        Edité par Masterzeus64 3 juin 2019 à 16:40:41

        • Partager sur Facebook
        • Partager sur Twitter
          3 juin 2019 à 17:59:56

          On ne peut pas faire hériter des constructeurs. Ici, vous indiquez juste le constructeur de la classe mère à appeler et les arguments à lui passer.

          Aussi, la conception, c'est très subjectif je trouve. Et je n'aime pas trop donner des leçons (surtout, je ne peux vraiment pas me vanter de régner sur le sujet), mais je pense que :

          • Piece ne sera jamais instancié
          • Les Form n'ont pas grand chose à faire dans le constructeur des pièces (j'avais pô vu avant)

          J'aurais fait la chose de cette façon :

          La classe Mère Piece

              public abstract class Piece
              {
                  public int x, y;
          
                  protected Piece(int x, int y) { this.x = x; this.y = y; }
          
                  public override String ToString() { return String.Format("{0} in ({1} - {2})", this.GetType().Name, this.x, this.y); }
              }

          C'est minimaliste :

          • Les coordonnées de la pièce sur le plateau.
          • un constructeur de classe mère qui va définir le body (cf les constructeurs des classes filles)
          • on override le ToString pour toute les instances filles

          Pour les classes filles, tout bêtement

          sealed class Tower : Piece
              {
                  public Tower(int x, int y) : base(x, y)
                  {
                  }
              }
          
              sealed class King : Piece
              {
                  public King() : this(4, 0) { }
          
                  public King(int x, int y) : base(x, y)
                  {
                  }
              }

          A ça, on peut rajouter une classe Player

              public class Player
              {
          //Toute les pièces du joueur public List<Piece> Pieces { get; private set; }
          //On met Initializer à part. Parce que je préfère !
          //et parce que si on veut garder le même joueur (avec un score) mais remettre le jeu à 0,
          //on peut l'appeler sans passer par le constructeur void Initializer() { this.Pieces = new List<Piece>(); this.Pieces.Add(new Tower(0,0)); this.Pieces.Add(new Tower(7,0)); this.Pieces.Add(new Fou(0, 0)); this.Pieces.Add(new Fou(0, 0)); this.Pieces.Add(new King()); //etc... } public void LosePiece(int x, int y) { Piece toRemove = Pieces.Find(p => (p.x == x) && (p.y == y)); this.Pieces.Remove(toRemove); } public Player() { Initializer(); } }


          De cette façon,

                      Player one = new Player();
          
                      //Nbr de Pièces après création du joueur
                      Console.WriteLine(one.Pieces.Count);
          
                      //Do stuff in board
          
                      //La pièce en 7,0 se fait manger 
                      one.LosePiece(7, 0);
          
                      //Nbr de Pièces après s'en être fait manger une
                      Console.WriteLine(one.Pieces.Count);


          La différence, c'est que tu as une Liste de pièces au lieu d'un nombre de pièces. Tu peux donc savoir quelle pièce il te reste, quel type de pièce et leur position sur le tableau

          King p = new King();
          Console.WriteLine(k.ToString());

          Bref, je me suis perdue ! Met un breakpoint dans le constructeur de ta classe mère.




          -
          Edité par LilyKianii 3 juin 2019 à 18:10:11

          • Partager sur Facebook
          • Partager sur Twitter
            4 juin 2019 à 8:05:17

            Je te remercie pour tes remarques, je vois une meilleure méthode pour réaliser mon projet maintenant :)

            Pour ce qui est des Form dans les classes, je les utilises pour pouvoir afficher une picturebox depuis une classe fille (vu que je génère mes picturebox dans les classe filles).

            Mais du coup, pour revenir à ma question première, comment je fais si je veux modifier une static dans un constructeur de classe fille? Est-ce que c'est même possible?

            • Partager sur Facebook
            • Partager sur Twitter
              4 juin 2019 à 10:58:53

              Masterzeus64 a écrit:

              Mais du coup, pour revenir à ma question première, comment je fais si je veux modifier une static dans un constructeur de classe fille? Est-ce que c'est même possible?

              Le problème c'est l'erreur. Pas le fait d'utiliser une static.

              Autrement dit, tu as fait une bêtise dans ton constructeur de Piece.

              • Partager sur Facebook
              • Partager sur Twitter
                5 juin 2019 à 8:56:48

                ok, merci, je changer ça alors^^
                • Partager sur Facebook
                • Partager sur Twitter

                Modifier une static depuis une classe fille

                × 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