astrid 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/astrid.gemspec +23 -0
- data/lib/astrid/finders/a_star.rb +195 -0
- data/lib/astrid/heuristics/manhattan.rb +17 -0
- data/lib/astrid/version.rb +3 -0
- data/lib/astrid.rb +7 -0
- data/spec/astrid/finders/a_star_spec.rb +230 -0
- data/spec/spec_helper.rb +4 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5805f0aabcdedf0d3f848c806e3dcd84c11108ec
|
4
|
+
data.tar.gz: 8122dbbd6d0a2f111154e65f75eb36a5cd72eaca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 72ec33b083718e395523d2dc0a8c9e7268d24d05f1c27ffc5c845f4980e7d689226cf09a75b5f107d55b10d292fa24bda70640fd8468170ebb6366941fc89fcf
|
7
|
+
data.tar.gz: 1e17a34f968e762bace8f055800f443a209a452204bd4ffe69c7ebada0677c8a8b53643e999ffdddc9ad2d137307885970dbd00c3a33d95f484686312ece9c4d
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 JHawk
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Astrid
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'astrid'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install astrid
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( https://github.com/[my-github-username]/astrid/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/astrid.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'astrid/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "astrid"
|
8
|
+
spec.version = Astrid::VERSION
|
9
|
+
spec.authors = ["JHawk"]
|
10
|
+
spec.email = ["josh.r.hawk@gmail.com"]
|
11
|
+
spec.summary = %q{A Star in ruby.}
|
12
|
+
spec.description = %q{A Star in ruby.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'astrid/heuristics/manhattan'
|
2
|
+
|
3
|
+
module Pathfinder
|
4
|
+
module Finders
|
5
|
+
class AStar
|
6
|
+
|
7
|
+
attr_accessor :allow_diagonal, :current_grid, :current_path
|
8
|
+
|
9
|
+
def initialize(opts={})
|
10
|
+
@allow_diagonal = opts[:allow_diagonal] || false
|
11
|
+
@heuristic = opts[:heuristic] || Heuristics::Manhattan
|
12
|
+
# @diagonal_movement = opts[:diagonal_movement]
|
13
|
+
@weight = opts[:weight] || 1;
|
14
|
+
end
|
15
|
+
|
16
|
+
def sanitize(node)
|
17
|
+
node
|
18
|
+
end
|
19
|
+
|
20
|
+
# look at
|
21
|
+
# https://github.com/qiao/PathFinding.js/blob/master/src/finders/AStarFinder.js
|
22
|
+
# A*
|
23
|
+
# requires x & y
|
24
|
+
# node = g, f, h, x, y, opened, walkable, closed, parent
|
25
|
+
#
|
26
|
+
# extract a grid class
|
27
|
+
# clearly not optomized at all!
|
28
|
+
def find_path(start_node, end_node, grid)
|
29
|
+
start_node = sanitize(start_node)
|
30
|
+
end_node = sanitize(end_node)
|
31
|
+
if grid.nil?
|
32
|
+
[start_node]
|
33
|
+
else
|
34
|
+
@current_grid = grid.clone
|
35
|
+
_max_x = grid[:max_x]
|
36
|
+
_max_y = grid[:max_y]
|
37
|
+
|
38
|
+
raise 'max_x & max_y required' unless _max_x && _max_y
|
39
|
+
|
40
|
+
_start_node = start_node.clone
|
41
|
+
_end_node = end_node.clone
|
42
|
+
|
43
|
+
heuristic = @heuristic.new(_end_node, @weight)
|
44
|
+
|
45
|
+
_start_node[:f] = 0 # sum of g and h
|
46
|
+
_start_node[:g] = 0 # steps to start node
|
47
|
+
_start_node[:h] = nil # steps to end node
|
48
|
+
_start_node[:opened] = true
|
49
|
+
|
50
|
+
# use heap or tree for better perf
|
51
|
+
open = []
|
52
|
+
open.push _start_node
|
53
|
+
|
54
|
+
while !open.empty? do
|
55
|
+
_current_node = open.pop
|
56
|
+
|
57
|
+
_current_node[:closed] = true
|
58
|
+
@current_grid[node_to_a(_current_node)] = _current_node
|
59
|
+
|
60
|
+
if node_to_a(_current_node) == node_to_a(_end_node)
|
61
|
+
return final_path(_current_node)
|
62
|
+
end
|
63
|
+
|
64
|
+
new_g = _current_node[:g] + 1
|
65
|
+
|
66
|
+
x = _current_node[:x]
|
67
|
+
y = _current_node[:y]
|
68
|
+
|
69
|
+
neighbors = []
|
70
|
+
|
71
|
+
neighbors << [x-1, y] if x > 0
|
72
|
+
neighbors << [x, y-1] if y > 0
|
73
|
+
neighbors << [x+1, y] if x < _max_x-1
|
74
|
+
neighbors << [x, y+1] if y < _max_y-1
|
75
|
+
|
76
|
+
_neighbors = neighbors.map do |position|
|
77
|
+
node = @current_grid[position]
|
78
|
+
if node.nil? || node[:walkable]
|
79
|
+
node ||= {}
|
80
|
+
@current_grid[position] = node.merge({
|
81
|
+
x: position.first,
|
82
|
+
y: position[1],
|
83
|
+
closed: false,
|
84
|
+
opened: false
|
85
|
+
})
|
86
|
+
end
|
87
|
+
end.compact
|
88
|
+
|
89
|
+
_neighbors.each do |neighbor|
|
90
|
+
if (!neighbor[:opened] || new_g < neighbor[:g])
|
91
|
+
neighbor[:g] = new_g
|
92
|
+
neighbor[:h] ||= heuristic.h(neighbor)
|
93
|
+
neighbor[:f] = neighbor[:g] + neighbor[:h]
|
94
|
+
neighbor[:parent] = node_to_a(_current_node)
|
95
|
+
|
96
|
+
if (!neighbor[:opened])
|
97
|
+
open.push neighbor
|
98
|
+
neighbor[:opened] = true
|
99
|
+
else
|
100
|
+
# ???
|
101
|
+
puts "got here some how!!!"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
open.sort_by! {|i| [-i[:f], -i[:h]]}
|
107
|
+
# grid_p
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def final_path(_end_node)
|
113
|
+
path = [_end_node]
|
114
|
+
_current_node = _end_node
|
115
|
+
|
116
|
+
while _current_node[:parent] do
|
117
|
+
parent_position = _current_node[:parent]
|
118
|
+
parent_node = @current_grid[parent_position]
|
119
|
+
|
120
|
+
path << parent_node
|
121
|
+
_current_node = parent_node
|
122
|
+
end
|
123
|
+
|
124
|
+
@current_path = path.reverse
|
125
|
+
end
|
126
|
+
|
127
|
+
def find_path_a(start_node, end_node, grid)
|
128
|
+
p = find_path(start_node, end_node, grid)
|
129
|
+
if p
|
130
|
+
p.map do |node|
|
131
|
+
node_to_a(node)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def find_path_a_with_time(start_node, end_node, grid)
|
137
|
+
result, time = find_path_a(start_node, end_node, grid)
|
138
|
+
end
|
139
|
+
|
140
|
+
def grid_from_s_map(str)
|
141
|
+
normalize = str.lines.reverse
|
142
|
+
|
143
|
+
max_x = normalize.map(&:length).max
|
144
|
+
max_y = normalize.length
|
145
|
+
|
146
|
+
y_idx = 0
|
147
|
+
normalize.inject({max_x: max_x, max_y: max_y}) do |grid, line|
|
148
|
+
line.each_char.each_with_index do |c, x_idx|
|
149
|
+
if c == '|' || c == '_'
|
150
|
+
grid.merge!(
|
151
|
+
[x_idx,y_idx] => { walkable: false}
|
152
|
+
)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
y_idx += 1
|
156
|
+
grid
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def visited_positions
|
161
|
+
@current_grid.select do |k,v|
|
162
|
+
k.is_a?(Array) && (v[:opened] || v[:closed])
|
163
|
+
end.map {|a| a[1]}
|
164
|
+
end
|
165
|
+
|
166
|
+
def grid_p
|
167
|
+
puts ""
|
168
|
+
puts "#"*80
|
169
|
+
s = ""
|
170
|
+
n = @current_grid[:max_y].to_s.size + 2
|
171
|
+
(-@current_grid[:max_y]..0).each do |y|
|
172
|
+
(0..@current_grid[:max_x]).each do |x|
|
173
|
+
node = @current_grid[[x,-y]]
|
174
|
+
if node
|
175
|
+
if node[:walkable].nil? || node[:walkable]
|
176
|
+
s << node[:f].to_s.rjust(n, " ")
|
177
|
+
else
|
178
|
+
s << "|".rjust(n, " ")
|
179
|
+
end
|
180
|
+
else
|
181
|
+
s << ''.rjust(n, '.')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
s << "\n"
|
185
|
+
end
|
186
|
+
puts s
|
187
|
+
end
|
188
|
+
|
189
|
+
def node_to_a(node)
|
190
|
+
[node[:x], node[:y]]
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pathfinder
|
2
|
+
module Heuristics
|
3
|
+
class Manhattan
|
4
|
+
|
5
|
+
def initialize(end_node, weight=1)
|
6
|
+
@end_x = end_node[:x]
|
7
|
+
@end_y = end_node[:y]
|
8
|
+
@weight = weight
|
9
|
+
end
|
10
|
+
|
11
|
+
def h(node, weight=@weight)
|
12
|
+
weight * ((node[:x] - @end_x).abs + (node[:y] - @end_y).abs)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
data/lib/astrid.rb
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'astrid/finders/a_star'
|
3
|
+
|
4
|
+
describe 'Pathfinder::Finders::AStar' do
|
5
|
+
|
6
|
+
|
7
|
+
let(:a_star) { Pathfinder::Finders::AStar.new }
|
8
|
+
|
9
|
+
describe "#grid" do
|
10
|
+
describe "#visited_positions" do
|
11
|
+
let(:closed) { {:x=>0, :y=>0, :f=>0, :g=>0, :h=>nil, :opened=>true, :closed=>true} }
|
12
|
+
let(:opened) { {:x=>0, :y=>0, :f=>0, :g=>0, :h=>nil, :opened=>true} }
|
13
|
+
let(:not_visited) { {:x=>0, :y=>0, :f=>0, :g=>0, :h=>nil} }
|
14
|
+
|
15
|
+
let(:grid) do
|
16
|
+
{
|
17
|
+
:max_x => 10,
|
18
|
+
:max_y => 10,
|
19
|
+
|
20
|
+
[0,0] => closed,
|
21
|
+
[0,1] => opened,
|
22
|
+
[0,2] => not_visited
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
before do
|
27
|
+
a_star.current_grid = grid
|
28
|
+
end
|
29
|
+
|
30
|
+
subject { a_star.visited_positions }
|
31
|
+
|
32
|
+
it { is_expected.to include(closed) }
|
33
|
+
it { is_expected.to include(opened) }
|
34
|
+
it { is_expected.not_to include(not_visited) }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#grid_from_s_map" do
|
38
|
+
context "when | on map" do
|
39
|
+
subject do
|
40
|
+
a_star.grid_from_s_map(<<-G)
|
41
|
+
.|.
|
42
|
+
.|.
|
43
|
+
G
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'makes the | not walkable' do
|
47
|
+
grid = subject
|
48
|
+
|
49
|
+
expect(grid[[1,0]][:walkable]).to be_falsey
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when _ on map" do
|
54
|
+
subject do
|
55
|
+
a_star.grid_from_s_map(<<-G)
|
56
|
+
._.
|
57
|
+
._.
|
58
|
+
G
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'makes the _ not walkable' do
|
62
|
+
grid = subject
|
63
|
+
|
64
|
+
expect(grid[[1,0]][:walkable]).to be_falsey
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#find_path" do
|
71
|
+
context 'timed' do
|
72
|
+
subject { a_star.find_path_a_with_time(position1, position2, grid) }
|
73
|
+
|
74
|
+
context 'origin to 100,100' do
|
75
|
+
let(:position1) { {x: 0, y: 0} }
|
76
|
+
let(:position2) { {x: 100, y: 100} }
|
77
|
+
let(:grid) { {max_x:10000, max_y:10000} }
|
78
|
+
|
79
|
+
it 'should not take too long' do
|
80
|
+
path = subject
|
81
|
+
|
82
|
+
expect(path).to include([0,0])
|
83
|
+
expect(path).to include([100,100])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'no diagonals' do
|
89
|
+
subject { a_star.find_path_a(position1, position2, grid) }
|
90
|
+
|
91
|
+
context 'origin to origin' do
|
92
|
+
let(:position1) { {x: 0, y: 0} }
|
93
|
+
let(:position2) { {x: 0, y: 0} }
|
94
|
+
let(:grid) { {max_x:10, max_y:10} }
|
95
|
+
|
96
|
+
it { is_expected.to eq([[0,0]]) }
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'origin to 1,1' do
|
100
|
+
let(:position1) { {x: 0, y: 0} }
|
101
|
+
let(:position2) { {x: 1, y: 1} }
|
102
|
+
|
103
|
+
context "when grid is nil" do
|
104
|
+
let(:grid) { nil }
|
105
|
+
|
106
|
+
it { is_expected.to eq([[0,0]]) }
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when grid contains start and end" do
|
110
|
+
let(:grid) { {max_x:2, max_y:2} }
|
111
|
+
|
112
|
+
it { is_expected.to eq([[0,0],[0,1],[1,1]]) }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'origin to 2,2' do
|
117
|
+
let(:position1) { {x: 0, y: 0} }
|
118
|
+
let(:position2) { {x: 2, y: 2} }
|
119
|
+
let(:grid) { {max_x:5, max_y:5} }
|
120
|
+
|
121
|
+
it { is_expected.to include([0,0]) }
|
122
|
+
it { is_expected.to include([2,2]) }
|
123
|
+
|
124
|
+
it 'has the correct length' do
|
125
|
+
path = subject
|
126
|
+
|
127
|
+
expect(path.length).to eq(5)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'unsolvable' do
|
132
|
+
context '1' do
|
133
|
+
let(:grid) {
|
134
|
+
a_star.grid_from_s_map(<<-G)
|
135
|
+
....|......
|
136
|
+
.1..|..2...
|
137
|
+
....|......
|
138
|
+
G
|
139
|
+
}
|
140
|
+
|
141
|
+
let(:position1) { {x: 1, y: 1} }
|
142
|
+
let(:position2) { {x: 7, y: 1} }
|
143
|
+
|
144
|
+
it { is_expected.to be_nil }
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'obstructed paths' do
|
150
|
+
context '1' do
|
151
|
+
let(:grid) {
|
152
|
+
a_star.grid_from_s_map(<<-G)
|
153
|
+
........
|
154
|
+
...........
|
155
|
+
...........
|
156
|
+
...........
|
157
|
+
....|......
|
158
|
+
.1..|..2...
|
159
|
+
....|......
|
160
|
+
..........
|
161
|
+
...........
|
162
|
+
G
|
163
|
+
}
|
164
|
+
|
165
|
+
let(:position1) { {x: 1, y: 3} }
|
166
|
+
let(:position2) { {x: 7, y: 3} }
|
167
|
+
|
168
|
+
it { is_expected.to include([1,3]) }
|
169
|
+
it { is_expected.to include([7,3]) }
|
170
|
+
|
171
|
+
it { is_expected.not_to include([4,2]) }
|
172
|
+
it { is_expected.not_to include([4,3]) }
|
173
|
+
it { is_expected.not_to include([4,4]) }
|
174
|
+
|
175
|
+
it 'has the correct length' do
|
176
|
+
path = subject
|
177
|
+
expect(path.length).to eq(11)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should only visit necessary positions' do
|
181
|
+
subject
|
182
|
+
|
183
|
+
expect(a_star.current_grid).not_to be_nil
|
184
|
+
expect(a_star.visited_positions.count).to eq(31)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context '2' do
|
189
|
+
let(:grid) {
|
190
|
+
a_star.grid_from_s_map(<<-G)
|
191
|
+
......|.....
|
192
|
+
.1....|.....
|
193
|
+
......|.....
|
194
|
+
......|.....
|
195
|
+
......|..2..
|
196
|
+
......|.....
|
197
|
+
......|.....
|
198
|
+
............
|
199
|
+
............
|
200
|
+
............
|
201
|
+
............
|
202
|
+
G
|
203
|
+
}
|
204
|
+
|
205
|
+
let(:position1) { {x: 1, y: 10} }
|
206
|
+
let(:position2) { {x: 9, y: 6} }
|
207
|
+
|
208
|
+
it { is_expected.to include([1,10]) }
|
209
|
+
it { is_expected.to include([9,6]) }
|
210
|
+
|
211
|
+
it { is_expected.not_to include([6,4]) }
|
212
|
+
it { is_expected.not_to include([6,5]) }
|
213
|
+
it { is_expected.not_to include([6,6]) }
|
214
|
+
it { is_expected.not_to include([6,7]) }
|
215
|
+
it { is_expected.not_to include([6,8]) }
|
216
|
+
it { is_expected.not_to include([6,9]) }
|
217
|
+
it { is_expected.not_to include([6,10]) }
|
218
|
+
it { is_expected.not_to include([6,11]) }
|
219
|
+
|
220
|
+
it 'has the correct length' do
|
221
|
+
path = subject
|
222
|
+
|
223
|
+
expect(path.length).to eq(19)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: astrid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- JHawk
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: A Star in ruby.
|
42
|
+
email:
|
43
|
+
- josh.r.hawk@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- astrid.gemspec
|
54
|
+
- lib/astrid.rb
|
55
|
+
- lib/astrid/finders/a_star.rb
|
56
|
+
- lib/astrid/heuristics/manhattan.rb
|
57
|
+
- lib/astrid/version.rb
|
58
|
+
- spec/astrid/finders/a_star_spec.rb
|
59
|
+
- spec/spec_helper.rb
|
60
|
+
homepage: ''
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.2.2
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: A Star in ruby.
|
84
|
+
test_files:
|
85
|
+
- spec/astrid/finders/a_star_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
has_rdoc:
|