| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'elm/battlemap/src/Battlemap/Navigator/Path.elm')
| -rw-r--r-- | elm/battlemap/src/Battlemap/Navigator/Path.elm | 170 | 
1 files changed, 170 insertions, 0 deletions
| diff --git a/elm/battlemap/src/Battlemap/Navigator/Path.elm b/elm/battlemap/src/Battlemap/Navigator/Path.elm new file mode 100644 index 0000000..5ce2d4c --- /dev/null +++ b/elm/battlemap/src/Battlemap/Navigator/Path.elm @@ -0,0 +1,170 @@ +module Battlemap.Navigator.Path exposing +   ( +      Type, +      new, +      get_current_location, +      get_remaining_points, +      follow_directions +   ) + +import Set + +import Battlemap.Direction +import Battlemap.Location +import Battlemap.Tile + +-------------------------------------------------------------------------------- +-- TYPES ----------------------------------------------------------------------- +-------------------------------------------------------------------------------- +type alias Type = +   { +      current_location : Battlemap.Location.Type, +      visited_locations : (Set.Set Battlemap.Location.Ref), +      previous_directions : (List Battlemap.Direction.Type), +      remaining_points : Int +   } + +-------------------------------------------------------------------------------- +-- LOCAL ----------------------------------------------------------------------- +-------------------------------------------------------------------------------- +has_not_been_to : ( +      Type -> +      Battlemap.Location.Type -> +      Bool +   ) +has_not_been_to path location = +   ( +      (path.current_location /= location) +      && +      (not +         (Set.member +            (Battlemap.Location.get_ref location) +            path.visited_locations +         ) +      ) +   ) + +move_to : ( +      Type -> +      Battlemap.Direction.Type -> +      Battlemap.Location.Type -> +      Int -> +      Type +   ) +move_to path dir next_loc cost = +   {path | +      current_location = next_loc, +      visited_locations = +         (Set.insert +            (Battlemap.Location.get_ref path.current_location) +            path.visited_locations +         ), +      previous_directions = (dir :: path.previous_directions), +      remaining_points = (path.remaining_points - cost) +   } + +battlemap_backtrack : ( +      Battlemap.Type -> +      Battlemap.Location.Type -> +      Battlemap.Type +   ) +battlemap_backtrack battlemap current_loc = +   (Battlemap.apply_to_tile_unsafe +      battlemap +      current_loc +      (Battlemap.Tile.set_direction +         Battlemap.Direction.None +      ) +   ) + +navigator_backtrack : ( +      Battlemap.Navigator.Type -> +      Battlemap.Location.Type -> +      (List Battlemap.Direction.Type) -> +      Battlemap.Navigator.Type +   ) +try_backtracking_to path location dir = +               case (Util.List.pop nav.previous_directions) of +                     (Just (head, tail)) -> +                        if (head == (Battlemap.Direction.opposite_of dir)) +                        then +                           (backtrack_to +                              nav +                              next_location +                              tail +                           ) +                           ) +                        else +                           (battlemap, nav) +                     Nothing -> (battlemap, nav) +               move_to path next_location +               if (can_move_to_new_tile path next_location) +               then +               else +   {nav | +      current_location = next_loc, +      visited_locations = +         (Set.remove +            (Battlemap.Location.get_ref next_loc) +            nav.visited_locations +         ), +      previous_directions = prev_dir_tail, +      remaining_points = (nav.remaining_points + 1) +   } + + +to : ( +      Type -> +      Battlemap.Direction.Type -> +      (Battlemap.Type, Battlemap.Navigator.Type) +   ) +to battlemap nav dir char_list = + +-------------------------------------------------------------------------------- +-- EXPORTED -------------------------------------------------------------------- +-------------------------------------------------------------------------------- + +new : Battlemap.Location.Type -> Int -> Type +new start points = +   { +      current_location = start, +      visited_locations = Set.empty, +      previous_directions = [], +      remaining_points = points +   } + +get_current_location : Type -> Battlemap.Location.Type +get_current_location path = path.current_location + +get_remaining_points : Type -> Int +get_remaining_points path = path.remaining_points + +follow_direction : ( +      (Battlemap.Location.Type -> Bool) -> +      (Maybe Type) -> +      Battlemap.Direction.Type -> +      (Maybe Type) +   ) +follow_direction can_cross cost_fun maybe_path dir = +   case maybe_path of +      (Just path) -> +         let +            next_location = +               (Battlemap.Location.neighbor +                  nav.current_location +                  dir +               ) +         in +            if (can_cross path next_location) +            then +               if (has_not_been_to path next_location) +               then +                  (Just (move_to path next_location dir)) +               else +                  (try_backtracking_to path next_location dir) +            else +               Nothing +            else +               (battlemap, nav) + +      Nothing -> Nothing | 


