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;
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();

View file

@ -3,25 +3,19 @@ use crate::tile::{Edges, Tile, WIDTH};
pub struct Region {
/// rows of tiles
tiles: Vec<Vec<Tile>>,
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());
}
}
}
}

View file

@ -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,