Browse Source

Code I wrote before the break. Not sure what some of it is doing anymore.

master
Thomas Johnson 2 years ago
commit
bbb15cc8cf
  1. 2
      .gitignore
  2. 9
      Cargo.toml
  3. 287
      src/grid.rs
  4. 7
      src/main.rs

2
.gitignore

@ -0,0 +1,2 @@
/target
Cargo.lock

9
Cargo.toml

@ -0,0 +1,9 @@
[package]
name = "cells"
version = "0.1.0"
authors = ["thajohns <thajohns@clarkson.edu>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

287
src/grid.rs

@ -0,0 +1,287 @@
use std::collections::hash_map::HashMap;
use std::cell::RefCell;
pub const TILEBITS: usize = 8;
pub const TILESIZE: usize = 1 << TILEBITS;
pub struct Grid
{
tiles: HashMap<(isize, isize), RefCell<Tile>>,
}
pub struct Tile
{
which: bool,
cells: [[Cell; TILESIZE]; TILESIZE],
}
#[derive(Copy, Clone, Debug)]
pub struct Cell
{
// Switch between which of the states we use.
first: State,
second: State,
}
#[derive(Copy, Clone, Debug)]
enum State
{
Dead(),
Alive(),
}
impl Grid
{
fn get(&self, x: isize, y: isize) -> State
{
let (xtile, ytile) = (x >> TILEBITS, y >> TILEBITS);
match self.tiles.get(&(xtile, ytile))
{
None => State::Dead(),
Some(tile) =>
{
let tile = tile.borrow();
*tile.cells[(x & (TILESIZE as isize - 1)) as usize][(y & (TILESIZE as isize - 1)) as usize].get(tile.which)
},
}
}
fn get_other(&self, x: isize, y: isize) -> State
{
let (xtile, ytile) = (x >> TILEBITS, y >> TILEBITS);
match self.tiles.get(&(xtile, ytile))
{
None => State::Dead(),
Some(tile) =>
{
let tile = tile.borrow();
*tile.cells[(x & (TILESIZE as isize - 1)) as usize][(y & (TILESIZE as isize - 1)) as usize].get_other(tile.which)
},
}
}
fn set(&mut self, x: isize, y: isize, state: State)
{
let (xtile, ytile) = (x >> TILEBITS, y >> TILEBITS);
let (xminor, yminor) = ((x & (TILESIZE - 1) as isize) as usize, (y & (TILESIZE - 1) as isize) as usize);
match self.tiles.get(&(xtile, ytile))
{
None => if let State::Alive() = state
{
let mut tile = Tile::new_blank(false);
let which = tile.which;
tile.cells[xminor][yminor].set(state, which);
self.tiles.insert((xtile, ytile), RefCell::new(tile));
},
Some(tile) =>
{
let mut tile = tile.borrow_mut();
let which = tile.which;
tile.cells[xminor][yminor].set(state, which);
},
}
}
pub fn step(&mut self, on: (usize, usize), off: (usize, usize))
{
for ent in self.tiles.iter()
{
let mut tile = ent.1.borrow_mut();
tile.do_step_internal(on, off);
for xg in 0..TILESIZE
{
for yg in 0..TILESIZE
{
let get_tile_offset = |xoff: usize, yoff: usize|
{
let (xl, yl);
let (xtile, ytile);
let (xoff, yoff) = (xoff + xg, yoff + yg);
let mut thistile = true;
if xoff >= TILESIZE
{
xtile = (ent.0).0 + 1;
xl = 0;
thistile = false;
} else if xoff < 0
{
xtile = (ent.0).0 - 1;
xl = TILESIZE - 1;
thistile = false;
} else
{
xtile = (ent.0).0;
xl = xoff;
}
if yoff >= TILESIZE
{
ytile = (ent.0).1 + 1;
yl = 0;
thistile = false;
} else if yoff < 0
{
ytile = (ent.0).1 - 1;
yl = TILESIZE - 1;
thistile = false;
} else
{
ytile = (ent.0).1;
yl = yoff;
}
if thistile
{
} else
{
}
};
}
}
}
}
}
impl Tile
{
fn new_blank(which: bool) -> Tile
{
Tile
{
which,
cells: [[Cell {first: State::Dead(), second: State::Dead()}; TILESIZE]; TILESIZE],
}
}
fn do_step_internal(&mut self, on: (usize, usize), off: (usize, usize))
{
let mut parity = false;
let which = self.which;
let cells = &mut self.cells;
let mut count =
{
let mut count = 0;
for x in 0..3
{
for y in 0..3
{
if x != 1 || y != 1
{
if let &State::Alive() = cells[x][y].get(which)
{
count += 1;
}
}
}
}
count
};
for x in 1..TILESIZE - 1
{
enum IterChoice<A, B> { A(A), B(B) };
impl<A, B, Item> IterChoice<A, B> where
A: Iterator<Item = Item>,
B: Iterator<Item = Item>,
{
fn inner(&mut self) -> &mut dyn Iterator<Item = Item>
{ match self { Self::A(ref mut a) => a, Self::B(ref mut b) => b } }
};
let mut range = if parity { IterChoice::A(1 .. TILESIZE - 2) }
else { IterChoice::B((2 .. TILESIZE - 1).rev()) };
for y in range.inner()
{
match cells[x][y].get(which)
{
State::Alive() =>
{
if off.0 <= count && count <= off.1 { cells[x][y].set_other(State::Dead(), which); }
},
State::Dead() =>
{
if on.0 <= count && count <= on.1 { cells[x][y].set_other(State::Alive(), which); }
},
}
let shift = if parity { 1 } else { 0 };
for x0 in x - 1 ..= x + 1
{
if let State::Alive() = cells[x0][y - 1 - shift].get(which)
{
if parity { count += 1; }
else { count -= 1; }
}
if let State::Alive() = cells[x0][y + 2 - shift].get(which)
{
if parity { count -= 1; }
else { count += 1; }
}
}
parity = !parity;
}
{
let y = TILESIZE - 2;
match cells[x][y].get(which)
{
State::Alive() =>
{
if off.0 <= count && count <= off.1 { cells[x][y].set_other(State::Dead(), which); }
},
State::Dead() =>
{
if on.0 <= count && count <= on.1 { cells[x][y].set_other(State::Alive(), which); }
},
}
for y0 in y - 1 ..= y + 1
{
if let State::Alive() = cells[x - 1][y0].get(which)
{
count -= 1;
}
if let State::Alive() = cells[x + 2][y0].get(which)
{
count += 1;
}
}
}
}
}
}
impl Cell
{
fn get(&self, which: bool) -> &State
{
if which
{
&self.first
} else
{
&self.second
}
}
fn get_other(&self, which: bool) -> &State
{
self.get(!which)
}
fn set(&mut self, new: State, which: bool)
{
if which
{
self.first = new;
} else
{
self.second = new;
}
}
fn set_other(&mut self, new: State, which: bool)
{
self.set(new, !which);
}
}

7
src/main.rs

@ -0,0 +1,7 @@
#![feature(const_in_array_repeat_expressions)]
mod grid;
fn main()
{
}
Loading…
Cancel
Save