mazecetric, random one
This commit is contained in:
parent
22faceab57
commit
fb02ed4080
29
src/main.rs
29
src/main.rs
|
@ -12,7 +12,7 @@ use crossterm::terminal::{
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use rand::distributions::{Distribution, Standard};
|
use rand::distributions::{Distribution, Standard};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use servicepoint2::{ByteGrid, CompressionCode, Connection, FRAME_PACING, Grid, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH};
|
use servicepoint2::{ByteGrid, CompressionCode, Connection, Grid, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH};
|
||||||
use servicepoint2::Command::{BitmapLinearWin, CharBrightness};
|
use servicepoint2::Command::{BitmapLinearWin, CharBrightness};
|
||||||
|
|
||||||
use crate::game::Game;
|
use crate::game::Game;
|
||||||
|
@ -33,19 +33,19 @@ fn main() {
|
||||||
let connection = init();
|
let connection = init();
|
||||||
|
|
||||||
let mut left_pixels = Game {
|
let mut left_pixels = Game {
|
||||||
rules: Rules::day_and_night(),
|
rules: Rules::random_bb3(),
|
||||||
field: PixelGrid::max_sized(),
|
field: PixelGrid::max_sized(),
|
||||||
};
|
};
|
||||||
let mut right_pixels = Game {
|
let mut right_pixels = Game {
|
||||||
rules: Rules::seeds(),
|
rules: Rules::random_bb3(),
|
||||||
field: PixelGrid::max_sized(),
|
field: PixelGrid::max_sized(),
|
||||||
};
|
};
|
||||||
let mut left_luma = Game {
|
let mut left_luma = Game {
|
||||||
rules: Rules::continuous_game_of_life(),
|
rules: Rules::random_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::continuous_game_of_life(),
|
rules: Rules::random_u8b3(),
|
||||||
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
field: ByteGrid::new(TILE_WIDTH, TILE_HEIGHT),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,16 +75,24 @@ fn main() {
|
||||||
|
|
||||||
if split_speed > 0 && split_pixel == pixels.width() {
|
if split_speed > 0 && split_pixel == pixels.width() {
|
||||||
split_pixel = 0;
|
split_pixel = 0;
|
||||||
|
|
||||||
(left_luma, right_luma) = (right_luma, left_luma);
|
(left_luma, right_luma) = (right_luma, left_luma);
|
||||||
(left_pixels, right_pixels) = (right_pixels, left_pixels);
|
(left_pixels, right_pixels) = (right_pixels, left_pixels);
|
||||||
|
|
||||||
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_luma.rules = Rules::random_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();
|
||||||
|
|
||||||
(left_luma, right_luma) = (right_luma, left_luma);
|
(left_luma, right_luma) = (right_luma, left_luma);
|
||||||
(left_pixels, right_pixels) = (right_pixels, left_pixels);
|
(left_pixels, right_pixels) = (right_pixels, left_pixels);
|
||||||
|
|
||||||
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_luma.rules = Rules::random_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;
|
||||||
|
@ -122,9 +130,10 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let wanted_time = Duration::from_millis(100);
|
||||||
let tick_time = start.elapsed();
|
let tick_time = start.elapsed();
|
||||||
if tick_time < FRAME_PACING {
|
if tick_time < wanted_time {
|
||||||
thread::sleep(FRAME_PACING - tick_time);
|
thread::sleep(wanted_time - tick_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,11 +220,7 @@ fn draw_luma(luma: &mut ByteGrid, left: &ByteGrid, right: &ByteGrid, split_tile:
|
||||||
for x in 0..luma.width() {
|
for x in 0..luma.width() {
|
||||||
let left_or_right = if x < split_tile { left } else { right };
|
let left_or_right = if x < split_tile { left } else { right };
|
||||||
for y in 0..luma.height() {
|
for y in 0..luma.height() {
|
||||||
let set = if x == split_tile {
|
let set = u8::max(48, left_or_right.get(x, y));
|
||||||
255
|
|
||||||
} else {
|
|
||||||
u8::max(48, left_or_right.get(x, y))
|
|
||||||
};
|
|
||||||
luma.set(x, y, set);
|
luma.set(x, y, set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
87
src/rules.rs
87
src/rules.rs
|
@ -1,3 +1,5 @@
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
pub struct Rules<TState, TKernel, const KERNEL_SIZE: usize>
|
pub struct Rules<TState, TKernel, const KERNEL_SIZE: usize>
|
||||||
where TState: Copy + PartialEq, TKernel: Copy
|
where TState: Copy + PartialEq, TKernel: Copy
|
||||||
{
|
{
|
||||||
|
@ -12,12 +14,36 @@ pub const MOORE_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||||
[true, true, true]
|
[true, true, true]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub const NEUMANN_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||||
|
[false, true, false],
|
||||||
|
[true, false, true],
|
||||||
|
[false, true, false]
|
||||||
|
];
|
||||||
|
|
||||||
|
pub const DIAGONALS_NEIGHBORHOOD: [[bool; 3]; 3] = [
|
||||||
|
[true, false, true],
|
||||||
|
[false, true, false],
|
||||||
|
[true, false, true]
|
||||||
|
];
|
||||||
|
|
||||||
pub fn count_true_neighbor(neighbor_state: bool, kernel_value: bool) -> i32
|
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> {
|
impl Rules<bool, bool, 3> {
|
||||||
|
#[must_use]
|
||||||
|
pub fn random_bb3() -> Self {
|
||||||
|
match rand::thread_rng().gen_range(0..=4) {
|
||||||
|
0 => Self::game_of_life(),
|
||||||
|
1 => Self::high_life(),
|
||||||
|
2 => Self::seeds(),
|
||||||
|
3 => Self::day_and_night(),
|
||||||
|
4 => Self::mazecetric(),
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn game_of_life() -> Self {
|
pub fn game_of_life() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -69,9 +95,35 @@ impl Rules<bool, bool, 3> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn mazecetric() -> Self {
|
||||||
|
Self {
|
||||||
|
kernel: MOORE_NEIGHBORHOOD,
|
||||||
|
count_neighbor: count_true_neighbor,
|
||||||
|
next_state: |state, neighbors| {
|
||||||
|
match (state, neighbors) {
|
||||||
|
(false, 3) => true,
|
||||||
|
(true, 0) => false,
|
||||||
|
(true, n) if n < 5 => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rules<u8, bool, 3> {
|
impl Rules<u8, bool, 3> {
|
||||||
|
#[must_use]
|
||||||
|
pub fn random_u8b3() -> Self {
|
||||||
|
match rand::thread_rng().gen_range(0..3) {
|
||||||
|
0 => Self::brians_brain(),
|
||||||
|
1 => Self::continuous_game_of_life(),
|
||||||
|
2 => Self::equalizer(),
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn brians_brain() -> Self {
|
pub fn brians_brain() -> Self {
|
||||||
const ALIVE: u8 = u8::MAX;
|
const ALIVE: u8 = u8::MAX;
|
||||||
|
@ -98,6 +150,8 @@ impl Rules<u8, bool, 3> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub fn continuous_game_of_life() -> Self {
|
pub fn continuous_game_of_life() -> Self {
|
||||||
Self {
|
Self {
|
||||||
kernel: MOORE_NEIGHBORHOOD,
|
kernel: MOORE_NEIGHBORHOOD,
|
||||||
|
@ -115,5 +169,38 @@ impl Rules<u8, bool, 3> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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: |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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue