diff --git a/.gitignore b/.gitignore index 9106b2a..4b365f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.idea /.bundle/ /.yardoc /_yardoc/ diff --git a/lib/cyberarm_engine/pathfinding/graph.rb b/lib/cyberarm_engine/pathfinding/graph.rb new file mode 100644 index 0000000..be215e0 --- /dev/null +++ b/lib/cyberarm_engine/pathfinding/graph.rb @@ -0,0 +1,15 @@ +module CyberarmEngine + module Pathfinding + class Graph + Location = Data.define(:x, :y, :z, :cost) + + def initialize(edges: {}) + @edges = edges + end + + def neighbors(location) + @edges[location] + end + end + end +end diff --git a/lib/cyberarm_engine/pathfinding/graph_search.rb b/lib/cyberarm_engine/pathfinding/graph_search.rb new file mode 100644 index 0000000..3913fec --- /dev/null +++ b/lib/cyberarm_engine/pathfinding/graph_search.rb @@ -0,0 +1,6 @@ +module CyberarmEngine + module Pathfinding + class GraphSearch + end + end +end diff --git a/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb b/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb new file mode 100644 index 0000000..1afe026 --- /dev/null +++ b/lib/cyberarm_engine/pathfinding/graph_searches/astar_search.rb @@ -0,0 +1,6 @@ +module CyberarmEngine + module Pathfinding + class AStarSearch < GraphSearch + end + end +end diff --git a/lib/cyberarm_engine/pathfinding/graph_searches/bread_first_search.rb b/lib/cyberarm_engine/pathfinding/graph_searches/bread_first_search.rb new file mode 100644 index 0000000..7679727 --- /dev/null +++ b/lib/cyberarm_engine/pathfinding/graph_searches/bread_first_search.rb @@ -0,0 +1,27 @@ +module CyberarmEngine + module Pathfinding + class BreadthFirstSearch < GraphSearch + def search(graph:, start:, goal: nil) + frontier = [] + came_from = {} + + frontier.put(start) + came_from[start] = start + + while(current = frontier.shift) + # early exit if we reach our goal + break if current == goal + + graph.neighbors(current).each do |neighbor| + next if came_from[neighbor] + + frontier.put(neighbor) + came_from[neighbor] = current + end + end + + came_from + end + end + end +end diff --git a/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb b/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb new file mode 100644 index 0000000..3b75fc8 --- /dev/null +++ b/lib/cyberarm_engine/pathfinding/graph_searches/dijkstra_search.rb @@ -0,0 +1,6 @@ +module CyberarmEngine + module Pathfinding + class DijkstraSearch < GraphSearch + end + end +end diff --git a/lib/cyberarm_engine/pathfinding/graphs/grid.rb b/lib/cyberarm_engine/pathfinding/graphs/grid.rb new file mode 100644 index 0000000..b6d8d08 --- /dev/null +++ b/lib/cyberarm_engine/pathfinding/graphs/grid.rb @@ -0,0 +1,33 @@ +module CyberarmEngine + module Pathfinding + class Grid < Graph + Cell = Data.define(:location, :blocker, :cost) + + # nodes: a 2d array of nodes to convert to list of edges + def self.edges_from_world_grid(nodes:) + edges = {} + + nodes.each_index do |y, y_index| + y.each_with_index do |x_index| + node = nodes[y_index][x_index] + next unless node + + left = nodes[y_index]&.[x_index - 1] + right = nodes[y_index]&.[x_index + 1] + top = nodes[y_index - 1]&.[x_index] + bottom = nodes[y_index + 1]&.[x_index] + + location = Location.new(x_index, y_index, 0, 0) + edges[location] = [] + edges[location].push(Location.new(x_index - 1, y_index, 0, 0)) if left + edges[location].push(Location.new(x_index + 1, y_index, 0, 0)) if right + edges[location].push(Location.new(x_index, y_index - 1, 0, 0)) if top + edges[location].push(Location.new(x_index, y_index + 1, 0, 0)) if bottom + end + end + + new(edges: edges) + end + end + end +end