Search code examples
c#listrandom

C# Object Duplication In List


I am trying to create a simple simulation using a list of objects and making it perform a calculation repeatedly to represent a farmer. It has one method which increases the amount of money the farmer has by a random percentage and each farmer starts with $100

public class Farmer
{
    public decimal money { get; set; }

    public Farmer()
    {
        money = 100;
    }

    public void doOneYear() //Represents how much money the farmer earned
    {
        Random random = new Random();
        decimal growth = random.Next(0, 100);
        decimal percentage = (growth / 1000);
        money = money * (1 + percentage);
    }
}

The code which runs is this

List<Farmer> farmers = new List<Farmer>();

int count = 0;

while (count < 10)
{
    Farmer newFarmer = new Farmer();
    farmers.Add(newFarmer);
    count++;
}

        
foreach(var farmer in farmers)
{
    int years = 0;
    while (years < 10)
    {
        farmer.doOneYear();
        years++;
    }
}


foreach (var farmer in farmers)
{
    MessageBox.Show(farmer.money.ToString());
}

However the results I get back is just the first object in the list repeated. If I step through the whole process in debug mode it works fine but when I let it run the objects appear to be duplicated.


Solution

  • Because the program runs so quickly, and I believe the Random class uses a time setting as its default seed, you need to inject a seed yourself into the Random call. (This is also likely why you would see different numbers when debugging - you made the program run slower, therefore the Random class would output different numbers).

    I did it like this, and saw a different number for each farmer in the output. You may want to use a different seed generation though.

        public class Farmer
        {
            private static int seed = 17;
    
            public decimal money { get; set; }
            public int FarmerID { get; set; }
            public Farmer(int id)
            {
                money = 100;
                FarmerID = id;
            }
    
            public void doOneYear() //Represents how much money the farmer earned
            {
                seed++;
                Random random = new Random(seed);
                decimal growth = random.Next(0, 100);
                decimal percentage = (growth / 1000);
                money = money * (1 + percentage);
            }
        }