1#![allow(unused)]
2#![deny(missing_docs)]
3
4mod ga;
9pub use ga::*;
11
12#[cfg(test)]
13mod tests {
14
15 use super::ga::*;
16
17 use rand::Rng;
18
19 fn random() -> f64 {
20 rand::thread_rng().gen()
21 }
22
23 fn radint(num: usize) -> usize {
24 ((num as f64) * random()) as usize
25 }
26
27 fn rex(start: usize, end: usize) -> usize {
28 start + radint(end - start)
29 }
30
31 const TARGET: [char; 20] = ['T', 'o', ' ', 'b', 'e', ',',
32 ' ', 'o', 'r', ' ', 'n', 'o', 't', ' ', 't', 'o', ' ', 'b', 'e', '.'];
33
34 use std::iter::once;
35
36 fn random_char() -> char {
37 (rex(32, 122) as u8) as char
38 }
39
40 struct Gene {
41 text: [char; 20]
42 }
43
44 impl Genome for Gene {
45 fn new() -> Self {
46 let mut text = [0u8 as char; 20];
47 for i in 0..20 {
48 text[i] = random_char();
49 }
50 Self { text }
51 }
52
53 fn fitness(&self) -> f64 {
54 2f64.powf((0..20).map(|i| ((self.text[i] == TARGET[i]) as usize) as f64).sum())
55 }
56
57 fn cross(&self, other: &Self) -> Self {
58 let mut text = [0u8 as char; 20];
59 for i in 0..20 {
60 text[i] = match radint(2) {
61 0 => self.text[i],
62 1 => other.text[i],
63 _ => random_char()
64 }
65 }
66
67 Self { text }
68 }
69
70 fn mutate(mut self) -> Self {
71 for i in 0..20 {
72 if random() < 0.01 {
73 self.text[i] = random_char();
74 }
75 }
76 self
77 }
78
79 fn display(&self) {
80 let display_text: String = self.text.iter().cloned().collect();
81 println!("{}", display_text);
82 }
83 }
84
85 #[test]
86 fn test_shakespear() {
87 let mut population: Population<Gene> = Population::new(100);
88 for i in 0..1000 {
89 population.live();
90 population.next_generation();
91 }
92 }
93}