aboutsummaryrefslogtreecommitdiff
path: root/src/state.rs
blob: 5d1390202102ee4b88e1b2ff3b121e8dfcde04bf (plain)
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
66
67
68
69
70
71
72
use crate::canvas::Canvas;

#[derive(Debug, Clone)]
pub struct State {
    width: u32,
    height: u32,
    cells: Vec::<bool>,
}

impl State {
    pub fn new(width: u32, height: u32) -> State {
        let cells = (0..width * height)
            .map(|_| js_sys::Math::random() < 0.5)
            .collect();

        State {
            width,
            height,
            cells,
        }
    }

    pub fn neighbor_count(&self, x: u32, y: u32) -> u32 {
        let mut count = 0;
        for delta_x in [self.height - 1, 0, 1].iter().clone() {
            for delta_y in [self.width - 1, 0, 1].iter().clone() {
                let neighbor_x = (x + delta_x) % self.width;
                let neighbor_y = (y + delta_y) % self.height;

                if (*delta_x, *delta_y) != (0, 0) && self.is_on(neighbor_x, neighbor_y) {
                    count += 1;
                }
            }
        }
        count
    }

    pub fn next(&self) -> State {
        let cells = (0..self.width * self.height)
            .map(|i| {
                let x = i % self.width;
                let y = i / self.width;
                let neighbor_count = self.neighbor_count(x, y);
                neighbor_count == 3 || self.is_on(x, y) && neighbor_count == 2
            })
            .collect();

        State {
            width: self.width,
            height: self.height,
            cells,
        }
    }

    fn is_on(&self, x: u32, y: u32) -> bool {
        let inside_x = (x + self.width) % self.width;
        let inside_y = (y + self.height) % self.height;
        self.cells[(inside_x + inside_y * self.width) as usize]
    }

    pub fn draw(&self, canvas: &Canvas) {
        canvas.clear();

        for y in 0..self.height {
            for x in 0..self.width {
                if self.is_on(x, y) {
                    canvas.draw(x, y, "green");
                }
            }
        }
    }
}