@@ -10,7 +10,7 @@ use nom::Err::Error;
1010use nom:: { AsBytes , AsChar , Compare , IResult , Input , Parser } ;
1111use nom_parse_trait:: ParseFrom ;
1212use std:: fmt:: { Debug , Formatter , Write } ;
13- use std:: ops:: { Index , IndexMut , Range } ;
13+ use std:: ops:: { Add , Index , IndexMut , Range } ;
1414
1515#[ derive( Clone , Hash , PartialEq ) ]
1616pub struct Grid < T > {
@@ -470,6 +470,20 @@ impl<T> Grid<T> {
470470 . save_with_format ( filename, image:: ImageFormat :: Png )
471471 . expect ( "Expect saving to not be a problem" ) ;
472472 }
473+
474+ pub fn search_graph < ' a , FS , FH , S > (
475+ & ' a self ,
476+ goal : Location ,
477+ score_step : FS ,
478+ heuristic_score : FH ,
479+ ) -> GridGraph < ' a , T , FS , FH >
480+ where
481+ FS : Fn ( Location , & T , & T ) -> Option < S > ,
482+ S : Copy + Default + Eq + Add < S , Output = S > + Ord ,
483+ FH : Fn ( Vector < 2 , i32 > ) -> S ,
484+ {
485+ GridGraph :: < ' a , T , FS , FH > { grid : self , goal, score_step, heuristic_score }
486+ }
473487}
474488
475489impl < T : Copy + Into < char > > Debug for Grid < T > {
@@ -726,3 +740,41 @@ where
726740 #[ inline]
727741 fn size_hint ( & self ) -> ( usize , Option < usize > ) { self . iter . size_hint ( ) }
728742}
743+
744+ pub struct GridGraph < ' a , T , FS , FH > {
745+ grid : & ' a Grid < T > ,
746+ goal : Location ,
747+ score_step : FS ,
748+ heuristic_score : FH ,
749+ }
750+
751+ impl < ' a , T , S , FS , FH > crate :: search:: SearchGraph for GridGraph < ' a , T , FS , FH >
752+ where
753+ FS : Fn ( Location , & T , & T ) -> Option < S > ,
754+ S : Copy + Default + Eq + Add < S , Output = S > + Ord ,
755+ FH : Fn ( Vector < 2 , i32 > ) -> S ,
756+ {
757+ type Node = Location ;
758+ type Score = S ;
759+
760+ fn neighbours ( & self , current_loc : Location ) -> impl Iterator < Item = ( Location , S ) > {
761+ let current_val = self . grid . get ( current_loc) . unwrap ( ) ;
762+ self . grid . direct_neighbours ( current_loc) . flat_map ( move |( dir, val) | {
763+ let next_loc = current_loc + dir;
764+ ( self . score_step ) ( next_loc, current_val, val) . map ( |score| ( next_loc, score) )
765+ } )
766+ }
767+
768+ fn expected_state_size ( & self ) -> usize { ( self . grid . width ( ) * self . grid . height ( ) ) as usize }
769+ }
770+
771+ impl < ' a , T , S , FS , FH > crate :: search:: SearchGraphWithGoal for GridGraph < ' a , T , FS , FH >
772+ where
773+ FS : Fn ( Location , & T , & T ) -> Option < S > ,
774+ S : Copy + Default + Eq + Add < S , Output = S > + Ord ,
775+ FH : Fn ( Vector < 2 , i32 > ) -> S ,
776+ {
777+ fn is_goal ( & self , curr : Location ) -> bool { curr == self . goal }
778+
779+ fn heuristic ( & self , curr : Location ) -> Self :: Score { ( self . heuristic_score ) ( self . goal - curr) }
780+ }
0 commit comments