1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Apply noise to the map.
//! Each cell will be set to Floor with the given probabilty.
//! 
//! Example usage:
//! ```
//! use rand::prelude::*;
//! use mapgen::{MapBuffer, MapFilter};
//! use mapgen::filter::NoiseGenerator;
//! 
//! let mut rng = StdRng::seed_from_u64(100);
//! let gen = NoiseGenerator::uniform();
//! let map = gen.modify_map(&mut rng, &MapBuffer::new(80, 50));
//! 
//! assert_eq!(map.width, 80);
//! assert_eq!(map.height, 50);
//! ```
//! 

use rand::prelude::*;
use crate::MapFilter;
use crate::MapBuffer;


/// Map noise generator
pub struct NoiseGenerator {
    prob: f32,
}

impl MapFilter for NoiseGenerator {
    fn modify_map(&self, rng: &mut StdRng, map: &MapBuffer)  -> MapBuffer {
        self.build(map, rng)
    }
}

impl NoiseGenerator {
    /// Create noise with custom probability
    pub fn new(prob: f32) -> Box<NoiseGenerator> {
        Box::new(NoiseGenerator {
            prob,
        })
    }

    /// Create uniform noise (Probablity 0.5)
    pub fn uniform() -> Box<NoiseGenerator> {
        Box::new(NoiseGenerator {
            prob: 0.5,
        })
    }

    /// Generate map
    fn build(&self, map: &MapBuffer, rng: &mut StdRng) -> MapBuffer {
        let mut new_map = map.clone();
        let p = (self.prob * 100.0) as u32;
        for y in 1..new_map.height-1 {
            for x in 1..new_map.width-1 {
                let roll = rng.next_u32() % 100;
                if roll > p { new_map.set_walkable(x, y, true) } 
                else { new_map.set_walkable(x, y, false) }
            }
        }

        new_map
    }

}