1use crate::hex::Hex;
2use std::ops::{Add, Div, Mul, Neg, Sub};
3
4#[derive(Debug, Copy, Clone)]
5pub struct FractionalHex {
6 pub q: f32,
7 pub r: f32,
8 pub s: f32,
9}
10
11impl FractionalHex {
12 pub const fn new(q: f32, r: f32, s: f32) -> FractionalHex {
13 FractionalHex { q, r, s }
14 }
15 pub fn add(self, rhs: FractionalHex) -> FractionalHex {
16 FractionalHex {
17 q: self.q + rhs.q,
18 r: self.r + rhs.r,
19 s: self.s + rhs.s,
20 }
21 }
22 pub fn round(&self) -> Hex {
23 let FractionalHex { q, r, s } = self;
24
25 let q_diff = diff_from_round(q);
26 let r_diff = diff_from_round(r);
27 let s_diff = diff_from_round(s);
28
29 if q_diff > r_diff && q_diff > s_diff {
30 let hi_q = (-r.round() - s.round()) as i32;
31 let r = r.round() as i32;
32 let s = s.round() as i32;
33
34 return Hex { q: hi_q, r, s };
35 } else if r_diff > s_diff {
36 let hi_r = (-q.round() - s.round()) as i32;
37 let q = q.round() as i32;
38 let s = s.round() as i32;
39
40 return Hex { q, r: hi_r, s };
41 }
42
43 let hi_s = (-q.round() - r.round()) as i32;
44 let q = q.round() as i32;
45 let r = r.round() as i32;
46
47 Hex { q, r, s: hi_s }
48 }
49}
50
51fn diff_from_round(i: &f32) -> f32 {
52 (i - i.round()).abs()
53}
54
55impl PartialEq for FractionalHex {
56 fn eq(&self, rhs: &Self) -> bool {
57 self.q == rhs.q && self.r == rhs.r && self.s == rhs.s
58 }
59}
60
61impl Add for FractionalHex {
62 type Output = FractionalHex;
63
64 fn add(self, rhs: Self) -> Self::Output {
65 FractionalHex {
66 q: self.q + rhs.q,
67 r: self.r + rhs.r,
68 s: self.s + rhs.s,
69 }
70 }
71}
72
73impl Add<Hex> for FractionalHex {
74 type Output = FractionalHex;
75
76 fn add(self, rhs: Hex) -> Self::Output {
77 FractionalHex {
78 q: (rhs.q as f32) + self.q,
79 r: (rhs.r as f32) + self.r,
80 s: (rhs.s as f32) + self.s,
81 }
82 }
83}
84
85impl Sub for FractionalHex {
86 type Output = FractionalHex;
87
88 fn sub(self, rhs: Self) -> Self::Output {
89 FractionalHex {
90 q: self.q - rhs.q,
91 r: self.r - rhs.r,
92 s: self.s - rhs.s,
93 }
94 }
95}
96
97impl Sub<Hex> for FractionalHex {
98 type Output = FractionalHex;
99
100 fn sub(self, rhs: Hex) -> Self::Output {
101 FractionalHex {
102 q: self.q - (rhs.q as f32),
103 r: self.r - (rhs.r as f32),
104 s: self.s - (rhs.s as f32),
105 }
106 }
107}
108
109impl Mul<f32> for FractionalHex {
110 type Output = FractionalHex;
111
112 fn mul(self, rhs: f32) -> Self::Output {
113 let rhs = &rhs;
114
115 FractionalHex {
116 q: self.q * rhs,
117 r: self.r * rhs,
118 s: self.s * rhs,
119 }
120 }
121}
122
123impl Div<f32> for FractionalHex {
124 type Output = FractionalHex;
125
126 fn div(self, rhs: f32) -> Self::Output {
127 let rhs = &rhs;
128
129 let q = self.q / rhs;
130 let r = self.r / rhs;
131 let s = self.s / rhs;
132
133 FractionalHex { q, r, s }
134 }
135}
136
137impl Neg for FractionalHex {
138 type Output = FractionalHex;
139
140 fn neg(self) -> Self::Output {
141 FractionalHex::new(-self.q, -self.r, -self.s)
142 }
143}