a-star 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/bin/a-star +15 -0
 - data/lib/A_Star.rb +214 -0
 - metadata +46 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: eabf290e90562cb865fd597d9c7a446ccf6a10ad
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 61f5081fdde910f354b26d53dfc0fa7b0479810d
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 6542dba427725e0a7f01d8c1ff7f7da16a31d38c340ae6ba3fc767714bbc8f8c8f1a76aa744f42e233c906f1853b482da9dd0a65fde093cb164c403dbc8cc75e
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: eb8e7625a42a6e7a9e0ce58dd8378d0c19b89d25b59b0edec2180772c1104aff77388853ebe89f427d1529480380baa8ec61e4cc8c67cb308107eaf52720ab6c
         
     | 
    
        data/bin/a-star
    ADDED
    
    | 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'A_Star'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            image = nil
         
     | 
| 
      
 5 
     | 
    
         
            +
            begin
         
     | 
| 
      
 6 
     | 
    
         
            +
              image = ChunkyPNG::Image.from_file(ARGV[ARGV.length - 1])
         
     | 
| 
      
 7 
     | 
    
         
            +
            rescue
         
     | 
| 
      
 8 
     | 
    
         
            +
              puts "Please supply correct commandline arguments.\nNo image given or wrong image format, PNG only!"
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            unless image.nil?
         
     | 
| 
      
 12 
     | 
    
         
            +
              loc = FromTo.new image
         
     | 
| 
      
 13 
     | 
    
         
            +
              init = AStar.new image, loc.findStart, loc.findEnd
         
     | 
| 
      
 14 
     | 
    
         
            +
              init.draw
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/A_Star.rb
    ADDED
    
    | 
         @@ -0,0 +1,214 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'chunky_png'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class FromTo
         
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize image
         
     | 
| 
      
 5 
     | 
    
         
            +
                @image = image
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def findEnd
         
     | 
| 
      
 9 
     | 
    
         
            +
                0.upto @image.dimension.width - 1 do |i|
         
     | 
| 
      
 10 
     | 
    
         
            +
                  red = ChunkyPNG::Color.r(@image[i, @image.dimension.height - 1])
         
     | 
| 
      
 11 
     | 
    
         
            +
                  green = ChunkyPNG::Color.g(@image[i, @image.dimension.height - 1])
         
     | 
| 
      
 12 
     | 
    
         
            +
                  blue = ChunkyPNG::Color.b(@image[i, @image.dimension.height - 1])
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  if red > 255/2 && green > 255/2 && blue > 255/2
         
     | 
| 
      
 15 
     | 
    
         
            +
                    return [i, @image.dimension.height - 1]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
                return Array.new
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              def findStart
         
     | 
| 
      
 22 
     | 
    
         
            +
                0.upto @image.dimension.width - 1 do |i|
         
     | 
| 
      
 23 
     | 
    
         
            +
                  red = ChunkyPNG::Color.r(@image[i, 0])
         
     | 
| 
      
 24 
     | 
    
         
            +
                  green = ChunkyPNG::Color.g(@image[i, 0])
         
     | 
| 
      
 25 
     | 
    
         
            +
                  blue = ChunkyPNG::Color.b(@image[i, 0])
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  if red > 255/2 && green > 255/2 && blue > 255/2
         
     | 
| 
      
 28 
     | 
    
         
            +
                    return [i, 0]
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
                return Array.new
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            def node x, y, index, cost, destCost, totalCost
         
     | 
| 
      
 36 
     | 
    
         
            +
              return [x, y, index, cost, destCost, totalCost]
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            class AStar
         
     | 
| 
      
 40 
     | 
    
         
            +
              def initialize maze, start, dest
         
     | 
| 
      
 41 
     | 
    
         
            +
                raise "Either start, end or both locations not found!" if start.empty? || dest.empty?
         
     | 
| 
      
 42 
     | 
    
         
            +
                @maze = maze
         
     | 
| 
      
 43 
     | 
    
         
            +
                @start = start
         
     | 
| 
      
 44 
     | 
    
         
            +
                @dest = dest
         
     | 
| 
      
 45 
     | 
    
         
            +
                @solvedMaze = @maze
         
     | 
| 
      
 46 
     | 
    
         
            +
                mazeName = ARGV[ARGV.length - 1]
         
     | 
| 
      
 47 
     | 
    
         
            +
                @mazeLabel = mazeName.split( /()\s|\./)[0]
         
     | 
| 
      
 48 
     | 
    
         
            +
                @mazeFileType = "." + mazeName.split(/\s|\./)[1]
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                @firstNode = node start[0], start[1], -1, -1, -1, -1 # [x, y, index, startCost, destcost, heuristic]
         
     | 
| 
      
 51 
     | 
    
         
            +
                @destNode  = node dest[0], dest[1],   -1, -1, -1, -1
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                @height       = maze.dimension.height
         
     | 
| 
      
 54 
     | 
    
         
            +
                @width        = maze.dimension.width
         
     | 
| 
      
 55 
     | 
    
         
            +
                @perimiter    = (2 * @width) + (2 * @height)
         
     | 
| 
      
 56 
     | 
    
         
            +
                @area = @width * @height
         
     | 
| 
      
 57 
     | 
    
         
            +
                @visited = []
         
     | 
| 
      
 58 
     | 
    
         
            +
                @unvisited  = []
         
     | 
| 
      
 59 
     | 
    
         
            +
                @visited << @firstNode
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              def solve
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                while not @visited.empty? do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  minIndex = 0
         
     | 
| 
      
 66 
     | 
    
         
            +
                  0.upto @visited.length - 1 do |i|
         
     | 
| 
      
 67 
     | 
    
         
            +
                    if @visited[i][5] < @visited[minIndex][5]
         
     | 
| 
      
 68 
     | 
    
         
            +
                      minIndex = i
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
                  chosenNode = minIndex
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  here = @visited[chosenNode]
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  if here[0] == @destNode[0] && here[1] == @destNode[1]
         
     | 
| 
      
 76 
     | 
    
         
            +
                    path = [@destNode]
         
     | 
| 
      
 77 
     | 
    
         
            +
                    puts "We're here! Final node at: (x: #{here[0]}, y: #{here[1]})"
         
     | 
| 
      
 78 
     | 
    
         
            +
                    while here[2] != -1 do
         
     | 
| 
      
 79 
     | 
    
         
            +
                      here = @unvisited[here[2]]
         
     | 
| 
      
 80 
     | 
    
         
            +
                      path.unshift here
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
                    puts "The entire path from #{@start} to #{@dest} is: \n#{path}"
         
     | 
| 
      
 83 
     | 
    
         
            +
                    path.each do |arr|
         
     | 
| 
      
 84 
     | 
    
         
            +
                      @solvedMaze[arr[0], arr[1]] = ChunkyPNG::Color.from_hex "#752bff"
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    return path
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  @visited.delete_at chosenNode
         
     | 
| 
      
 90 
     | 
    
         
            +
                  @unvisited << here
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  friendNodes = lookAround here
         
     | 
| 
      
 93 
     | 
    
         
            +
                  0.upto friendNodes.length - 1 do |j|
         
     | 
| 
      
 94 
     | 
    
         
            +
                    horizontalFriend = friendNodes[j][0]
         
     | 
| 
      
 95 
     | 
    
         
            +
                    verticalFriend   = friendNodes[j][1]
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                    if passable? horizontalFriend, verticalFriend || (horizontalFriend = @destNode[0] && verticalFriend == @destNode[1])
         
     | 
| 
      
 98 
     | 
    
         
            +
                      onUnvisited = false
         
     | 
| 
      
 99 
     | 
    
         
            +
                      0.upto @unvisited.length - 1 do |k|
         
     | 
| 
      
 100 
     | 
    
         
            +
                        unvisitedNode = @unvisited[k]
         
     | 
| 
      
 101 
     | 
    
         
            +
                        if horizontalFriend == unvisitedNode[0] && verticalFriend == unvisitedNode[1]
         
     | 
| 
      
 102 
     | 
    
         
            +
                          onUnvisited = true
         
     | 
| 
      
 103 
     | 
    
         
            +
                          break
         
     | 
| 
      
 104 
     | 
    
         
            +
                        end
         
     | 
| 
      
 105 
     | 
    
         
            +
                      end
         
     | 
| 
      
 106 
     | 
    
         
            +
                      next if onUnvisited
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                      onVisited = false
         
     | 
| 
      
 109 
     | 
    
         
            +
                      0.upto @visited.length - 1 do |k|
         
     | 
| 
      
 110 
     | 
    
         
            +
                        visitedNode = @visited[k]
         
     | 
| 
      
 111 
     | 
    
         
            +
                        if horizontalFriend == visitedNode[0] && verticalFriend == visitedNode[1]
         
     | 
| 
      
 112 
     | 
    
         
            +
                          onVisited = true
         
     | 
| 
      
 113 
     | 
    
         
            +
                          break
         
     | 
| 
      
 114 
     | 
    
         
            +
                        end
         
     | 
| 
      
 115 
     | 
    
         
            +
                      end
         
     | 
| 
      
 116 
     | 
    
         
            +
                      friendHeuristics = Array.new
         
     | 
| 
      
 117 
     | 
    
         
            +
                      for k in 0..friendNodes.length - 1 do
         
     | 
| 
      
 118 
     | 
    
         
            +
                        friendHeuristics << heuristic(friendNodes[k], @dest)
         
     | 
| 
      
 119 
     | 
    
         
            +
                      end
         
     | 
| 
      
 120 
     | 
    
         
            +
                      lowestHeuristic = friendHeuristics.min
         
     | 
| 
      
 121 
     | 
    
         
            +
                      if not onVisited && heuristic(friendNodes[j], @dest) == lowestHeuristic # If you're somwhere new and is fastest
         
     | 
| 
      
 122 
     | 
    
         
            +
                        newNode = node horizontalFriend, verticalFriend, @unvisited.length - 1, -1, -1, -1
         
     | 
| 
      
 123 
     | 
    
         
            +
                        newNode[3] = here[3] + cost(here, newNode)
         
     | 
| 
      
 124 
     | 
    
         
            +
                        newNode[4] = heuristic newNode, @destNode
         
     | 
| 
      
 125 
     | 
    
         
            +
                        newNode[5] = newNode[3] + newNode[4]
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                        @visited << newNode
         
     | 
| 
      
 128 
     | 
    
         
            +
                        #puts "!! New Node at\n(x: " + horizontalFriend.to_s + ", y: " + verticalFriend.to_s + ")"
         
     | 
| 
      
 129 
     | 
    
         
            +
                        #puts "Destination = " + @destNode[0].to_s + ", " + @destNode[1].to_s
         
     | 
| 
      
 130 
     | 
    
         
            +
                        # Uncoment below to see unvisited nodes!
         
     | 
| 
      
 131 
     | 
    
         
            +
                        #@solvedMaze[horizontalFriend, verticalFriend] = ChunkyPNG::Color.from_hex "#999"
         
     | 
| 
      
 132 
     | 
    
         
            +
                      end
         
     | 
| 
      
 133 
     | 
    
         
            +
                    end
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
                return []
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
              def heuristic here, destination
         
     | 
| 
      
 140 
     | 
    
         
            +
                return ( Math.sqrt( ((here[0] - destination[0]) ** 2) + ((here[1] - destination[1]) ** 2) ) ).floor
         
     | 
| 
      
 141 
     | 
    
         
            +
              end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
              def cost here, destination
         
     | 
| 
      
 144 
     | 
    
         
            +
                direction = direction here, destination
         
     | 
| 
      
 145 
     | 
    
         
            +
                if [2, 4, 6, 8].include? direction
         
     | 
| 
      
 146 
     | 
    
         
            +
                  return 10
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
                return 14
         
     | 
| 
      
 149 
     | 
    
         
            +
              end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              def passable? x, y
         
     | 
| 
      
 152 
     | 
    
         
            +
                if (x < 0 || y < 0) || (x > @width - 1 || y > @height - 1)
         
     | 
| 
      
 153 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 154 
     | 
    
         
            +
                end
         
     | 
| 
      
 155 
     | 
    
         
            +
                red = ChunkyPNG::Color.r(@maze[x, y])
         
     | 
| 
      
 156 
     | 
    
         
            +
                green = ChunkyPNG::Color.g(@maze[x, y])
         
     | 
| 
      
 157 
     | 
    
         
            +
                blue = ChunkyPNG::Color.b(@maze[x, y])
         
     | 
| 
      
 158 
     | 
    
         
            +
                if red > 255/2 && green > 255/2 && blue > 255/2
         
     | 
| 
      
 159 
     | 
    
         
            +
                  return true
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
                return false
         
     | 
| 
      
 162 
     | 
    
         
            +
              end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
              def direction here, destination
         
     | 
| 
      
 165 
     | 
    
         
            +
                direction = [ destination[1] - here[1], destination[0] - here[0] ]
         
     | 
| 
      
 166 
     | 
    
         
            +
                return case
         
     | 
| 
      
 167 
     | 
    
         
            +
                  when direction[0] > 0 && direction[1] == 0
         
     | 
| 
      
 168 
     | 
    
         
            +
                    2 # y-negative, down
         
     | 
| 
      
 169 
     | 
    
         
            +
                  when direction[1] < 0 && direction[0] == 0
         
     | 
| 
      
 170 
     | 
    
         
            +
                    4 # x-negative, left
         
     | 
| 
      
 171 
     | 
    
         
            +
                  when direction[0] < 0 && direction[1] == 0
         
     | 
| 
      
 172 
     | 
    
         
            +
                    8 # y-positive, up
         
     | 
| 
      
 173 
     | 
    
         
            +
                  when direction[1] > 0 && direction[0] == 0
         
     | 
| 
      
 174 
     | 
    
         
            +
                    6 # x-positive, right
         
     | 
| 
      
 175 
     | 
    
         
            +
                end
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              def lookAround here
         
     | 
| 
      
 179 
     | 
    
         
            +
                return [
         
     | 
| 
      
 180 
     | 
    
         
            +
                  [here[0], (here[1] + 1)], # y-positive, up
         
     | 
| 
      
 181 
     | 
    
         
            +
                  [here[0], (here[1] - 1)], # y-negative, down
         
     | 
| 
      
 182 
     | 
    
         
            +
                  [(here[0] + 1), here[1]], # x-positive, right
         
     | 
| 
      
 183 
     | 
    
         
            +
                  [(here[0] - 1), here[1]]  # x-negative, left
         
     | 
| 
      
 184 
     | 
    
         
            +
                ]
         
     | 
| 
      
 185 
     | 
    
         
            +
              end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
              def draw
         
     | 
| 
      
 188 
     | 
    
         
            +
                puts "Solving..."
         
     | 
| 
      
 189 
     | 
    
         
            +
                go = Time.new
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                path = solve # Here we go
         
     | 
| 
      
 192 
     | 
    
         
            +
                unless path.empty?
         
     | 
| 
      
 193 
     | 
    
         
            +
                  finish = Time.new
         
     | 
| 
      
 194 
     | 
    
         
            +
                  puts "\n\nTime taken to solve: " + (finish - go).to_s + " seconds!"
         
     | 
| 
      
 195 
     | 
    
         
            +
                  minutes = ((finish - go) / 60).round
         
     | 
| 
      
 196 
     | 
    
         
            +
                  if minutes > 0
         
     | 
| 
      
 197 
     | 
    
         
            +
                    if minutes > 1
         
     | 
| 
      
 198 
     | 
    
         
            +
                      puts "Circa " + minutes.to_s + " Minutes."
         
     | 
| 
      
 199 
     | 
    
         
            +
                    else
         
     | 
| 
      
 200 
     | 
    
         
            +
                      puts "Circa " + minutes.to_s + " Minute."
         
     | 
| 
      
 201 
     | 
    
         
            +
                    end
         
     | 
| 
      
 202 
     | 
    
         
            +
                  end
         
     | 
| 
      
 203 
     | 
    
         
            +
                else
         
     | 
| 
      
 204 
     | 
    
         
            +
                  puts "No solution found, solve function returned empty array for path!\nPlease make sure your maze is solvable!"
         
     | 
| 
      
 205 
     | 
    
         
            +
                end
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                startColour = "#ff3c5e"
         
     | 
| 
      
 208 
     | 
    
         
            +
                destColour  = "#68ff9f"
         
     | 
| 
      
 209 
     | 
    
         
            +
                @solvedMaze[@start[0], @start[1]] = ChunkyPNG::Color.from_hex startColour
         
     | 
| 
      
 210 
     | 
    
         
            +
                @solvedMaze[@dest[0], @dest[1]] = ChunkyPNG::Color.from_hex destColour
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                @solvedMaze.save(@mazeLabel + "-solved" + @mazeFileType)
         
     | 
| 
      
 213 
     | 
    
         
            +
              end
         
     | 
| 
      
 214 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: a-star
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: '0.1'
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Demonstrandum
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2017-04-19 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 13 
     | 
    
         
            +
            description: A* Search Algorithm for PNG images
         
     | 
| 
      
 14 
     | 
    
         
            +
            email: knutsen@jetspace.co
         
     | 
| 
      
 15 
     | 
    
         
            +
            executables:
         
     | 
| 
      
 16 
     | 
    
         
            +
            - a-star
         
     | 
| 
      
 17 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 18 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 19 
     | 
    
         
            +
            files:
         
     | 
| 
      
 20 
     | 
    
         
            +
            - bin/a-star
         
     | 
| 
      
 21 
     | 
    
         
            +
            - lib/A_Star.rb
         
     | 
| 
      
 22 
     | 
    
         
            +
            homepage: https://github.com/Demonstrandum/A-Star
         
     | 
| 
      
 23 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 24 
     | 
    
         
            +
            - GPL-3.0
         
     | 
| 
      
 25 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 26 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 27 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 28 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 29 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 30 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 31 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 32 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 33 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 34 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 35 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 36 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 37 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 38 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 39 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 40 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 41 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 42 
     | 
    
         
            +
            rubygems_version: 2.6.11
         
     | 
| 
      
 43 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 44 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 45 
     | 
    
         
            +
            summary: A* Path finding
         
     | 
| 
      
 46 
     | 
    
         
            +
            test_files: []
         
     |