CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: How do I??

  1. #1
    Join Date
    Jun 2008
    Posts
    154

    How do I??

    C# here

    StatisticsValue is a struct of values (floats)
    class Spell is defining some values that StaticsValue holds, the spell may have 1 or more values but not all of the values StatisticsValue holds.


    StatisticsValue statEffect = spell.TargetEffectValue;

    how do I multiply each of the values in the Spell by this value?

    float ARCmodifier

    something like

    i = 0;
    int total = spell.TargetEffectValue.count;
    for (i = 1; i < total; i++)
    {
    statEffect * ARCmodifier;
    }

    I am doing it wrong - should I use a foreach??
    I am still learning

  2. #2
    Join Date
    Mar 2007
    Posts
    375

    Re: How do I??

    Code:
    StatisticsValue statEffect = spell.TargetEffectValue;
    You cannot assign one float value to a whole structure. Do it like this
    Code:
    StatisticsValue statEffect = new StatisticsValue();
    statEffect.SomeVariable = spell.TargetEffectValue;


    If you want to multiply every float in a class with a value, try this
    Code:
    foreach(float f in spell)
        f = (f * ARCmodifier);
    Last edited by dahwan; September 12th, 2008 at 06:12 PM.
    Please vote the posts you find usefull.

    ---

    I'm back
    Bigger and badder
    Better and bolder
    Explaining stuff -
    With an improved vocabulary!

  3. #3
    Join Date
    Jun 2008
    Posts
    154

    Re: How do I??

    TargetEffectValue is not a single variable - srry I should have clarified that.

    Code:
    from class Spell
    
            /// <summary>
            /// Therange of statistics effects of this spell on its target.
            /// Like Equipment We can do a lot of things here.
            ///    HealthPoints
            ///    MagicPoints
            ///    Strength
            ///    Vitality
            ///    Agility
            ///    Accuracy
            ///    Evasion
            ///    Parry
            ///    CounterAttack
            ///    TotalArmor
            ///    MagicDefense
            ///    SpellCasting
            /// This is a debuff if IsOffensive is true, otherwise it's a buff.
            /// This is the Initial reading of the spell effects.
            /// Later we will modify it by the Caster's Arcane Level
            ///  </summary>
    
            private StatisticsValue targetEffectValue = new StatisticsValue();
    
            [ContentSerializerIgnore]
            public StatisticsValue TargetEffectValue
            {
                get { return targetEffectValue; }
            }
    Hrmmmm
    --------------------------------------------------

    Code:
            public static StatisticsValue CalculateSpellDamage(Combatant combatant, Spell spell)
            {
                // check the parameters
                if (combatant == null)
                {
                    throw new ArgumentNullException("combatant");
                }
                if (spell == null)
                {
                    throw new ArgumentNullException("spell");
                }
                // get the magical offense from the character's class, gear, and bonuses
                // -- note that this includes stat buffs
                float arcaneSkill = combatant.Character.Arcane;
                //if we are going ot do damage its going to be a variance based off of our Arcane Skill
                //Get the Variance
                float variance = 0.30f;
                //Create the Arcane modifer
                float ARCmodifier = 1 + (arcaneSkill / 100);
    
                List<StatisticsValue> statEffect = List<spell.TargetEffectValue>();
    
                foreach (float statEffect in spell)
                {
                    statEffect = (statEffect * ARCmodifier);
                }
                //calculating...
                //and add variance
                float postVarianceEffect = statEffect * variance;
    -----------------------------
    I think I am getting closer but...
    Last edited by bixel; September 13th, 2008 at 04:58 PM.

  4. #4
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: How do I??

    Hi bixel !

    Please read our forum habits and use codetags. As you dnt your code losts any sort of formatting and is just unreadable. Please edit your code and do a correct Format so its easier to read.
    Additional your code is wrong in a lot of places and would never compile
    For example
    Code:
    List<StatisticsValue> statEffect = List<spell.TargetEffectValue>();
    At first instantiating a generic List you need to have the Type in yot list definition so the left part is correct but in the right side you cannot define the type using an instance of another class and a parameter of this class.
    Additional instantiating needs the 'new keyword so this line should be
    Code:
    List<StatisticsValue> statEffect = new List<StatisticsValue>();
    The next one is also not compileable
    Code:
    foreach (float statEffect in spell)
    ...
    This would need to have a list of statEffect contained in a List called spell and statEffect should be a float. But just in the line before you declared it to be a generic List of objects of type StatisticsValue.

    So, sorry to say, this seems me to be a totally confusion.
    Do it in a clar line
    a) define your StatistricsValue class in a clear way. Is Statistics Value itself one Value or a class containing different StatisticValues ? IMHO the second point is correct. So it needs to get a correct name. StatisticsValues !! As earlier you decide yourself to have a clean precise naming in your classnames as easier you will be able to code it.
    If you need to multiply any property of a class which could be multiplied then you can do this with different methods
    The easiest is to have it in the class itself like (taking part of your example as an example
    Code:
    public class StatisticsValues{
    	private int _healthPoints;
    	private int _magicPoints;
    	private int _strength;
    	private decimal _agility;
    	private decimal _vitality;
    	#region Constructor
    	public StatisticsValues( int health, int magic, int strength, decimal agility,decimal vitality) {
    		_healthPoints = health;
    		_magicPoints = magic;
    		_strength = strength;
    		_agility = agility;
    		_vitality = vitality;
    	}
    	#endregion
    	public int HealthPoints {
    		get { return _healthPoints; }
    		set { _healthPoints = value; }
    	}
    	public int MagicPoints {
    		get { return _magicPoints; }
    		set { _magicPoints = value; }
    	}
    	public int Strength {
    		get { return _strength; }
    		set { _strength = value; }
    	}
    	public decimal Vitality {
    		get { return _vitality; }
    		set { _vitality = value; }
    	}
    	public decimal Agility {
    		get { return _agility; }
    		set { _agility = value; }
    	}
    	public StatisticsValues GetVarianceStats(decimal variance) {
    		StatisticsValues varData = new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
    		return varData;
    	}
    }
    Instead of writing
    Code:
    		StatisticsValues varData = new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
    		return varData;
    // you can also simplify this to 
    		return new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
    I did it the explicit way so you could better see what I'm doing.. Simple creating a new class where all inparams are multiplied.
    If you want to use a loop for going through different params of a class and multiplying them you need to know a bit about reflection and this way you can read your class and for example multiplying all properties which are of Type int or of type float or whatever you want to to.
    But if you want to have it simple and only need this one class to multiply do it like I showed you.
    Last edited by JonnyPoet; September 13th, 2008 at 03:56 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  5. #5
    Join Date
    Jun 2008
    Posts
    154

    Re: How do I??

    Code:
    	public StatisticsValues GetVarianceStats(decimal variance)
            {
    		StatisticsValues varData = new StatisticsValues((int)(_healthPoints*variance), (int)(_magicPoints*variance), (int)(_strength*variance),_agility*variance,_vitality*variance );
    		return varData;
    	}
    oooh thats nifty

    I did an overload and it worked on a value by value basis, but the above example is better for doing a modification as a whole.

    Code:
            public static StatisticsValue MultiplyFloat(StatisticsValue value1, float value2)
            {
                StatisticsValue outputValue = new StatisticsValue();
                outputValue.HealthPoints =
                    value1.HealthPoints * value2;
                outputValue.MagicPoints =
                    value1.MagicPoints * value2;
                outputValue.Strength =
                    value1.Strength * value2;
                outputValue.Vitality =
                    value1.Vitality * value2;
                outputValue.Agility =
                    value1.Agility * value2;
                outputValue.Accuracy =
                    value1.Accuracy * value2;
                outputValue.Evasion =
                    value1.Evasion * value2;
                outputValue.Parry =
                    value1.Parry * value2;
                outputValue.CounterAttack =
                    value1.CounterAttack * value2;
                outputValue.TotalArmor =
                    value1.TotalArmor * value2;
                outputValue.MagicDefense =
                    value1.MagicDefense * value2;
                outputValue.SpellCasting =
                    value1.SpellCasting * value2;
    
                return outputValue;
            }
    turns out my old overload worked!
    Code:
                float ARCmodifier = 1 + (arcaneSkill / 100);
                StatisticsValue statEffect = spell.TargetEffectValue;
                StatisticsValue moddedEffect = StatisticsValue.MultiplyFloat(statEffect, ARCmodifier);
    perhaps some how I used it wrong
    Last edited by bixel; September 13th, 2008 at 05:21 PM.

  6. #6
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: How do I??

    Code:
    StatisticsValue moddedEffect = StatisticsValue.MultiplyFloat(statEffect, ARCmodifier);
    Looks fine, there is only one point I want to mention which is irritating a bit: Learn to use the standard notation. A local field everytime begins with a lower case letter so it needs to be arcModifier ! Otherwise I was looking for a class named ARCmodifier ! So this gives a wrong impression when you are trained to use the camel style. You will get thinking in that methods and looking for something which isn't here
    MSDN has documentaion regarding how to use it look
    http://msdn.microsoft.com/en-us/libr...w0(VS.71).aspx

    If any more questions feel free to ask. and Thx for using Codetags now
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  7. #7
    Join Date
    Jul 2008
    Posts
    29

    Re: How do I??

    Hmm, I just have something against hardcoded stuff like that.. Couldn't you just use



    Code:
    public static T MultiplyByFactor<T>(T value, float factor)
    {
        T modValues = (T)Activator.CreateInstance<T>();
    
        foreach (PropertyInfo propInfo in values.GetType().GetProperties())
       {
            if (propInfo.PropertyType.IsValueType)
                   propInfo.SetValue(modValues, propInfo.GetValue(values, null) * factor, null);
       }
    
       return modValues as T;
    }
    Using the code would then look like this:
    Code:
    StatisticValues statValues = new StatisticsValues();
     StatisticValues modStatValues = MultiplyByFactor<StatisticValues>(statValues, 1.5666f);
    That code should set each property to be multiplied by a certain value. If not all values are floats maybe you will have to use casting to avoid float*int or something like that.

    Edit: Hmm, perhaps that method does indeed use alot more resources since it has to instantiate alot of PropertyInfos, and it seems you are trying to produce a game, which probably needs all the resources it can get.. Up to you.
    Last edited by CyberRascal; September 14th, 2008 at 08:22 AM.

  8. #8
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: How do I??

    Quote Originally Posted by CyberRascal
    Hmm, I just have something against hardcoded stuff like that.. Couldn't you just use
    ...
    Thats what I mentioned in post#4 -> using reflection
    If he knows how to use reflection he can do it this way. BTW I'm not sure if this doesn't get into troubles if he has other valuetype properties in his class for example bool , DateTime, char, byte? So I would restrict your method a bit more for example to only use PropertyTypes typeof(Int32) ... typeof(float.. whatever he really needs ) excluding all Types which arn't to be handled by math operation.
    You also need to add namespace reflection or the propertyInfo will not get compileable.

    But basically yes... Thats the advanced approach..
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  9. #9
    Join Date
    Jul 2008
    Posts
    29

    Re: How do I??

    Oh sorry, that's what I get for reading too fast. Anyway, you are right, he might get in trouble for that. Now I'm pretty new to programming so I don't know the best practice for that, but I would use attributes to single out the properties which should be converted..

    Code:
            public T MultiplyByFactor<T>(T value, float factor) where T : class
            {
                T modValues = (T)Activator.CreateInstance<T>();
    
                foreach (PropertyInfo propInfo in value.GetType().GetProperties())
                {
                    object[] objectArray = propInfo.GetCustomAttributes(typeof(DoConvertAttribute), false);
                    if (objectArray.Length != 0)
                    {
                        IConvertible oldValue = (IConvertible)propInfo.GetValue(value, null);
                        IConvertible newValue = (IConvertible)(oldValue.ToSingle(new NumberFormatInfo()) * factor);
                        propInfo.SetValue(modValues, newValue.ToType(propInfo.PropertyType, new NumberFormatInfo()), null);
                    }
                    else
                        propInfo.SetValue(modValues, propInfo.GetValue(value, null), null);
                }
    
                return modValues as T;
            }
    Class declaration would then look like this:
    Code:
    public class DoConvertAttribute : Attribute
    { }
    
    public class StatisticValues
    {
        [DoConvertAttribute]
        public float Health
        { get; set; }
    
        [DoConvertAttribute]
        public int MagicPoints
         {
                    get { return _magicPoints; }
    		set { _magicPoints = value; }
         }
      
         [DoConvertAttribute]
         public int Strength
            {
    		get { return _strength; }
    		set { _strength = value; }
    	}
    }
    Perhaps not the best way, but doable. Maybe too advanced aswell, but I think it's better to have a steep learning curve instead of ingraining bad practice...

    edit: Explaining why I do certain stuff:

    Having T in the method signature:
    This is called a generic argument and is used to make methods and classes more powerful, as they can be used with more classes/types than just one.

    Casting the property values to IConvertible:
    IConvertible provides means to convert value types to other kinds of value types. Converting to float here is necessary to make it possible to multiply. Then converting back to typeof(T) is necessary because the property will only accept values of the same type as in its signature.
    Last edited by CyberRascal; September 14th, 2008 at 12:43 PM.

  10. #10
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: How do I??

    Quote Originally Posted by CyberRascal
    ...
    Perhaps not the best way, but doable. Maybe too advanced aswell, but I think it's better to have a steep learning curve instead of ingraining bad practice...
    I dont fully agree. Looking to the code this seems much to advanced to get this done that way. And if someone has no basic knowlwdge about reflection, he may loose the ground under the feet totally. A learning curve easily can go out of gradient and then the people trying to learn are lost.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  11. #11
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: How do I??

    Quote Originally Posted by CyberRascal
    .... Then converting back to typeof(T) is necessary because the property will only accept values of the same type as in its signature.
    May I correct you for better understanding.
    We are not casting back to typeof(T) as this would mean casting any value to class StatisticVvaluues as T in your example is StaticticValues.
    Correct you have meant: You are casting back to the same PropertyType which just was read out of the class using propInfo.PropertyType of the class PropertyInfo which is part of the Reflection namespace.
    This way the property is filled with the correct values.
    Also you should have explained that you have built a new class derived fro the Attribute class which is only a derived instande of it ( its empty as we see ) This is used to sign, which Attribútes to be used so if you for example have some boolean Property or some DateTime Property as I mentioned earlier, you didn't want to change them, so you simple dont set them to this class
    Code:
    public class StatisticValues {
    	private float _health;
    	private int _magicPoints;
    	private int _strength;
    	private DateTime _today;
    	private bool _anotAllowed;
     
    	// no DoConvertAttribute here
    	public bool NotAllowed {
    		get { return _notAllowed; }
    		set { _notAllowed = value; }
    	}
     
    // no DoConvertAttribute here
    	public DateTime Today {
    		get { return _today; }
    		set { _today = value; }
    	}
    	[DoConvertAttribute]
    	public float Health{
    		get { return _health; }
    		set { _health = value; }
    	}
    	[DoConvertAttribute]
    	public int MagicPoints {
    		get { return _magicPoints; }
    		set { _magicPoints = value; }
    	}
    	[DoConvertAttribute]
    	public int Strength {
    		get { return _strength; }
    		set { _strength = value; }
    	}
    }
    // and where you want to use the method
     
    StatisticValues inVal = new StatisticValues();
    inVal.MagicPoints = 30;
    inVal.Strength = 50;
    inVal.Health = 100;
    inVal.Today = DateTime.Now.Date;
    inVal.NotAllowed = true;
    float factor = 8.0f;
    StatisticValues result = MultiplyByFactor<StatisticValues>(inval, factor);
    In this example The NotAllowed Property as well as the Today Property is transfered with its original values , but all which are 'signed' with class DoConvertAttribute are used to be converted.
    Hope this helps to understnd this really good code example.

    BTW: You cannot be totally 'new' to programming. Therefore the code is too cool

    About CustomAttributes and Reflection I would suggest the questioner to read MSDN references about 'Attribute' class
    Last edited by JonnyPoet; September 14th, 2008 at 06:01 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  12. #12
    Join Date
    Jul 2008
    Posts
    29

    Re: How do I??

    Oh yes! Thank you, excellently explained. Sorry for making mistakes in explaining, makes it alot harder to understand. And yes, it is true that it's easy to get lost, especially while learning other concepts it was a "bad" example. I actually thought it would be quite simple at first, but there was quite a few complications, so it got more advanced than I thought at first! Will take note to post better (Or atleast correct!) explanation next time.

    So to poster:

    Use Jonnys example if you want to learn other concepts, keeping this one simple. Otherwise I think you can learn much by testing out the code I posted.

    PS: Well, not totally new but still new enough to come up with a lot of pretty horrible designs!

  13. #13
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: How do I??

    Quote Originally Posted by CyberRascal
    ...Will take note to post better (Or atleast correct!) explanation next time.
    The code itself is great as it shows advanced concepts, which are used for getting reuseable code.
    Quote Originally Posted by CyberRascal
    So to poster:

    Use Jonnys example if you want to learn other concepts, keeping this one simple. Otherwise I think you can learn much by testing out the code I posted.!
    I woud suggest to try your example and to go through it step by step using the debugger. With your code and the (hopefully) full explanation of how it works he should really have taken the curve this time and learned a lot.
    Quote Originally Posted by CyberRascal
    PS: Well, not totally new but still new enough to come up with a lot of pretty horrible designs!
    I overlooked and tested your code.
    Cannot see any troubles here. My Considerations only have been regarding the obviously just learning poster and your very advanced example. My idea of learning is more a gradient concept: Learn the basics, -learn the basics- learn and understand really all basics. Train them in easy understandable examples. - When you feel fit about all this basic stuff, -> then go on and study design. Going this way someone will find that some of his own ideas are already known design patterns - and will have great win on that - and he will learn about design patterns in general and how to use them in his own designs. Sure he will redesign a lot of his stuff - but this will result in a good deep based knowledge how to do it and how to do it better. - This is based on my own learning experience - and I have seen this working on other people too, so this is 'my way'
    Last edited by JonnyPoet; September 14th, 2008 at 06:31 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured