diff --git a/src/main.rs b/src/main.rs index f31e381..93bc242 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod world; +mod state; use noise::{Perlin, ScalePoint, Add, NoiseFn, Multiply, ScaleBias}; use noise::utils::{NoiseMapBuilder, PlaneMapBuilder}; @@ -37,6 +38,8 @@ impl NoiseFn for BorderNoise { fn main() { + let N_TOWNS = 10; + let mut rng = rand::thread_rng(); let map_size = 256; @@ -80,11 +83,31 @@ fn main() { for y in 0..map_size { let h = plane.get_value(x, y); let t = world::Terrain::from_height(h); - world.map[x][y] = t; + world.map[x][y] = world::WorldCell::new(t); img.put_pixel(x as u32, y as u32, Rgb(t.to_color())); } } - img.save("world.png").unwrap(); + + let mut placed = 0; + while placed < N_TOWNS { + let x = rng.gen_range(0..map_size); + let y = rng.gen_range(0..map_size); + if + world.map[x][y].terrain == world::Terrain::Flats || + world.map[x][y].terrain == world::Terrain::Hills + { + world.add_structure(x, y, world::Structure::Town(world::Town::new())); + placed += 1; + img.put_pixel(x as u32, y as u32, Rgb([255, 0, 0])); + } + } + + let scaled = image::imageops::resize( + &img, + map_size as u32 * 4, map_size as u32 * 4, + image::imageops::FilterType::Nearest); + + scaled.save("world.png").unwrap(); diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..149c53c --- /dev/null +++ b/src/state.rs @@ -0,0 +1,4 @@ +use crate::world::World; +pub struct GameState { + pub world: World, +} \ No newline at end of file diff --git a/src/world.rs b/src/world.rs index e1a5c85..bc70828 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,6 +1,6 @@ - -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Terrain { + Void, DeepOcean, Ocean, Beach, @@ -10,18 +10,41 @@ pub enum Terrain { HighMountains, } +pub struct Town { + pub name: String, + pub population: u32, +} + +pub enum Structure { + Town(Town), +} + +pub struct WorldCell { + pub terrain: Terrain, + pub structure: Option, +} + pub struct World { - pub map: Vec>, + pub map: Vec>, pub size: usize, } +impl WorldCell { + pub fn new(terrain: Terrain) -> WorldCell { + WorldCell { + terrain: terrain, + structure: None, + } + } +} + impl World { pub fn new(size: usize) -> World { let mut map = Vec::new(); for _ in 0..size { let mut row = Vec::new(); for _ in 0..size { - row.push(Terrain::DeepOcean); + row.push(WorldCell::new(Terrain::Void)); } map.push(row); } @@ -30,6 +53,10 @@ impl World { size: size, } } + + pub fn add_structure(&mut self, x: usize, y: usize, structure: Structure) { + self.map[x][y].structure = Some(structure); + } } impl Terrain { @@ -53,6 +80,7 @@ impl Terrain { pub fn to_color(self) -> [u8; 3] { match self { + Terrain::Void => [0, 0, 0], Terrain::DeepOcean => [20, 60, 255], Terrain::Ocean => [20, 120, 255], Terrain::Beach => [255, 255, 100], @@ -63,3 +91,12 @@ impl Terrain { } } } + +impl Town { + pub fn new() -> Town { + Town { + name: "Town".to_string(), + population: 100, + } + } +}