Issue with "linking" ids of data

Hello,

Bellow is my convoluted bit of code which is causing the issue:

for id in 0..self.people.len() {
            if self.people[id].age != -1 {
                // Ages all people by 1 month
                self.people[id].age += 1;

                // println!("{:?}", people_temp);

                // Chooses people what will have babies
                if self.people[id].love_vec[0] == -1 && self.people[id].age > 12 * 12 {
                    // Creates a random number to chose a lover for person
                    let lover = rand::thread_rng().gen_range(0..self.people.len());

                    // println!("{}", lover);

                    // If the person is not the lover and if the person does not have a lover one is given
                    if
                        lover != id &&
                        self.people[lover].love_vec[0] == -1 &&
                        self.people[id].sex != self.people[lover].sex &&
                        rand::thread_rng().gen_range(0.0..100.0) >= 95.0
                    {
                        self.people[id].love_vec[0] = lover as i64;
                        self.people[lover].love_vec[0] = id as i64;
                    }
                }

                // Changes id to -1 for people who will be killed/removed from vec
                let ages = [2, 5, 10, 25, 35, 45, 60, 70, 80, 90];
                let weights = [5, 5, 25, 55, 75, 105, 135, 1050, 350, 150];
                let dist = WeightedIndex::new(&weights).unwrap();
                // println!("{}", ages[dist.sample(&mut rng)]);
                if
                    self.people[id].age > ages[dist.sample(&mut thread_rng())] * 12 &&
                    rand::thread_rng().gen_range(0.0..1.0) > 0.98
                {
                    // Age of death in months
                    self.people[id].age = -1;
                }

                // Set the lover as -1 in the love_vec if they are dead
                match self.people.get(self.people[id].love_vec[0] as usize) {
                    Some(_err) => {}
                    None => {
                        if self.people[id].love_vec[0] != -1 {
                            self.people[id].love_vec[0] = -1;
                        }
                    }
                }

                // println!("{}", self.people.len());
            }
        }

The expected result is for people which can be in love to have the following in their love_vec[0]:
person1 love_vec[0] should equal to person2 id
person2 love_vec[0] should equal to person1 id

But here are screenshots from my GUI showing otherwise:
image
image
As you can see my issue is shown here where the id in person2 love_vec[0] is not the id of person1. And for some reason the check of sex was also skipped

But strangely sometimes the issue is not there, with smaller populations especially.

I think that the issue comes from the order of my checks but i am clueless from that point onwards.

The best outcome would be if anyone knows some kind of data linking crate or something, because i could not find anything.

Thanks in advance :slight_smile:

Probably you should change how you "unlover" the deceased. You just maybe made [id] deceased but then effectively checked to see if the [lover] was deceased.

                    // Age of death in months
                    self.people[id].age = -1;

                    // Set the lover as -1 in the love_vec if they are dead
                    let other = self.people[id].love_vec[0];
                    if other > 0 {
                        self.people[id].love_vec[0] = -1;
                        self.people[other as usize].love_vec[0] = -1;
                    }

More generally speaking,

  • Use Option<u16> instead of i16 with a -1 sentinel value for age (guessing at bit width)
  • Use Option<usize> for storing indices instead of i64 with a -1 sentinel value
  • No need for Vec if you only use the first field
  • Reduce indexing where possible (though you probably won't get rid of all of it in this case)
  • Move logic like "make this person deceased" to methods

thanks, i think thats what i needed

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.