auto resize region when patterns hit the edge

This commit is contained in:
Crispy 2023-07-21 16:36:33 +02:00
parent 4a096adfe2
commit d22ed686e3
3 changed files with 73 additions and 45 deletions

View file

@ -3,12 +3,14 @@ mod tile;
use region::Region; use region::Region;
fn main() { fn main() {
let mut region = Region::new(); let mut region = Region::new(1, 1);
region.randomise();
loop { loop {
println!("####################"); println!("####################");
region.print_all(); region.print_all(true);
region.step(); region.step();
region.auto_grow();
{ {
let mut a = String::new(); let mut a = String::new();
std::io::stdin().read_line(&mut a).unwrap(); std::io::stdin().read_line(&mut a).unwrap();

View file

@ -3,25 +3,19 @@ use crate::tile::{Edges, Tile, WIDTH};
pub struct Region { pub struct Region {
/// rows of tiles /// rows of tiles
tiles: Vec<Vec<Tile>>, tiles: Vec<Vec<Tile>>,
auto_expand: bool,
} }
impl Region { impl Region {
pub fn new() -> Self { pub fn new(width: usize, height: usize) -> Self {
let width = 2; let tiles = vec![vec![Tile::new(); width]; height];
let height = 2; Self { tiles }
let mut tiles = Vec::new();
for _ in 0..height {
let mut row = Vec::new();
for _ in 0..width {
row.push(Tile::random());
}
tiles.push(row);
} }
Self { pub fn randomise(&mut self) {
tiles, for row in self.tiles.iter_mut() {
auto_expand: false, for tile in row {
tile.randomise()
}
} }
} }
@ -33,22 +27,25 @@ impl Region {
self.tiles[0].len() self.tiles[0].len()
} }
pub fn print_all(&self) { pub fn print_all(&self, tile_grid: bool) {
for y in 0..self.height() { for y in 0..self.height() {
for ch_row in 0..(WIDTH / 2) { for ch_row in 0..(WIDTH / 2) {
for x in 0..self.width() { for x in 0..self.width() {
self.tiles[y][x].print_row(ch_row); self.tiles[y][x].print_row(ch_row);
// print!("|"); if tile_grid {
print!("|");
}
} }
println!() println!()
} }
// println!("------"); if tile_grid {
println!(
"{}",
format!("{:->w$}", "+", w = WIDTH + 1).repeat(self.width())
);
}
} }
} }
// pub fn set_cell(&mut self, x: isize, y: isize, state: bool) {
// //
// }
fn get_tile_relative(&self, x: usize, y: usize, relx: isize, rely: isize) -> Option<&Tile> { fn get_tile_relative(&self, x: usize, y: usize, relx: isize, rely: isize) -> Option<&Tile> {
self.tiles self.tiles
@ -82,8 +79,33 @@ impl Region {
self.tiles[y][x].step(&edges[y][x]); self.tiles[y][x].step(&edges[y][x]);
} }
} }
if self.auto_expand { }
// todo
pub fn auto_grow(&mut self) {
if self.tiles[0].iter().any(|tile| tile.rows[0] != 0) {
let row = vec![Tile::new(); self.width()];
self.tiles.insert(0, row);
}
if self.tiles[self.height() - 1]
.iter()
.any(|tile| tile.rows[WIDTH - 1] != 0)
{
let row = vec![Tile::new(); self.width()];
self.tiles.push(row);
}
if self.tiles.iter().any(|row| row[0].edge_west() != 0) {
for row in &mut self.tiles {
row.insert(0, Tile::new());
}
}
if self
.tiles
.iter()
.any(|row| row[row.len() - 1].edge_east() != 0)
{
for row in &mut self.tiles {
row.push(Tile::new());
}
} }
} }
} }

View file

@ -1,4 +1,4 @@
pub type Row = u64; type Row = u16;
pub const WIDTH: usize = Row::BITS as usize; pub const WIDTH: usize = Row::BITS as usize;
const LAST: usize = WIDTH - 1; const LAST: usize = WIDTH - 1;
@ -24,19 +24,29 @@ impl Tile {
pub const EMPTY: Tile = Tile { rows: [0; WIDTH] }; pub const EMPTY: Tile = Tile { rows: [0; WIDTH] };
pub fn new() -> Self { pub fn new() -> Self {
Self { rows: [0; WIDTH] } Self::EMPTY
} }
pub fn is_empty(&self) -> bool { pub fn edge_east(&self) -> Row {
self.rows.iter().fold(0, |a, r| a | r) == 0 let mut edge = 0;
for n in 0..WIDTH {
edge |= (self.rows[n] & 1) << n;
}
edge
} }
pub fn random() -> Self { pub fn edge_west(&self) -> Row {
let mut t = Self::new(); let mut edge = 0;
for r in 0..(WIDTH / 2) { for n in 0..WIDTH {
t.rows[r] = rand::random(); edge |= (self.rows[n] >> LAST) << n;
}
edge
}
pub fn randomise(&mut self) {
for r in 0..WIDTH {
self.rows[r] = rand::random();
} }
t
} }
pub fn print_row(&self, ch_row: usize) { pub fn print_row(&self, ch_row: usize) {
@ -144,17 +154,11 @@ impl Edges {
se: &Tile, se: &Tile,
sw: &Tile, sw: &Tile,
) -> Self { ) -> Self {
let mut east = 0;
let mut west = 0;
for n in 0..WIDTH {
east |= (e.rows[n] >> LAST) << n;
west |= (w.rows[n] & 1) << n;
}
Self { Self {
n: n.rows[LAST], n: n.rows[LAST],
s: s.rows[0], s: s.rows[0],
e: east, e: e.edge_west(),
w: west, w: w.edge_east(),
nw: (nw.rows[LAST] & 1) != 0, nw: (nw.rows[LAST] & 1) != 0,
ne: (ne.rows[LAST] >> LAST) != 0, ne: (ne.rows[LAST] >> LAST) != 0,
sw: (sw.rows[0] & 1) != 0, sw: (sw.rows[0] & 1) != 0,