Introduce Life type in game_of_life

This commit is contained in:
Héctor Ramón Jiménez 2020-05-01 01:08:39 +02:00
parent 71323c51bb
commit a6db1e1fb3

View File

@ -163,7 +163,7 @@ mod grid {
#[derive(Default)]
pub struct Grid {
life: HashSet<Cell>,
life: Life,
interaction: Interaction,
cache: canvas::Cache,
translation: Vector,
@ -176,35 +176,14 @@ mod grid {
impl Grid {
pub fn tick(&mut self) {
use itertools::Itertools;
let populated_neighbors: HashMap<Cell, usize> = self
.life
.iter()
.flat_map(Cell::cluster)
.unique()
.map(|cell| (cell, self.count_adjacent_life(cell)))
.collect();
for (cell, amount) in populated_neighbors.iter() {
match amount {
2 => {}
3 => {
let _ = self.life.insert(*cell);
}
_ => {
let _ = self.life.remove(cell);
}
}
}
self.life.tick();
self.cache.clear()
}
pub fn update(&mut self, message: Message) {
match message {
Message::Populate(cell) => {
self.life.insert(cell);
self.life.populate(cell);
self.cache.clear()
}
}
@ -216,17 +195,6 @@ mod grid {
.height(Length::Fill)
.into()
}
fn count_adjacent_life(&self, cell: Cell) -> usize {
let cluster = Cell::cluster(&cell);
let is_neighbor = |candidate| candidate != cell;
let is_populated = |cell| self.life.contains(&cell);
cluster
.filter(|&cell| is_neighbor(cell) && is_populated(cell))
.count()
}
}
impl<'a> canvas::Program<Message> for Grid {
@ -370,6 +338,56 @@ mod grid {
}
}
#[derive(Default)]
pub struct Life {
cells: HashSet<Cell>,
}
impl Life {
fn contains(&self, cell: &Cell) -> bool {
self.cells.contains(cell)
}
fn populate(&mut self, cell: Cell) {
self.cells.insert(cell);
}
fn tick(&mut self) {
use itertools::Itertools;
let populated_neighbors: HashMap<Cell, usize> = self
.cells
.iter()
.flat_map(Cell::cluster)
.unique()
.map(|cell| (cell, self.count_adjacent(cell)))
.collect();
for (cell, amount) in populated_neighbors.iter() {
match amount {
2 => {}
3 => {
let _ = self.cells.insert(*cell);
}
_ => {
let _ = self.cells.remove(cell);
}
}
}
}
fn count_adjacent(&self, cell: Cell) -> usize {
let cluster = Cell::cluster(&cell);
let is_neighbor = |candidate| candidate != cell;
let is_populated = |cell| self.cells.contains(&cell);
cluster
.filter(|&cell| is_neighbor(cell) && is_populated(cell))
.count()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Cell {
i: isize,