1pub mod input_cells;
2use self::input_cells::InputCells;
3use world::CellState;
4use std::str::FromStr;
5use std::collections::HashMap;
6
7type RulesetType = HashMap<(CellState, CellState), Vec<(usize, CellState)>>;
8
9#[derive(Clone)]
10pub enum Rulesets {
11 Custom,
12 Conway,
13 ConwayEasy,
14 ConwayVeryEasy,
15 Decay,
16}
17#[derive(Clone)]
18pub struct Ruleset {
19 pub input_cells: InputCells,
20 pub rules: Rulesets,
21}
22impl FromStr for Rulesets {
23 type Err = ();
24 fn from_str(s: &str) -> Result<Rulesets, ()> {
25 match s {
26 "Conway" => Ok(Rulesets::Conway),
27 "ConwayEasy" => Ok(Rulesets::ConwayEasy),
28 "ConwayVeryEasy" => Ok(Rulesets::ConwayVeryEasy),
29 "Decay" => Ok(Rulesets::Decay),
30 _ => Err(()),
31 }
32 }
33}
34impl Rulesets {
35 pub fn get_data(&self) -> DSLRuleset {
36 use self::CellState::{Dead, Live};
37 match *self {
38 Rulesets::Custom => {
40 let mut ruleset = DSLRuleset::new();
41 ruleset.add_cases(Dead, Live, vec![(3, Live)]);
42 ruleset
43 },
44 Rulesets::Conway => {
45 let mut ruleset = DSLRuleset::new();
46 ruleset.add_cases(Dead, Live, vec![(3, Live)]);
47 ruleset.add_cases(Live, Live, vec![
48 (0, Dead), (1, Dead), (4, Dead), (5, Dead),
49 (6, Dead), (7, Dead), (8, Dead), (9, Dead),
50 ]);
51 ruleset
52 },
53 Rulesets::ConwayEasy => {
54 let mut ruleset = DSLRuleset::new();
55 ruleset.add_cases(Dead, Live, vec![(3, Live)]);
56 ruleset.add_cases(Live, Live, vec![
57 (0, Dead), (1, Dead), (2, Live), (3, Live),
58 (4, Dead), (5, Dead), (6, Dead), (7, Live), (8, Dead),
59 ]);
60 ruleset
61 },
62 Rulesets::ConwayVeryEasy => {
63 let mut ruleset = DSLRuleset::new();
64 ruleset.add_cases(Dead, Live, vec![
65 (3, Live), (4, Live),
66 ]);
67 ruleset.add_cases(Live, Live, vec![
68 (0, Dead), (1, Dead), (4, Dead), (5, Dead),
69 (6, Dead), (7, Live), (8, Dead), (9, Dead),
70 ]);
71 ruleset
72 },
73 Rulesets::Decay => {
74 let mut ruleset = DSLRuleset::new();
75 ruleset.add_cases(Dead, Live, vec![(3, Live), (4, Live)]);
76 ruleset.add_cases(Live, Live, vec![
77 (0, Dead), (1, Live), (2, Dead), (3, Dead),
78 (4, Live), (5, Dead), (6, Dead), (7, Dead), (8, Dead),
79 ]);
80 ruleset
81 },
82 }
83 }
84}
85pub struct DSLRuleset {
86 data: RulesetType,
87}
88impl DSLRuleset {
89 pub fn new() -> Self {
90 DSLRuleset {
91 data: HashMap::new(),
92 }
93 }
94 pub fn add_cases(&mut self,
95 identity_state: CellState,
96 for_state: CellState,
97 cases: Vec<(usize, CellState)>
98 ) {
99 let key = (identity_state, for_state);
100
101 self.data.insert(key, cases);
102 }
103 pub fn compute(&mut self,
104 identity_state: CellState,
105 input_states: Vec<(CellState, usize)>
106 ) -> CellState {
107
108 let mut return_state = identity_state.clone();
109
110 let mut key = (identity_state, CellState::Uninitialized);
111 for &(ref state, ref amt) in input_states.iter() {
113 key.1 = state.clone();
115
116 match self.data.get(&key) {
117 Some(vec) => {
118 for &(ref trigger_amt, ref result_state) in vec {
119 if trigger_amt == amt {
120 return_state = result_state.clone();
121 }
122 }
123 },
124 None => (),
125 }
126 }
127
128 return_state
129 }
130}