cell_automata_1d/
cellauto.rs1use crate::rule::*;
2
3pub struct CellAutomata1D {
4 state: Vec<bool>,
5 rule: Rule
6}
7
8impl CellAutomata1D {
9 pub fn new(init_state: &str, rule_num: u8) -> Self {
10 CellAutomata1D {
11 state: Self::str_state_to_vec(init_state),
12 rule: Rule::new(rule_num)
13 }
14 }
15
16 pub fn with_rule(rule_num: u8) -> Self {
17 CellAutomata1D {
18 state: Vec::new(),
19 rule: Rule::new(rule_num)
20 }
21 }
22
23 pub fn set_state(&mut self, state: &str) {
24 self.state = Self::str_state_to_vec(state);
25 }
26
27 pub fn set_rule(&mut self, number: u8) {
28 self.rule = Rule::new(number);
29 }
30
31 pub fn next(&mut self) {
32 let mut next_state: Vec<bool> = Vec::with_capacity(self.state.len());
33 next_state.resize(self.state.len(), false);
34 for i in 0..self.state.len() {
35 let triad = self.triad_for(i);
36 next_state[i] = self.rule.result_of(triad);
37 }
38 self.state = next_state;
39 }
40
41 pub fn string_state(&self) -> String {
42 let mut state_str = String::with_capacity(self.state.len());
43 for cell in self.state.iter() {
44 state_str.push(if *cell {'#'} else {' '});
45 }
46 state_str
47 }
48
49 pub fn get_state(&self) -> Vec<bool> {
50 self.state.clone()
51 }
52
53 fn triad_for(&self, ind: usize) -> [bool; 3] {
54 let ind = ind as isize;
55 let mut triad = [false; 3];
56 let mut bit_ind = 0;
57 for i in ind-1..=ind+1 {
58 triad[bit_ind] = self.cycle_at(i);
59 bit_ind += 1;
60 }
61 triad
62 }
63
64 fn cycle_at(&self, ind: isize) -> bool {
65 if ind >= self.state.len() as isize {
66 self.state[0]
67 } else if ind < 0 {
68 *self.state.last().unwrap()
69 } else {
70 self.state[ind as usize]
71 }
72 }
73
74 fn str_state_to_vec(str: &str) -> Vec<bool> {
75 let mut vec: Vec<bool> = Vec::with_capacity(str.len());
76 for ch in str.chars() {
77 vec.push(if ch != '0' {true} else {false});
78 }
79 vec
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use crate::cellauto::*;
86
87 #[test]
88 fn automata_work() {
89 let mut automata = CellAutomata1D::new("00001001", 2);
90 automata.next();
91 assert_eq!(automata.string_state(), " # # ");
92 automata.next();
93 assert_eq!(automata.string_state(), " # # ");
94 }
95
96 #[test]
97 fn setting_state_works() {
98 let mut automata = CellAutomata1D::new("00001001", 2);
99 automata.next();
100 assert_eq!(automata.string_state(), " # # ");
101 automata.set_state("10000100");
102 automata.next();
103 assert_eq!(automata.string_state(), " # #");
104
105 let mut automata = CellAutomata1D::with_rule(18);
106 automata.set_state("00010000");
107 automata.next();
108 assert_eq!(automata.string_state(), " # # ");
109 }
110
111 #[test]
112 fn printing_state() {
113 let automata = CellAutomata1D::new("11100101", 0b00000100);
114 assert_eq!(automata.string_state(), "### # #");
115 }
116
117 #[test]
118 fn triad_creating() {
119 let automata = CellAutomata1D::new("10000101", 0xff);
120 assert_eq!(automata.triad_for(0), [true, true, false]);
121 assert_eq!(automata.triad_for(7), [false, true, true]);
122 assert_eq!(automata.triad_for(4), [false, false, true]);
123 }
124
125 #[test]
126 fn cycle_state_indexing() {
127 let automata = CellAutomata1D::new("00000101", 0xff);
128 assert_eq!(automata.cycle_at(-1), true);
129 assert_eq!(automata.cycle_at(8), false);
130 assert_eq!(automata.cycle_at(5), true);
131 assert_eq!(automata.cycle_at(4), false);
132 }
133
134 #[test]
135 fn reading_state_from_str() {
136 let readed = CellAutomata1D::str_state_to_vec("11100101");
137 assert_eq!(readed, vec![true, true, true, false, false, true, false, true]);
138 }
139}