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 ) ]
386416pub ( 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 ) ]
451443pub ( 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