1pub mod cell;
2use self::cell::{Cell, CellState};
3pub mod builder;
4use self::builder::{InitialState, WorldBuilder};
5pub mod return_types;
6use self::return_types::{StepResult, StepError};
7pub mod rules;
8use self::rules::{DSLRuleset, Rulesets};
9use self::rules::input_cells::InputCells;
10
11#[derive(Clone)]
12pub struct WorldOptions {
13 pub width: usize,
14 pub height: usize,
15 pub init: InitialState,
16 pub input_cells: InputCells,
17 pub rules: Rulesets,
18}
19impl WorldOptions {
20 pub fn new() -> Self {
21 WorldOptions {
22 width: 0,
23 height: 0,
24 init: InitialState::Random,
25 input_cells: InputCells::Neighbors,
26 rules: Rulesets::Conway,
27 }
28 }
29}
30
31pub struct World {
32 time: u64,
33 width: usize,
34 height: usize,
35 grid: Vec<Cell>,
36 input_cells: InputCells,
37 rules: DSLRuleset,
38}
39impl World {
40 pub fn new(options: WorldOptions) -> Self {
41 let (w, h) = (options.width, options.height);
42
43 let mut grid = Vec::with_capacity(w as usize * h as usize);
44
45 let wb = WorldBuilder::new(w, h, options.init);
46 wb.build(&mut grid);
52
53 let rules = options.rules.get_data();
54
55 World {
56 time: 0,
57 width: w, height: h,
58 grid: grid,
59 input_cells: options.input_cells,
60 rules: rules,
61 }
62 }
63
64 fn set_cell_state(&mut self, index: usize, new: CellState) {
65 if let Some(cell) = self.grid.get_mut(index) {
66 cell.set_state(new)
67 }
68 }
69
70 fn get_cell_state(&self, xy: (u64, u64)) -> CellState {
71 let index = xy.0 + self.width as u64 * xy.1;
72
73 match self.grid.get(index as usize) {
74 Some(cell) => cell.get_state().clone(),
75 None => CellState::OOB,
76 }
77 }
78
79 fn get_neighbor_states(&self, xy: (u64, u64)) -> Vec<(CellState, usize)> {
80 let (x, y) = xy;
81 let neighbor_states = self.input_cells.get_data().iter().map(|rule| {
83 let x = x as i64 + rule.0 as i64;
84 let y = y as i64 + rule.1 as i64;
85 if (x < 0) | (y < 0) | (x > self.width as i64) | (y > self.height as i64) {
86 CellState::OOB
87 } else {
88 let coords = (x as u64, y as u64);
89 self.get_cell_state(coords)
90 }
91 }).collect::<Vec<_>>();
92
93 let mut output_vector = Vec::new();
95 use self::cell::CellState::{Dead, Live};
96 for state in vec![Dead, Live].iter() {
97 let num = neighbor_states.iter().filter(|x| x == &state).count();
98 output_vector.push( (state.clone(), num) );
99 }
100
101 output_vector
102 }
103
104 fn process_cells(&mut self) -> Vec<CellState> {
106
107 let mut neighbor_states = Vec::new();
108 for cell in self.grid.iter() {
109 neighbor_states.push(self.get_neighbor_states(cell.get_xy()));
110 }
111 let mut processed = Vec::new();
112 for (index, cell) in self.grid.iter().enumerate() {
113 if let Some(nb_states) = neighbor_states.get(index) {
114 processed.push(
115 self.rules.compute(cell.get_state().clone(), nb_states.clone())
116 );
117 }
118 }
119
120 processed
121 }
122
123 fn apply_state_changes(&mut self, new_state: Vec<CellState>) -> StepResult {
125 for (index, new) in new_state.into_iter().enumerate() {
126 self.set_cell_state(index, new);
127 }
128 StepResult {
129 steps: 10,
130 updated_cells: 100,
131 }
132 }
133
134 pub fn step(&mut self) -> Result<StepResult, StepError> {
135 self.time = self.time + 1;
136 let changes = self.process_cells();
138
139 let sr = self.apply_state_changes(changes);
141
142 Ok(sr)
143 }
144
145 pub fn return_grid(&self) -> &Vec<Cell> {
146 &self.grid
147 }
148
149 pub fn return_width(&self) -> usize {
150 self.width as usize
151 }
152}