1use macroquad::prelude::*;
2
3#[derive(Copy, Clone, Debug, PartialEq, Eq)]
4enum CellState {
5 Alive,
6 Dead,
7}
8
9#[macroquad::main("Life")]
10async fn main() {
11 let w = screen_width() as usize;
12 let h = screen_height() as usize;
13
14 let mut cells = vec![CellState::Dead; w * h];
15 let mut buffer = vec![CellState::Dead; w * h];
16
17 let mut image = Image::gen_image_color(w as u16, h as u16, WHITE);
18
19 for cell in cells.iter_mut() {
20 if rand::gen_range(0, 5) == 0 {
21 *cell = CellState::Alive;
22 }
23 }
24 let texture = Texture2D::from_image(&image);
25
26 loop {
27 clear_background(WHITE);
28
29 let w = image.width();
30 let h = image.height();
31
32 for y in 0..h as i32 {
33 for x in 0..w as i32 {
34 let mut neighbors_count = 0;
35
36 for j in -1i32..=1 {
37 for i in -1i32..=1 {
38 if y + j < 0 || y + j >= h as i32 || x + i < 0 || x + i >= w as i32 {
40 continue;
41 }
42 if i == 0 && j == 0 {
44 continue;
45 }
46
47 let neighbor = cells[(y + j) as usize * w + (x + i) as usize];
48 if neighbor == CellState::Alive {
49 neighbors_count += 1;
50 }
51 }
52 }
53
54 let current_cell = cells[y as usize * w + x as usize];
55 buffer[y as usize * w + x as usize] = match (current_cell, neighbors_count) {
56 (CellState::Alive, x) if x < 2 => CellState::Dead,
59 (CellState::Alive, 2) | (CellState::Alive, 3) => CellState::Alive,
62 (CellState::Alive, x) if x > 3 => CellState::Dead,
65 (CellState::Dead, 3) => CellState::Alive,
68 (otherwise, _) => otherwise,
70 };
71 }
72 }
73
74 for i in 0..buffer.len() {
75 cells[i] = buffer[i];
76
77 image.set_pixel(
78 (i % w) as u32,
79 (i / w) as u32,
80 match buffer[i as usize] {
81 CellState::Alive => BLACK,
82 CellState::Dead => WHITE,
83 },
84 );
85 }
86
87 texture.update(&image);
88
89 draw_texture(&texture, 0., 0., WHITE);
90
91 next_frame().await
92 }
93}