|
|
@@ -12,12 +12,10 @@ extern crate serde_json;
|
|
|
|
|
|
/*
|
|
|
UNITS
|
|
|
-
|
|
|
-mass = kilogram
|
|
|
-time = sec
|
|
|
-distance = meter
|
|
|
-speed = meter / tick (s)
|
|
|
-
|
|
|
+ mass = kilogram
|
|
|
+ time = sec
|
|
|
+ distance = meter
|
|
|
+ speed = meter / tick (s)
|
|
|
*/
|
|
|
|
|
|
// Time constants
|
|
|
@@ -51,13 +49,25 @@ enum LifeformKind {
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
struct Biome {
|
|
|
- width: f32,
|
|
|
- height: f32,
|
|
|
water: f32,
|
|
|
biomass: f32,
|
|
|
- lifeforms: Vec<Lifeform>
|
|
|
+ lifeforms: Vec<Lifeform>,
|
|
|
+ bounds: Vec<f32> //left, top, right, bottom boundaries
|
|
|
}
|
|
|
|
|
|
+ fn move_random(lf: &mut Lifeform, bounds: &Vec<f32>) {
|
|
|
+ let mut rng = rand::thread_rng();
|
|
|
+ let rx = rng.gen_range::<f32>(-1.0, 1.0);
|
|
|
+ let rz = rng.gen_range::<f32>(-1.0, 1.0);
|
|
|
+ lf.position[0] += rx*lf.speed;
|
|
|
+ lf.position[2] += rz*lf.speed;
|
|
|
+
|
|
|
+ if lf.position[0] > bounds[2] {lf.position[0] = bounds[2]}; // x > right bound
|
|
|
+ if lf.position[2] > bounds[1] {lf.position[2] = bounds[1]}; // z > upper bound
|
|
|
+ if lf.position[0] < bounds[0] {lf.position[0] = bounds[0]}; // x < left bound
|
|
|
+ if lf.position[2] < bounds[3] {lf.position[2] = bounds[3]}; // z < lower bound
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
Biome - a container for lifeforms.
|
|
|
@@ -68,23 +78,27 @@ lifeform so it can access it and modify it.
|
|
|
impl Biome {
|
|
|
fn tick(&mut self){
|
|
|
|
|
|
- for lifeform in &mut self.lifeforms {
|
|
|
+ for mut lifeform in &mut self.lifeforms {
|
|
|
if lifeform.alive {
|
|
|
- lifeform.tick();
|
|
|
self.water -= lifeform.water_intake;
|
|
|
+ lifeform.mass += lifeform.nutrient_intake;
|
|
|
+ lifeform.age += 1;
|
|
|
+ if lifeform.age > lifeform.maxage {
|
|
|
+ lifeform.alive = false;
|
|
|
+ println!("Died: {:?}", lifeform);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ move_random(&mut lifeform, &self.bounds);
|
|
|
} else {
|
|
|
self.biomass += lifeform.mass;
|
|
|
lifeform.mass = 0.0;
|
|
|
}
|
|
|
|
|
|
- //keep lifeform in bounds - clamp does not work on f32? why?
|
|
|
- if lifeform.position[0] > self.width {lifeform.position[0] = self.width};
|
|
|
- if lifeform.position[2] > self.height {lifeform.position[2] = self.height};
|
|
|
- lifeform.position[0] = lifeform.position[0].abs();
|
|
|
- lifeform.position[2] = lifeform.position[2].abs();
|
|
|
-
|
|
|
- }
|
|
|
}
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
@@ -112,22 +126,7 @@ impl Lifeform {
|
|
|
it could interact with it.
|
|
|
*/
|
|
|
fn tick(&mut self){
|
|
|
- if self.alive {
|
|
|
- self.mass += self.nutrient_intake;
|
|
|
- self.age += 1;
|
|
|
- }
|
|
|
- if self.age > self.maxage {
|
|
|
- self.alive = false;
|
|
|
- println!("Died: {:?}", self);
|
|
|
- }
|
|
|
- self.move_random();
|
|
|
- }
|
|
|
- fn move_random(&mut self) {
|
|
|
- let mut rng = rand::thread_rng();
|
|
|
- let rx = rng.gen_range::<f32>(-1.0, 1.0);
|
|
|
- let rz = rng.gen_range::<f32>(-1.0, 1.0);
|
|
|
- self.position[0] += rx*self.speed;
|
|
|
- self.position[2] += rz*self.speed;
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -153,7 +152,7 @@ fn main() {
|
|
|
let start = SystemTime::now();
|
|
|
println!("{:?}", start);
|
|
|
|
|
|
- let mut biome = Biome {width: 1000.0, height: 1000.0, water: 1000.0, lifeforms: Vec::new(), biomass: TON};
|
|
|
+ let mut biome = Biome {water: 1000.0, lifeforms: Vec::new(), biomass: TON, bounds: vec![0.0, 100.0, 100.0, 0.0]};
|
|
|
|
|
|
|
|
|
// add some trees
|
|
|
@@ -202,8 +201,9 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
|
|
+ let simtime: i32 = 5*HOUR;
|
|
|
|
|
|
- for _i in 1..1000 {
|
|
|
+ for _i in 1..simtime {
|
|
|
biome.tick();
|
|
|
}
|
|
|
|