grid_sim/world/builder/
mod.rs1pub mod designs;
2use self::designs::Design;
3use world::{Cell, CellState};
4extern crate rand;
5use std::str::FromStr;
6use rand::Rng;
7
8#[derive(Clone)]
11pub enum InitialState {
12 Blank(CellState),
13 Random,
14 Ordered(Vec<(u64, u64)>),
15 Library(Design),
16 Lambda,
17}
18impl FromStr for InitialState {
19 type Err = ();
20 fn from_str(s: &str) -> Result<InitialState, ()> {
21 match s {
22 "Random" => Ok(InitialState::Random),
24 "Blank" => Ok(InitialState::Blank(CellState::Dead)),
25 "Filled" => Ok(InitialState::Blank(CellState::Live)),
26 "Eureka" => Ok(InitialState::Library(Design::Eureka)),
28 _ => Err(()),
29 }
30 }
31}
32pub struct WorldBuilder {
33 width: usize,
34 height: usize,
35 init: InitialState,
36}
37impl WorldBuilder {
38 pub fn new(width: usize, height: usize, init: InitialState) -> Self {
39 WorldBuilder {
40 width: width,
41 height: height,
42 init: init,
43 }
44 }
45 fn gen_index(&self, x: u64, y: u64) -> usize {
46 x as usize + y as usize * self.width as usize
47 }
48 fn add_cells(&self, grid_ref: &mut Vec<Cell>, w: usize, h: usize) {
49 for y in 0..h {
51 for x in 0..w {
52 let cell = Cell::new((x as u64,y as u64), CellState::Uninitialized);
53 grid_ref.push(cell);
54 }
55 }
56 }
57 pub fn build(&self, grid_ref: &mut Vec<Cell>) {
58 self.add_cells(grid_ref, self.width, self.height);
59
60 match self.init {
62 InitialState::Blank(ref state) => WorldBuilder::populate_all(grid_ref, state.clone()),
63 InitialState::Random => WorldBuilder::populate_random(grid_ref),
64 InitialState::Ordered(ref coords) => {
65 self.populate_ordered(grid_ref, coords);
66 },
67 InitialState::Library(ref design) => {
68 self.populate_library(grid_ref, design);
69 },
70 InitialState::Lambda => (),
72 }
73 }
74 fn populate_all(grid_ref: &mut Vec<Cell>, state: CellState) {
75 for cell in grid_ref.iter_mut() {
76 cell.set_state(state.clone());
77 }
78 }
79 fn populate_random(grid_ref: &mut Vec<Cell>) {
80 let mut rng = rand::thread_rng();
81 for cell in grid_ref.iter_mut() {
82 match rng.gen() {
83 true => cell.set_state(CellState::Live),
84 false => cell.set_state(CellState::Dead),
85 };
86 }
87 }
88 fn populate_ordered(&self, grid_ref: &mut Vec<Cell>, coords: &Vec<(u64, u64)>) {
89 WorldBuilder::populate_all(grid_ref, CellState::Dead);
90 for coord in coords.iter() {
91 match grid_ref.get_mut(self.gen_index(coord.0, coord.1)) {
92 Some(cell) => {
93 cell.set_state(CellState::Live);
94 },
95 None => panic!("invalid init coord"),
96 }
97 }
98 }
99 fn populate_library(&self, grid_ref: &mut Vec<Cell>, design: &Design) {
100 let data = design.get_data();
101 self.populate_ordered(grid_ref, &data);
102 }
103 }