ternary_spreadsheet/
cell.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
3pub enum TernaryValue {
4 Negative = -1,
5 Neutral = 0,
6 Positive = 1,
7}
8
9impl TernaryValue {
10 pub fn from_i8(v: i8) -> Self {
12 match v {
13 i8::MIN..=-1 => TernaryValue::Negative,
14 0 => TernaryValue::Neutral,
15 1..=i8::MAX => TernaryValue::Positive,
16 }
17 }
18
19 pub fn as_i8(self) -> i8 {
21 self as i8
22 }
23
24 pub fn flip(self) -> Self {
26 match self {
27 TernaryValue::Negative => TernaryValue::Positive,
28 TernaryValue::Neutral => TernaryValue::Neutral,
29 TernaryValue::Positive => TernaryValue::Negative,
30 }
31 }
32
33 pub fn all() -> [TernaryValue; 3] {
35 [TernaryValue::Negative, TernaryValue::Neutral, TernaryValue::Positive]
36 }
37
38 pub fn from_seed(seed: u32) -> Self {
40 match seed % 3 {
41 0 => TernaryValue::Negative,
42 1 => TernaryValue::Neutral,
43 _ => TernaryValue::Positive,
44 }
45 }
46}
47
48impl std::fmt::Display for TernaryValue {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 match self {
51 TernaryValue::Negative => write!(f, "-1"),
52 TernaryValue::Neutral => write!(f, "0"),
53 TernaryValue::Positive => write!(f, "+1"),
54 }
55 }
56}
57
58#[derive(Debug, Clone)]
60pub struct Cell {
61 pub value: TernaryValue,
62 pub fitness: f64,
63 pub history: Vec<TernaryValue>,
64 pub generation: u64,
65}
66
67impl Cell {
68 pub fn new(value: TernaryValue) -> Self {
70 Cell {
71 value,
72 fitness: 0.0,
73 history: vec![],
74 generation: 0,
75 }
76 }
77
78 pub fn neutral() -> Self {
80 Self::new(TernaryValue::Neutral)
81 }
82
83 pub fn set_value(&mut self, value: TernaryValue) {
85 self.history.push(self.value);
86 self.value = value;
87 self.generation += 1;
88 }
89
90 pub fn set_fitness(&mut self, fitness: f64) {
92 self.fitness = fitness;
93 }
94
95 pub fn compute_default_fitness(&self) -> f64 {
97 let base = self.value.as_i8() as f64;
98 let unique_count = {
99 let mut vals = self.history.clone();
100 vals.sort();
101 vals.dedup();
102 vals.len() as f64
103 };
104 base * (1.0 + unique_count * 0.1)
105 }
106
107 pub fn mutation_count(&self) -> usize {
109 self.history.len()
110 }
111
112 pub fn reset(&mut self) {
114 self.history.push(self.value);
115 self.value = TernaryValue::Neutral;
116 self.fitness = 0.0;
117 self.generation += 1;
118 }
119}
120
121impl Default for Cell {
122 fn default() -> Self {
123 Self::neutral()
124 }
125}