Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with a great numbers of variables in C#

Tags:

variables

c#

I'm making a game about genetics, and I stumble into a little "problem". (it's more of a question in fact)

I have a DNA class with a lot of variables that stores the infos about each "creature" in the game.

public class DNA {
    float size;
    float speed;
    float drag;
    float eyeSize;
    int numberOfEyes;
    float color_r;
    [...]
}

Now let's imagine I want to average two DNAs.

I could do:

DNA AverageDNAs (DNA dna1, DNA dna2) {
    DNA newDNA = new DNA ();
    newDNA.size = (dna1.size+dna2.size)/2f;
    newDNA.speed = (dna1.speed+dna2.speed)/2f;
    [...]
}

But it seems pretty long, and every time I'm going to do some calculation, I'll need to rewrite every variable one by one.

So I made a function that stores all the variables (normalized between 0 and 1) into a list

public class DNA {
    public float size;
    public float speed;
    [...]
    private List<float> tempList;
    public List<float> ToList() {
        if (tempList == null) {
        tempList = new List<float>();
        toReturn.Add (size/sizemax);
        toReturn.Add (speed/speedmax);
        [...]
        }
        return tempList
    }
    public static ADN fromList(List<float> list) {
        ADN toReturn = new ADN();
        toReturn.size = list[0]*sizemax;
        [...]
    }
}

Now, I can do:

DNA AverageDNAs (DNA dna1, DNA dna2) {
    List<float> dnaList1 = dna1.ToList();
    List<float> dnaList2 = dna2.ToList();
    List<float> newDNA = new List<float>();
    for (int i = 0; i<dnaList1.Count; i++) {
        newDNA.Add ((dnaList1[i]+dnaList2[i])/2f);
    }
    return DNA.fromList(newDNA);
}

It's easier to implement new functions and calculations, but it's pretty heavy (partly due to Lists creation), and not very pretty (I guess ?).

I would not prefer using just a List<float> for the sake of readability.

I wanted to know if there's a better way to handle that kind of situations?

(Please pardon my poor english, as I'm not a native speaker)

like image 287
Souk21 Avatar asked Dec 06 '22 21:12

Souk21


1 Answers

If you're always applying the same operation to all, you could use a parameter to specify the operation to be performed:

public DNA Cross(DNA dna1, DNA dna2, Func<float, float, float> operation)
{
  var newDNA = new DNA();

  newDNA.size = operation(dna1.size, dna2.size);
  newDNA.speed = operation(dna1.speed, dna1.speed);
  // And all the rest
}

This allows you to reuse this method for a wide range of different operations - as long as they always operate on the same amount of fields:

// Average
(d1, d2) => (d1 + d2) / 2f
// Sum
(d1, d2) => d1 + d2
// Random
(d1, d2) => RandomBool() ? d1 : d2

etc.

If you do want to apply the operation more selectively, you could also expand the Cross method to take an enum specifying which fields exactly you want to update. And of course, you might want to add another Func (or Action, depending on how comfortable you are with mutating arguments) to update the rest in any way you want.

like image 95
Luaan Avatar answered Dec 08 '22 11:12

Luaan