none
Copying variables from one class object to another RRS feed

  • Question

  • Hello!So i have a class called "Weapon" that has "Ammo" as an int var.I create an object(let's say M4) and set Ammo to 32,and then i created another object(let's call it Ak) and give it the M4.When i try to change Ammo for Ak,it will change the Ammo for M4 with the same value too and I don't want that.I just want to copy the values of M4 to Ak.Why does it act like a pointer to M4 and how can i copy the values(if there are more than one in the class) of M4 to Ak without affecting the M4 values when changing the Ak.Ammo?

    static void Main(string[] args)
    {
    Weapon M4=new Weapon();
    M4.Ammo=32;
    Weapon Ak=M4;
    Ak.Ammo=16;
    Console.WriteLine(M4.Ammo);
    //I expect 32,but it will change to 16 beacuse of Ak.Ammo
    Console.WriteLine(Ak.Ammo);//I expect 16
    Console.ReadKey();
    }
    Class Weapon
    {
    public int Ammo{get;set;}
    }



    • Edited by Ax1aL Sunday, March 18, 2018 7:14 PM
    Sunday, March 18, 2018 7:12 PM

Answers

  • Hello,

     So, how is your project status? Just wondered if any of the replies were helpful...

    Creating the base allows for improvements with low code change.  Enums used to

    describe weapon properties make adding new weapons a snap.  Even custom user

    defined weapon properties in a Constructor are useful. I defined a namespace for

    naming conventions flexability.

     

    The following code could work as a base frame work. 

    namespace GenericWeapon
    {
        [Flags]
        enum Ammo : int
        {
            _Undefine = 0,
            _9m  = 1,
            _12  = 2,
            _308 = 4,
            _45  = 8,
            _50  = 16,
            _556 = 32,
            _762 = 64
        }
    
        [Flags]
        enum Frame : byte
        {
            Undefine = 0,
            Pistol = 1,
            Shotgun = 2,
            Rifle = 4,
        }
    
        enum Capacity : int
        {
            Undefine = 0,
            Ammo2 = 2,
            Ammo6 = 6,
            Ammo7 = 7,
            Ammo15 = 15,
            Ammo30 = 30
        }
    
        [Flags]
        enum Mode : byte
        {
            Undefine = 0,
            Auto = 1,
            Bolt = 2,
            Pump = 4,
            Semi = 8,
            Single = 16
        }
    
        enum Style
        {
            Undefine = 0,
            Colt45,
            DesertEagle,
            AK47,
            M4,
            M9,
            M16,
            Mosberg,
            Springfield,
        }
    
        class Weapon
        {
            public Ammo AmmoType { get; private set; }
            public Capacity CapCount { get; private set; }
            public Frame FrameType { get; private set; }
            public Mode FireMode { get; private set; }
            public object NameTag { get; private set; }
    
            public float FireRate { get; private set; }
            public float ReloadTime { get; private set; }
    
            // User defined
            //
            public Weapon( string tag, Ammo a, Capacity c, Frame f, Mode m, float rate, float reload )
            {
                NameTag = ( tag == null ? "Undefined" : tag );
                AmmoType = a;
                CapCount = c;
                FrameType = f;
                FireMode = m;
                FireRate = ( rate < 0.0f ? 0.0f : rate );
                ReloadTime = ( reload < 0.0f ? 0.0f : ( reload > 15.0f ? 15.0f : reload ) );
            }
    
            // Select Preset
            public Weapon( Style nt )
            {
                switch ( nt )
                {
                    case Style.AK47:
                    AmmoType = Ammo._762;
                    FrameType = Frame.Rifle;
                    FireMode = Mode.Single | Mode.Auto;
                    FireRate = 5.0f;
                    CapCount = Capacity.Ammo30;
                    NameTag = Style.AK47;
                    ReloadTime = 15.0f;
                    break;
    
                    case Style.DesertEagle:
                    AmmoType = Ammo._45;
                    FrameType = Frame.Pistol;
                    FireRate = 1.0f;
                    FireMode = Mode.Single;
                    CapCount = Capacity.Ammo7;
                    NameTag = Style.DesertEagle;
                    ReloadTime = 10.0f;
                    break;
    
                    case Style.Mosberg:
                    AmmoType = Ammo._12;
                    FrameType = Frame.Shotgun;
                    FireRate = 3.0f;
                    FireMode = Mode.Single;
                    CapCount = Capacity.Ammo2;
                    NameTag = "Double Barrel";
                    ReloadTime = 15.0f;
                    break;
    
                    default:
                    break;
                }
            }
        }
    }

     The above code is just a small part of what is possible. Every aspect of a custom

    class is boundless. However, the bigger the class the more code to maintain for

    changes or debugging.

     Just extra information for you to consider, thanks :)

    • Marked as answer by Ax1aL Tuesday, March 20, 2018 4:00 PM
    Tuesday, March 20, 2018 3:44 AM

All replies

  • In some cases, you can replace ‘class Weapon’ with ‘struct Weapon’. Try it.

    If you want classes, then write

       Weapon Ak = new Weapon(M4);

    and also define the corresponding constructors inside the class.



    Sunday, March 18, 2018 8:02 PM
  • Hello,

     

     Your Weapon Class implementation will determine functionality.

    At Runtime, the code executes "Weapon M4 = new Weapon()"

    which will allocate "new" memory for the objects defined in

    class Weapon as "M4".  The Runtime code "Weapon Ak = M4"

    does not create a "new" object class Weapon.  It has declared

    an object class Weapon that points to "M4".  Take special note

    that "new" was not used. The result is variable changes via proxy.

     

     You can improve the class Weapon implementation by various ways.

    Define more than the default Constructor that take parameters. Like

    the code example from Viorel_ reply.

     

     Hope this helps :)

    Monday, March 19, 2018 4:25 AM
  • Most of the weapons have some attributes properties alike right? Like ammo, reload time etc.

    My aproach would be a bit more advanced. I'd create a base class weapon and place all the properties that all the weapons share, i'd use a enumeration with all the possible weapons in my game and then i would pass to the weapon class the type of weapon and define it's properties from the constructor like so:

    public enum WeaponType { AK, M4 // add as many types as you want. } public class Weapon { // Create the constructor public Weapon(WeaponType type) {

    // You will have as many cases as your weapon types. switch (type) { case WeaponType.AK: ReloadTime = 10.0f; Ammo = 16; break; case WeaponType.M4: ReloadTime = 15.0f; Ammo = 32; break; } } public float ReloadTime {get; private set;} public int Ammo {get; private set; } // i use private setters because i will change them from within the class with a fire method public void Fire() { Ammo --; } }


    After that for each weapon's specification that others don't have you could create a class foreach weapon and inherit from Weapon like so: (Note that you need to have the same constructor.

    public class M4 :Weapon
    {
        public M4(WeaponType type):base(type)
        {
            
        }
        // other specs
    }
    // You can access all the data inside the Weapon class by M4 in your main function like so:
    
    
    M4 m4 = new M4(WeaponType.M4);
    Console.WriteLine(m4.Ammo);
    Console.WriteLine(m4.ReloadTime);
    //Console.WriteLine(m4.otherspecs);
    //Same thing for AK
    // If you don't have any special specs for AK and it's just the normal then you can just call Weapon
    Weapon AK = new Weapon(WeaponType.AK);
    //and access the variable you want.

    at least that would be my approach..

    You could go deeper and use polymorphism but that is another subject..

    Monday, March 19, 2018 1:14 PM
  • But what do I do if I have 10 variables in weapon class?Let's say I have :int Ammo,string fullName,string ammoType etc.I will have to write:(in case Weapon Ak=new Weapon(M4),M4 is k)

    //this is the constructor

    public Weapon(Weapon k){ this.Ammo=k.Ammo; this.fullName=k.fullName; this.ammoType=k.ammoType; . . . . }

    or is there any faster way?

    (I prefer classes over struct and I am used to classes,but I will try to understand how struct works)



    • Edited by Ax1aL Monday, March 19, 2018 6:26 PM
    Monday, March 19, 2018 6:13 PM
  • Thanks for the help but it seems pretty hard for me to understand,I am still a beginner and I don't understand that well enum and construct inheritance.
    Monday, March 19, 2018 6:24 PM
  • Why would you want to copy the data from one weapon to another since each weapon has it's own specifications and number of bullets, type of bullets etc.? I don't see the point on doing that. I think the approach i gave above corresponds quite well on a game like this. Of course you can add more to it, the code i provided is just the "framework".
    Monday, March 19, 2018 6:30 PM
  • In normal words you write

    Create a new weapon and call it M4
    Tell that the amno for M4 = 32
    Give a synonym name for M4 and call it Ak
    Tell Ak and therefore M4 has Ammo 16.

    Therefore create separate weapons for M4 and AK with the keyword New 

    By the way that can quicker
    Weapon M4 = new Weapon(){Ammo=32};
    Weapon Ak = new Weapon(){Ammo=16};


    Success
    Cor


    Monday, March 19, 2018 6:32 PM
  • When you inherit from a class you basically get all the "settings" that the inherited class has. You can use all the public members and types on the class you are inheriting from.Thats all to inheritance. Polymorphism is way too complicated. An enumeration is basically a list of constants. Don't let it confuse you. You declare some constant types of weapons (AK , M4) in order to switch it later and set the right variables to the right weapon. Think like having a list of strings and inside them the weapon types. Well instead of a string list you use a enumeration. About inheritance in the constructor as you can see i type :base(type) . I am doing this because my M4 weapon constructor has to match the weapon class constructor. If they don't match i will get an error. By calling :base(type) the only thing i am doing is calling the weapon constructor from the weapon class in order to instantiate the weapon i want to use with the right variables. That's all there is to my code.
    Monday, March 19, 2018 6:54 PM
  • Greetings Ax1al.

    One possibility to avoid writing each property out one at a time in the copy constructor would be to create a structure for the properties, but leave Weapon as a class. This is a kind of compromise version of Viorel's suggestion.

    namespace XXX
    {
       class Program
       {
          static void Main(string[] args)
          {
             Weapon w1 = new Weapon();
             w1.Properties.Ammo = 10;
             w1.Properties.AmmoType = "Bullet";
             w1.Properties.FullName = "AK47";
    
             Weapon w2 = new Weapon(w1);
             w2.Properties.FullName = "Steyr";
    
             // The ammo and ammo type for w2 will be the same as for w1, but the name will be different.
             Console.WriteLine("{0} {1} {2}", w1.Properties.Ammo, w1.Properties.AmmoType, w1.Properties.FullName);
             Console.WriteLine("{0} {1} {2}", w2.Properties.Ammo, w2.Properties.AmmoType, w2.Properties.FullName);
          }
       }
    
       public class Weapon
       {
          // A structure to hold the weapon's properties.
          // You must remember to put everything you want copied in here. If you forget and put 
          // something somewhere else, it will cause headaches.
          public struct WeaponProperties
          {
             public int Ammo;
             public string AmmoType;
             public string FullName;
          }
    
          // An instance of the properties. Making this public is dangerous, but I think it's the only way 
          // to get a structure to do what you want.
          public WeaponProperties Properties;
    
          // Standard constructor.
          public Weapon()
          {
          }
    
          // Copy constructor. All we need to do is copy the properties, the whole structure in one go.
          public Weapon(Weapon k)
          {
             this.Properties = k.Properties;
          }
       }
    }

    Note that I am not recommending this approach. I am just mentioning it as a possibility. It has some dangers, which I have mentioned in the comments in the code.

    Tuesday, March 20, 2018 1:35 AM
  • Hello,

     So, how is your project status? Just wondered if any of the replies were helpful...

    Creating the base allows for improvements with low code change.  Enums used to

    describe weapon properties make adding new weapons a snap.  Even custom user

    defined weapon properties in a Constructor are useful. I defined a namespace for

    naming conventions flexability.

     

    The following code could work as a base frame work. 

    namespace GenericWeapon
    {
        [Flags]
        enum Ammo : int
        {
            _Undefine = 0,
            _9m  = 1,
            _12  = 2,
            _308 = 4,
            _45  = 8,
            _50  = 16,
            _556 = 32,
            _762 = 64
        }
    
        [Flags]
        enum Frame : byte
        {
            Undefine = 0,
            Pistol = 1,
            Shotgun = 2,
            Rifle = 4,
        }
    
        enum Capacity : int
        {
            Undefine = 0,
            Ammo2 = 2,
            Ammo6 = 6,
            Ammo7 = 7,
            Ammo15 = 15,
            Ammo30 = 30
        }
    
        [Flags]
        enum Mode : byte
        {
            Undefine = 0,
            Auto = 1,
            Bolt = 2,
            Pump = 4,
            Semi = 8,
            Single = 16
        }
    
        enum Style
        {
            Undefine = 0,
            Colt45,
            DesertEagle,
            AK47,
            M4,
            M9,
            M16,
            Mosberg,
            Springfield,
        }
    
        class Weapon
        {
            public Ammo AmmoType { get; private set; }
            public Capacity CapCount { get; private set; }
            public Frame FrameType { get; private set; }
            public Mode FireMode { get; private set; }
            public object NameTag { get; private set; }
    
            public float FireRate { get; private set; }
            public float ReloadTime { get; private set; }
    
            // User defined
            //
            public Weapon( string tag, Ammo a, Capacity c, Frame f, Mode m, float rate, float reload )
            {
                NameTag = ( tag == null ? "Undefined" : tag );
                AmmoType = a;
                CapCount = c;
                FrameType = f;
                FireMode = m;
                FireRate = ( rate < 0.0f ? 0.0f : rate );
                ReloadTime = ( reload < 0.0f ? 0.0f : ( reload > 15.0f ? 15.0f : reload ) );
            }
    
            // Select Preset
            public Weapon( Style nt )
            {
                switch ( nt )
                {
                    case Style.AK47:
                    AmmoType = Ammo._762;
                    FrameType = Frame.Rifle;
                    FireMode = Mode.Single | Mode.Auto;
                    FireRate = 5.0f;
                    CapCount = Capacity.Ammo30;
                    NameTag = Style.AK47;
                    ReloadTime = 15.0f;
                    break;
    
                    case Style.DesertEagle:
                    AmmoType = Ammo._45;
                    FrameType = Frame.Pistol;
                    FireRate = 1.0f;
                    FireMode = Mode.Single;
                    CapCount = Capacity.Ammo7;
                    NameTag = Style.DesertEagle;
                    ReloadTime = 10.0f;
                    break;
    
                    case Style.Mosberg:
                    AmmoType = Ammo._12;
                    FrameType = Frame.Shotgun;
                    FireRate = 3.0f;
                    FireMode = Mode.Single;
                    CapCount = Capacity.Ammo2;
                    NameTag = "Double Barrel";
                    ReloadTime = 15.0f;
                    break;
    
                    default:
                    break;
                }
            }
        }
    }

     The above code is just a small part of what is possible. Every aspect of a custom

    class is boundless. However, the bigger the class the more code to maintain for

    changes or debugging.

     Just extra information for you to consider, thanks :)

    • Marked as answer by Ax1aL Tuesday, March 20, 2018 4:00 PM
    Tuesday, March 20, 2018 3:44 AM
  • Thank you everyone!I was just curious about the fact that you can't copy an class object properties from one object to another.For example,i had more than one weapon of type M4:M41,M42,M43 etc,where the damage was the only thing different (M41.dmg=100,M42.dmg=120,M43.dmg=140...),I would have to write for every other objects the same thing like :ammo,fireRate,fullName etc,and it seems to me a waste of time and space.

    Thank you for your help!

    Tuesday, March 20, 2018 4:00 PM