diff --git a/src/main.rs b/src/main.rs index 277c1d7..1d4e7b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,14 @@ mod tile; use region::Region; fn main() { - let mut region = Region::new(); + let mut region = Region::new(1, 1); + region.randomise(); loop { println!("####################"); - region.print_all(); + region.print_all(true); region.step(); + region.auto_grow(); { let mut a = String::new(); std::io::stdin().read_line(&mut a).unwrap(); diff --git a/src/region.rs b/src/region.rs index 95960a9..f20ab26 100644 --- a/src/region.rs +++ b/src/region.rs @@ -3,25 +3,19 @@ use crate::tile::{Edges, Tile, WIDTH}; pub struct Region { /// rows of tiles tiles: Vec>, - auto_expand: bool, } impl Region { - pub fn new() -> Self { - let width = 2; - let height = 2; - 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); - } + pub fn new(width: usize, height: usize) -> Self { + let tiles = vec![vec![Tile::new(); width]; height]; + Self { tiles } + } - Self { - tiles, - auto_expand: false, + pub fn randomise(&mut self) { + for row in self.tiles.iter_mut() { + for tile in row { + tile.randomise() + } } } @@ -33,23 +27,26 @@ impl Region { self.tiles[0].len() } - pub fn print_all(&self) { + pub fn print_all(&self, tile_grid: bool) { for y in 0..self.height() { for ch_row in 0..(WIDTH / 2) { for x in 0..self.width() { self.tiles[y][x].print_row(ch_row); - // print!("|"); + if tile_grid { + print!("|"); + } } 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> { self.tiles .get(y.checked_add_signed(rely)?) @@ -82,8 +79,33 @@ impl Region { 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()); + } } } } diff --git a/src/tile.rs b/src/tile.rs index 33a4dd3..ed6f5c6 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -1,4 +1,4 @@ -pub type Row = u64; +type Row = u16; pub const WIDTH: usize = Row::BITS as usize; const LAST: usize = WIDTH - 1; @@ -24,19 +24,29 @@ impl Tile { pub const EMPTY: Tile = Tile { rows: [0; WIDTH] }; pub fn new() -> Self { - Self { rows: [0; WIDTH] } + Self::EMPTY } - pub fn is_empty(&self) -> bool { - self.rows.iter().fold(0, |a, r| a | r) == 0 - } - - pub fn random() -> Self { - let mut t = Self::new(); - for r in 0..(WIDTH / 2) { - t.rows[r] = rand::random(); + pub fn edge_east(&self) -> Row { + let mut edge = 0; + for n in 0..WIDTH { + edge |= (self.rows[n] & 1) << n; + } + edge + } + + pub fn edge_west(&self) -> Row { + let mut edge = 0; + for n in 0..WIDTH { + 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) { @@ -144,17 +154,11 @@ impl Edges { se: &Tile, sw: &Tile, ) -> 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 { n: n.rows[LAST], s: s.rows[0], - e: east, - w: west, + e: e.edge_west(), + w: w.edge_east(), nw: (nw.rows[LAST] & 1) != 0, ne: (ne.rows[LAST] >> LAST) != 0, sw: (sw.rows[0] & 1) != 0,