Skip to content

Commit 5bd83f3

Browse files
committed
Restored most functionality
1 parent 8321ee3 commit 5bd83f3

File tree

4 files changed

+356
-364
lines changed

4 files changed

+356
-364
lines changed

src/graph.rs

Lines changed: 92 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
use std::slice::Iter;
1+
use crate::utils::is_point_in_circle;
22

3-
use crate::utils;
4-
5-
// TODO: add iterator over points
6-
// TODO: add iterator bfs
7-
// TODO: add iterator dfs
83
// TODO: consider using a Vec<u8> to store the points
94
/// ### Dijkstra Graph
105
///
@@ -15,7 +10,7 @@ pub(crate) struct DijkstraGraph
1510
///
1611
/// Since we only allow 100 nodes and we identify them based on their id we can use the properties
1712
/// of an array to our advantage.
18-
graph: [Option<DijkstraNode>; 100],
13+
points: [Option<DijkstraNode>; 100],
1914

2015
start: Option<usize>,
2116
end: Option<usize>
@@ -27,7 +22,7 @@ impl Default for DijkstraGraph
2722
{
2823
return DijkstraGraph
2924
{
30-
graph:
25+
points:
3126
[
3227
None, None, None, None, None, None, None, None, None, None,
3328
None, None, None, None, None, None, None, None, None, None,
@@ -53,43 +48,62 @@ impl DijkstraGraph
5348

5449
pub fn clear(&mut self)
5550
{
56-
for mut node in self.graph.iter_mut()
57-
{ node = &mut None; }
51+
self.points = self.points.iter()
52+
.map(|_| None)
53+
.collect::<Vec<_>>()
54+
.try_into()
55+
.unwrap();
56+
5857
self.start = None;
5958
self.end = None;
6059
}
6160

6261
pub fn clear_path(&mut self)
6362
{
64-
for mut node in self.graph.iter_mut()
65-
{
66-
if let Some(node) = node
67-
{ node.parent = None; }
68-
}
63+
self.points = self.points.iter()
64+
.map(|point_option|
65+
{
66+
if point_option.is_some()
67+
{
68+
let mut point = point_option.clone().unwrap();
69+
point.parent = None;
70+
return Some(point);
71+
}
72+
else
73+
{
74+
return None;
75+
}
76+
})
77+
.collect::<Vec<_>>()
78+
.try_into()
79+
.unwrap();
80+
81+
self.start = None;
82+
self.end = None;
6983
}
7084

7185
/// Returns the amount of nodes in the graph
7286
pub fn size(&self) -> usize
7387
{
7488
let mut size = 0;
75-
self.graph.iter().for_each(|node| { if node.is_some() { size += 1; } });
89+
self.points.iter().for_each(|node| { if node.is_some() { size += 1; } });
7690
return size;
7791
}
7892

7993
pub fn add_point(&mut self, id: usize, x: f32, y: f32)
8094
{
8195
if id > 100 { return; }
82-
if self.graph[id].is_none() { self.graph[id] = Some(DijkstraNode::new(x, y)); }
96+
if self.points[id].is_none() { self.points[id] = Some(DijkstraNode::new(x, y)); }
8397
}
8498

8599
/// Inserts a node at the first missing instance of the array
86100
pub fn append_point(&mut self, x: f32, y: f32)
87101
{
88-
for (index, node_option) in self.graph.iter().enumerate()
102+
for (index, node_option) in self.points.iter().enumerate()
89103
{
90104
if node_option.is_none()
91105
{
92-
self.graph[index] = Some(DijkstraNode::new(x, y));
106+
self.points[index] = Some(DijkstraNode::new(x, y));
93107
return;
94108
}
95109
}
@@ -98,39 +112,49 @@ impl DijkstraGraph
98112
pub fn remove_point(&mut self, id: usize)
99113
{
100114
if id > 100 { return; }
101-
self.graph[id] = None;
115+
self.points[id] = None;
102116
}
103117

104118
/// Adds a line; if it already exists, the length gets updated
105119
pub fn add_line(&mut self, from: usize, to: usize, distance: u16)
106120
{
107121
if from > 100 || to > 100 { return; }
108122

109-
if let Some(node) = &mut self.graph[from]
110-
{ node.edges.push(Edge { destination: to, distance }); }
123+
let Some(point) = self.points[from].as_mut() else { return; };
124+
125+
// Avoids duplicate edges
126+
for edge in point.edges.iter_mut()
127+
{
128+
if edge.destination == to
129+
{
130+
edge.distance = distance;
131+
return;
132+
}
133+
}
134+
135+
point.edges.push(Edge { destination: to, distance });
111136
}
112137

113138
pub fn remove_line(&mut self, from: usize, to: usize)
114139
{
115140
if from > 100 || to > 100 { return; }
116141

117-
if let Some(node) = &mut self.graph[from]
118-
{
119-
if node.edges.get(to).is_some()
120-
{ node.edges.remove(to); }
121-
}
142+
let Some(from_point) = self.points[from].as_mut() else { return; };
143+
from_point.edges.remove(to);
122144
}
123145

124146
pub fn get(&self, id: usize) -> &Option<DijkstraNode>
125-
{ return &self.graph[id]; }
147+
{ return &self.points[id]; }
148+
149+
pub fn get_mut(&mut self, id: usize) -> &mut Option<DijkstraNode>
150+
{ return &mut self.points[id]; }
126151

127152
pub fn start(&self) -> Option<usize>
128153
{ return self.start; }
129154

130155
pub fn set_start(&mut self, start: usize)
131156
{
132157
if start > 100 { return; }
133-
134158
self.start = Some(start);
135159
}
136160

@@ -143,7 +167,6 @@ impl DijkstraGraph
143167
pub fn set_end(&mut self, end: usize)
144168
{
145169
if end > 100 { return; }
146-
147170
self.end = Some(end);
148171
}
149172

@@ -166,12 +189,12 @@ impl DijkstraGraph
166189
let mut current_node = self.start.unwrap();
167190
let mut path = vec![current_node];
168191

169-
for _ in 0..self.graph.len()
192+
for _ in 0..self.points.len()
170193
{
171-
if self.graph[current_node].is_none() { return None; }
172-
if self.graph[current_node].as_ref().unwrap().parent.is_none() { return None; }
194+
if self.points[current_node].is_none() { return None; }
195+
if self.points[current_node].as_ref().unwrap().parent.is_none() { return None; }
173196

174-
current_node = self.graph[current_node].as_ref().unwrap().parent.unwrap();
197+
current_node = self.points[current_node].as_ref().unwrap().parent.unwrap();
175198

176199
path.push(current_node);
177200

@@ -182,39 +205,46 @@ impl DijkstraGraph
182205
}
183206

184207
pub fn points(&self) -> &[Option<DijkstraNode>; 100]
185-
{ return &self.graph; }
208+
{ return &self.points; }
186209

187210
pub fn lines(&self) -> Vec<(usize, &DijkstraNode, u16, usize, &DijkstraNode)>
188211
{
189-
let mut lines_iter = vec![];
212+
let mut lines = vec![];
190213

191-
for (from_id, point_option) in self.graph.iter().enumerate()
192-
{
193-
let Some(from_point) = point_option else { continue; };
194-
195-
for edge in &from_point.edges
214+
self.points.iter().enumerate()
215+
.filter(|(_, option)| option.is_some())
216+
.map(|(from_id, option)| (from_id, option.as_ref().unwrap()))
217+
.for_each(|(from_id, from_point)|
196218
{
197-
let Some(Some(to_point)) = self.graph.get(edge.destination) else { continue; };
219+
// It would take 2× as many lines of code to implement this in a functional style
220+
from_point.edges.iter()
221+
.for_each(|edge|
222+
{
223+
let Some(Some(to_point)) = self.points.get(edge.destination) else { return; };
198224

199-
lines_iter.push((from_id, from_point, edge.distance, edge.destination, to_point));
200-
}
201-
}
225+
lines.push((from_id, from_point, edge.distance, edge.destination, to_point));
226+
});
227+
});
202228

203-
return lines_iter;
229+
return lines;
204230
}
205231

206232
pub fn find_hovered_point(&mut self, mouse_x: f32, mouse_y: f32, radius: f32) -> Option<usize>
207233
{
208-
for (index, node_option) in self.graph.iter().enumerate()
209-
{
210-
if let Some(node) = node_option
234+
let mut point_id = None;
235+
236+
self.points.iter().enumerate()
237+
.filter(|(_, option)| option.is_some())
238+
.map(|(index, option)| (index, option.as_ref().unwrap()))
239+
.for_each(|(index, point)|
211240
{
212-
if utils::is_point_in_circle(mouse_x, mouse_y, node.position.x, node.position.y, radius)
213-
{ return Some(index); }
214-
}
215-
}
241+
if is_point_in_circle(mouse_x, mouse_y, point.x, point.y, radius)
242+
{
243+
point_id = Some(index);
244+
}
245+
});
216246

217-
return None;
247+
return point_id;
218248
}
219249

220250
// !dbg
@@ -228,14 +258,14 @@ impl DijkstraGraph
228258
pub fn print_graph_data(&self)
229259
{
230260
println!("Points:");
231-
self.graph.iter().enumerate().for_each(|(index, node_option)|
261+
self.points.iter().enumerate().for_each(|(index, node_option)|
232262
{
233263
if node_option.is_some()
234264
{ print!("{} ", index); }
235265
});
236266

237267
println!("Lines:");
238-
self.graph.iter().enumerate().for_each(|(index, node_option)|
268+
self.points.iter().enumerate().for_each(|(index, node_option)|
239269
{
240270
if let Some(node) = node_option
241271
{
@@ -382,10 +412,11 @@ impl DijkstraGraph
382412
}
383413
}
384414

385-
#[derive(Clone)]
415+
#[derive(Clone, Debug)]
386416
pub(crate) struct DijkstraNode
387417
{
388-
pub position: Position,
418+
pub x: f32,
419+
pub y: f32,
389420
parent: Option<usize>,
390421
distance: Option<u16>,
391422
visited: bool,
@@ -398,74 +429,23 @@ impl DijkstraNode
398429
{
399430
DijkstraNode
400431
{
401-
position: Position { x, y },
432+
x,
433+
y,
402434
parent: None,
403435
distance: None,
404436
visited: false,
405437
edges: vec![],
406438
}
407439
}
408-
409-
pub fn position(&self) -> Position
410-
{ return self.position; }
411-
412-
pub fn parent(&self) -> Option<usize>
413-
{ return self.parent; }
414-
415-
pub fn set_parent(&mut self, parent: Option<usize>)
416-
{ self.parent = parent; }
417-
418-
pub fn distance(&self) -> Option<u16>
419-
{ return self.distance; }
420-
421-
pub fn set_distance(&mut self, distance: Option<u16>)
422-
{ self.distance = distance; }
423-
424-
pub fn visited(&self) -> bool
425-
{ return self.visited; }
426-
427-
pub fn set_visited(&mut self, visited: bool)
428-
{ self.visited = visited; }
429-
430-
pub fn edges(&self) -> &Vec<Edge>
431-
{ return &self.edges; }
432-
}
433-
434-
#[derive(Clone, Copy)]
435-
pub(crate) struct Position
436-
{
437-
pub x: f32,
438-
pub y: f32,
439440
}
440441

441-
impl Position
442-
{
443-
pub fn get(&self) -> (f32, f32)
444-
{ return (self.x, self.y); }
445-
446-
pub fn set(&mut self, x: f32, y: f32)
447-
{ self.x = x; self.y = y; }
448-
}
449-
450-
#[derive(Clone, Copy)]
442+
#[derive(Clone, Copy, Debug)]
451443
pub(crate) struct Edge
452444
{
453445
destination: usize,
454446
distance: u16,
455447
}
456448

457-
impl Edge
458-
{
459-
pub fn destination(&self) -> usize
460-
{ return self.destination; }
461-
462-
pub fn distance(&self) -> u16
463-
{ return self.distance; }
464-
465-
pub fn set_distance(&mut self, distance: u16)
466-
{ self.distance = distance; }
467-
}
468-
469449
// Tests
470450
#[path = "./tests/graph_tests.rs"]
471451
#[cfg(test)]

0 commit comments

Comments
 (0)