make random rules prettier
This commit is contained in:
parent
b8eda9f316
commit
7da0730fab
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -264,12 +264,6 @@ dependencies = [
|
||||||
"windows-targets 0.52.5",
|
"windows-targets 0.52.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -363,16 +357,6 @@ version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rust-lzma"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7d62915608f6cee1d7f2fc00f28b4f058ff79d6e4ec3c2fe0006b09b52437c84"
|
|
||||||
dependencies = [
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -398,7 +382,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94d9aecc4d31a71578481de6c6d64383d374126c38469c9689067579c1d910fd"
|
checksum = "94d9aecc4d31a71578481de6c6d64383d374126c38469c9689067579c1d910fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rust-lzma",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -466,12 +449,6 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vcpkg"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -7,6 +7,6 @@ edition = "2021"
|
||||||
clap = { version = "4.5.4", features = ["derive"] }
|
clap = { version = "4.5.4", features = ["derive"] }
|
||||||
rand = "0.9.0-alpha.1"
|
rand = "0.9.0-alpha.1"
|
||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
servicepoint2 = "0.4.2"
|
servicepoint2 = { version = "0.4.2", default-features = false }
|
||||||
crossterm = "0.27.0"
|
crossterm = "0.27.0"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -17,7 +17,7 @@ use servicepoint2::Command::{BitmapLinearWin, CharBrightness};
|
||||||
|
|
||||||
use crate::game::Game;
|
use crate::game::Game;
|
||||||
use crate::print::{println_debug, println_info, println_warning};
|
use crate::print::{println_debug, println_info, println_warning};
|
||||||
use crate::rules::Rules;
|
use crate::rules::{generate_bb3, generate_u8b3};
|
||||||
|
|
||||||
mod game;
|
mod game;
|
||||||
mod rules;
|
mod rules;
|
||||||
|
@ -33,19 +33,19 @@ fn main() {
|
||||||
let connection = init();
|
let connection = init();
|
||||||
|
|
||||||
let mut left_pixels = Game {
|
let mut left_pixels = Game {
|
||||||
rules: Rules::random_bb3(),
|
rules: generate_bb3(),
|
||||||
field: PixelGrid::max_sized(),
|
field: PixelGrid::max_sized(),
|
||||||
};
|
};
|
||||||
let mut right_pixels = Game {
|
let mut right_pixels = Game {
|
||||||
rules: Rules::random_bb3(),
|
rules: generate_bb3(),
|
||||||
field: PixelGrid::max_sized(),
|
field: PixelGrid::max_sized(),
|
||||||
};
|
};
|
||||||
let mut left_luma = Game {
|
let mut left_luma = Game {
|
||||||
rules: Rules::random_u8b3(),
|
rules: generate_u8b3(),
|
||||||
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
||||||
};
|
};
|
||||||
let mut right_luma = Game {
|
let mut right_luma = Game {
|
||||||
rules: Rules::random_u8b3(),
|
rules: generate_u8b3(),
|
||||||
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,8 +65,10 @@ fn main() {
|
||||||
loop {
|
loop {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
|
if iteration % Wrapping(5) == Wrapping(0) {
|
||||||
left_pixels.step();
|
left_pixels.step();
|
||||||
right_pixels.step();
|
right_pixels.step();
|
||||||
|
}
|
||||||
|
|
||||||
left_luma.step();
|
left_luma.step();
|
||||||
right_luma.step();
|
right_luma.step();
|
||||||
|
@ -81,8 +83,8 @@ fn main() {
|
||||||
|
|
||||||
randomize(&mut left_pixels.field);
|
randomize(&mut left_pixels.field);
|
||||||
randomize(&mut left_luma.field);
|
randomize(&mut left_luma.field);
|
||||||
left_pixels.rules = Rules::random_bb3();
|
left_pixels.rules = generate_bb3();
|
||||||
left_luma.rules = Rules::random_u8b3();
|
left_luma.rules = generate_u8b3();
|
||||||
} else if split_speed < 0 && split_pixel == 0 {
|
} else if split_speed < 0 && split_pixel == 0 {
|
||||||
split_pixel = pixels.width();
|
split_pixel = pixels.width();
|
||||||
|
|
||||||
|
@ -91,8 +93,8 @@ fn main() {
|
||||||
|
|
||||||
randomize(&mut right_pixels.field);
|
randomize(&mut right_pixels.field);
|
||||||
randomize(&mut right_luma.field);
|
randomize(&mut right_luma.field);
|
||||||
right_pixels.rules = Rules::random_bb3();
|
right_pixels.rules = generate_bb3();
|
||||||
right_luma.rules = Rules::random_u8b3();
|
right_luma.rules = generate_u8b3();
|
||||||
}
|
}
|
||||||
|
|
||||||
split_pixel = i32::clamp(split_pixel as i32 + split_speed, 0, pixels.width() as i32) as usize;
|
split_pixel = i32::clamp(split_pixel as i32 + split_speed, 0, pixels.width() as i32) as usize;
|
||||||
|
|
237
src/rules.rs
237
src/rules.rs
|
@ -1,5 +1,3 @@
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
use rand::{Rng, thread_rng};
|
use rand::{Rng, thread_rng};
|
||||||
use rand::rngs::ThreadRng;
|
use rand::rngs::ThreadRng;
|
||||||
|
|
||||||
|
@ -9,7 +7,7 @@ pub struct Rules<TState, TKernel, const KERNEL_SIZE: usize>
|
||||||
where TState: Copy + PartialEq, TKernel: Copy
|
where TState: Copy + PartialEq, TKernel: Copy
|
||||||
{
|
{
|
||||||
pub kernel: [[TKernel; KERNEL_SIZE]; KERNEL_SIZE],
|
pub kernel: [[TKernel; KERNEL_SIZE]; KERNEL_SIZE],
|
||||||
pub count_neighbor: fn(neighbor_state: TState, kernel_value: TKernel) -> i32,
|
pub count_neighbor: Box<dyn Fn(TState, TKernel) -> i32>,
|
||||||
pub next_state: Box<dyn Fn(TState, i32) -> TState>,
|
pub next_state: Box<dyn Fn(TState, i32) -> TState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +25,7 @@ pub const NEUMANN_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||||
|
|
||||||
pub const DIAGONALS_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
pub const DIAGONALS_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||||
[true, false, true],
|
[true, false, true],
|
||||||
[false, true, false],
|
[false, false, false],
|
||||||
[true, false, true]
|
[true, false, true]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -36,252 +34,73 @@ pub fn count_true_neighbor(neighbor_state: bool, kernel_value: bool) -> i32
|
||||||
if neighbor_state && kernel_value { 1 } else { 0 }
|
if neighbor_state && kernel_value { 1 } else { 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rules<bool, bool, 3> {
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn random_bb3() -> Self {
|
pub fn generate_bb3() -> Rules<bool, bool, 3> {
|
||||||
Self::generate_bb3()
|
|
||||||
|
|
||||||
/*
|
|
||||||
match rand::thread_rng().gen_range(0..=5) {
|
|
||||||
0 => Self::game_of_life(),
|
|
||||||
1 => Self::high_life(),
|
|
||||||
2 => Self::seeds(),
|
|
||||||
3 => Self::day_and_night(),
|
|
||||||
4 => Self::mazecetric(),
|
|
||||||
5 => Self::generate_bb3(),
|
|
||||||
_ => panic!(),
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn game_of_life() -> Self {
|
|
||||||
println_info("game of life");
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: count_true_neighbor,
|
|
||||||
next_state: Box::new(|old_state, neighbors|
|
|
||||||
matches!((old_state, neighbors), (true, 2) | (true, 3) | (false, 3))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn high_life() -> Self {
|
|
||||||
println_info("high life");
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: count_true_neighbor,
|
|
||||||
next_state: Box::new(|old_state, neighbors|
|
|
||||||
matches!((old_state, neighbors), (true, 2) | (true, 3) | (false, 3)| (false, 6))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn seeds() -> Self {
|
|
||||||
println_info("seeds");
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: count_true_neighbor,
|
|
||||||
next_state: Box::new(|state, neighbors|
|
|
||||||
matches!((state, neighbors), (false, 2))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn day_and_night() -> Self {
|
|
||||||
println_info("day_and_night");
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: count_true_neighbor,
|
|
||||||
next_state: Box::new(|state, neighbors| {
|
|
||||||
match (state, neighbors) {
|
|
||||||
(false, 3) => true,
|
|
||||||
(false, 6) => true,
|
|
||||||
(false, 7) => true,
|
|
||||||
(false, 8) => true,
|
|
||||||
(true, 3) => true,
|
|
||||||
(true, 4) => true,
|
|
||||||
(true, 6) => true,
|
|
||||||
(true, 7) => true,
|
|
||||||
(true, 8) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn mazecetric() -> Self {
|
|
||||||
println_info("mazecetric");
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: count_true_neighbor,
|
|
||||||
next_state: Box::new(|state, neighbors| {
|
|
||||||
match (state, neighbors) {
|
|
||||||
(false, 3) => true,
|
|
||||||
(true, 0) => false,
|
|
||||||
(true, n) if n < 5 => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn generate_bb3() -> Self {
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
let is_moore = rng.gen_bool(1.0 / 2.0);
|
let is_moore = rng.gen_bool(1.0 / 2.0);
|
||||||
let kernel = if is_moore { MOORE_NEIGHBORHOOD } else { NEUMANN_NEIGHBORHOOD };
|
let kernel = if is_moore { MOORE_NEIGHBORHOOD } else { NEUMANN_NEIGHBORHOOD };
|
||||||
let max_neighbors = if is_moore { 8 } else { 4 };
|
let max_neighbors = if is_moore { 8 } else { 4 };
|
||||||
|
|
||||||
let birth = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng);
|
let birth = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng, &[0]);
|
||||||
let survive = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng);
|
let survive = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng, &[]);
|
||||||
|
|
||||||
println_info(format!("generated bb3 moore: Birth {birth:?} Survival {survive:?}, is moore: {is_moore}"));
|
println_info(format!("generated bb3: Birth {birth:?} Survival {survive:?}, kernel: {kernel:?}"));
|
||||||
|
|
||||||
Self {
|
Rules {
|
||||||
kernel,
|
kernel,
|
||||||
count_neighbor: count_true_neighbor,
|
count_neighbor: Box::new(count_true_neighbor),
|
||||||
next_state: Box::new(move |old_state, neighbors| {
|
next_state: Box::new(move |old_state, neighbors| {
|
||||||
old_state && survive.contains(&neighbors)
|
old_state && survive.contains(&neighbors)
|
||||||
|| !old_state && birth.contains(&neighbors)
|
|| !old_state && birth.contains(&neighbors)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_neighbor_counts(count: u8, rng: &mut ThreadRng) -> HashSet<i32> {
|
fn generate_neighbor_counts(count: u8, rng: &mut ThreadRng, exclude: &[i32]) -> Vec<i32> {
|
||||||
let mut result = HashSet::new();
|
let mut result = vec!();
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
result.insert(rng.gen_range(0..=count) as i32);
|
let value = rng.gen_range(0..=count) as i32;
|
||||||
|
if !exclude.contains(&value) {
|
||||||
|
result.push(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rules<u8, bool, 3> {
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn random_u8b3() -> Self {
|
pub fn generate_u8b3() -> Rules<u8, bool, 3> {
|
||||||
Self::generate_u8b3()
|
|
||||||
/*
|
|
||||||
match rand::thread_rng().gen_range(0..3) {
|
|
||||||
0 => Self::brians_brain(),
|
|
||||||
1 => Self::continuous_game_of_life(),
|
|
||||||
2 => Self::equalizer(),
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn brians_brain() -> Self {
|
|
||||||
const ALIVE: u8 = u8::MAX;
|
|
||||||
const DYING: u8 = ALIVE / 2;
|
|
||||||
const DEAD: u8 = 0;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: |state, kernel| {
|
|
||||||
if kernel && state == u8::MAX { 1 } else { 0 }
|
|
||||||
},
|
|
||||||
next_state: Box::new(|state, neighbors| {
|
|
||||||
match (state, neighbors) {
|
|
||||||
(ALIVE, _) => DYING,
|
|
||||||
(DYING, _) => DEAD,
|
|
||||||
(DEAD, 2) => ALIVE,
|
|
||||||
(random_state, _) => if random_state > DYING {
|
|
||||||
ALIVE
|
|
||||||
} else {
|
|
||||||
DEAD
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn continuous_game_of_life() -> Self {
|
|
||||||
Self {
|
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
|
||||||
count_neighbor: |state, kernel| {
|
|
||||||
if kernel && state >= u8::MAX / 2 { 1 } else { 0 }
|
|
||||||
},
|
|
||||||
next_state: Box::new(|old_state, neighbors| {
|
|
||||||
let is_alive = old_state >= u8::MAX / 2;
|
|
||||||
let delta = match (is_alive, neighbors) {
|
|
||||||
(true, 2) | (true, 3) | (false, 3) => 10,
|
|
||||||
_ => -10,
|
|
||||||
};
|
|
||||||
|
|
||||||
i32::clamp(old_state as i32 + delta, u8::MIN as i32, u8::MAX as i32) as u8
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn equalizer() -> Self {
|
|
||||||
Self {
|
|
||||||
kernel: DIAGONALS_NEIGHBORHOOD,
|
|
||||||
count_neighbor: |state, kernel| {
|
|
||||||
let state = state as i32;
|
|
||||||
if kernel {
|
|
||||||
state
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
next_state: Box::new(|old_state, neighbors| {
|
|
||||||
if old_state % 42 == 0 {
|
|
||||||
return u8::MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if old_state % 23 == 0 {
|
|
||||||
return u8::MIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
let average_health = neighbors / 5;
|
|
||||||
let delta = if average_health > old_state as i32 {
|
|
||||||
10
|
|
||||||
} else {
|
|
||||||
-10
|
|
||||||
};
|
|
||||||
|
|
||||||
i32::clamp(old_state as i32 + delta, u8::MIN as i32, u8::MAX as i32) as u8
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn generate_u8b3() -> Self {
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
let is_moore = rng.gen_bool(1.0 / 2.0);
|
let kernel = match rng.gen_range(0..3) {
|
||||||
let kernel = if is_moore { MOORE_NEIGHBORHOOD } else { NEUMANN_NEIGHBORHOOD };
|
0 => MOORE_NEIGHBORHOOD,
|
||||||
let max_neighbors = if is_moore { 8 } else { 4 };
|
1 => NEUMANN_NEIGHBORHOOD,
|
||||||
|
2 => DIAGONALS_NEIGHBORHOOD,
|
||||||
|
_ => panic!()
|
||||||
|
};
|
||||||
|
|
||||||
let alive_threshold = rng.gen();
|
let alive_threshold = rng.gen();
|
||||||
|
|
||||||
let birth = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng);
|
let birth = generate_neighbor_counts(rng.gen_range(1..=9), &mut rng, &[0]);
|
||||||
let survive = generate_neighbor_counts(rng.gen_range(1..=max_neighbors), &mut rng);
|
let survive = generate_neighbor_counts(rng.gen_range(1..=9 - birth.len()) as u8, &mut rng, &[]);
|
||||||
|
|
||||||
let add = rng.gen_range(5..40);
|
let add = rng.gen_range(5..40);
|
||||||
let sub = rng.gen_range(5..40);
|
let sub = rng.gen_range(5..40);
|
||||||
|
|
||||||
println_info(format!("generated bb3 moore: Birth {birth:?} Survival {survive:?}, is moore: {is_moore}"));
|
println_info(format!("generated u8b3: Birth {birth:?} Survival {survive:?}, kernel: {kernel:?}, alive_thresh: {alive_threshold}, delta: {add}/{sub}"));
|
||||||
|
|
||||||
Self {
|
Rules {
|
||||||
kernel,
|
kernel,
|
||||||
count_neighbor: |state, kernel| {
|
count_neighbor: Box::new(|state, kernel| {
|
||||||
if kernel { state as i32 } else { 0 }
|
if kernel { state as i32 } else { 0 }
|
||||||
},
|
}),
|
||||||
next_state: Box::new(move |old_state, neighbors| {
|
next_state: Box::new(move |old_state, neighbors| {
|
||||||
let neighbors = neighbors / alive_threshold as i32;
|
let neighbors = neighbors / alive_threshold as i32;
|
||||||
let old_is_alive = old_state >= alive_threshold;
|
let old_is_alive = old_state >= alive_threshold;
|
||||||
let new_is_alive = old_is_alive && survive.contains(&neighbors)
|
let new_is_alive = old_is_alive && survive.contains(&neighbors)
|
||||||
|| !old_is_alive && birth.contains(&neighbors);
|
|| !old_is_alive && birth.contains(&neighbors);
|
||||||
let delta = if new_is_alive { add as i32 } else { -(sub as i32) };
|
let delta = if new_is_alive { add } else { -sub };
|
||||||
i32::clamp(old_state as i32 + delta, u8::MIN as i32, u8::MAX as i32) as u8
|
i32::clamp(old_state as i32 + delta, u8::MIN as i32, u8::MAX as i32) as u8
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue