pathfinding 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/LICENSE +21 -0
- data/README.md +105 -0
- data/lib/pathfinding.rb +7 -0
- data/lib/pathfinding/core/diagonal_movement.rb +24 -0
- data/lib/pathfinding/core/grid.rb +187 -0
- data/lib/pathfinding/core/heuristic.rb +41 -0
- data/lib/pathfinding/core/node.rb +37 -0
- data/lib/pathfinding/finder/astar.rb +94 -0
- data/pathfinding.gemspec +32 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 10c0aa6e36e9928d826330a689ad3cf9767d35da2cdbd7549d166d39dd773cae
|
4
|
+
data.tar.gz: 0ffca62280a953128a6dce12fcf770327c047d0e34643a69bede0b6fadc8aa96
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c2f8885e510048fb258f89001c9a00279180d39fd5b088464f45764660e6e25f4ba0646276d37a9e02551800c8742bef6fa44f279d698ad3a0f32c1e24f82c38
|
7
|
+
data.tar.gz: 953698ca4662703997497c94977ce312ed16ebe1a38e06955c4c794d36588a70d2e20ab1e345b04f874ba4508de95a38dd2139260021c3029afc273e0a3e8cab
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 Quentin DESCHAMPS
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Pathfinding in Ruby
|
2
|
+
|
3
|
+
A pathfinding library in Ruby based on A* algorithm.
|
4
|
+
|
5
|
+
Inpired by [python-pathfinding](https://github.com/brean/python-pathfinding)
|
6
|
+
|
7
|
+
## Install
|
8
|
+
To install the library, use the `gem` command:
|
9
|
+
```
|
10
|
+
gem install pathfinding
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
This is a simple example to find a path using A*.
|
15
|
+
|
16
|
+
1. Import the library:
|
17
|
+
```ruby
|
18
|
+
require 'pathfinding'
|
19
|
+
```
|
20
|
+
2. Create a map using a 2D-list. Any value smaller or equal to 0 describes a walkable node. Any number bigger than 0 describes an obstacle. In this example, we added an obstacle in the middle.
|
21
|
+
```ruby
|
22
|
+
matrix = [
|
23
|
+
[0, 0, 0],
|
24
|
+
[0, 1, 0],
|
25
|
+
[0, 0, 0]
|
26
|
+
]
|
27
|
+
```
|
28
|
+
Note: you can use negative values to describe different types of obstacles.
|
29
|
+
|
30
|
+
3. Create a new grid from this map representation. This will create Nodes instances for every element of the map.
|
31
|
+
```ruby
|
32
|
+
grid = Grid.new(matrix)
|
33
|
+
```
|
34
|
+
|
35
|
+
4. Set the start and end point from the map. In this example, the start point is on top-left and the end point is on bottom-right.
|
36
|
+
```ruby
|
37
|
+
start_node = grid.node(0, 0)
|
38
|
+
end_node = grid.node(2, 2)
|
39
|
+
```
|
40
|
+
|
41
|
+
5. Create a new instance of the finder and run the `find_path` method. If a path from start to the end point exists, this method returns the list of nodes of the path. Else, it returns an empty list.
|
42
|
+
```ruby
|
43
|
+
finder = AStarFinder.new()
|
44
|
+
path = finder.find_path(start_node, end_node, grid)
|
45
|
+
```
|
46
|
+
Note:
|
47
|
+
|
48
|
+
- You can choose the heuristic function to use using the `heuristic` argument.
|
49
|
+
- You can also choose the diagonal movements allowed using the `diagonal_movement` argument.
|
50
|
+
```ruby
|
51
|
+
finder = AStarFinder.new(Heuristic::method(:manhattan), DiagonalMovement::NEVER)
|
52
|
+
```
|
53
|
+
See the [documentation](https://www.rubydoc.info/gems/pathfinding/0.0.1) for more details.
|
54
|
+
|
55
|
+
6. Print the result (or do something else with it).
|
56
|
+
```ruby
|
57
|
+
puts grid.to_s(path, start_node, end_node)
|
58
|
+
```
|
59
|
+
The result should look like this:
|
60
|
+
```
|
61
|
+
+---+
|
62
|
+
|sxx|
|
63
|
+
| #x|
|
64
|
+
| e|
|
65
|
+
+---+
|
66
|
+
```
|
67
|
+
* +, - and | characters show the border around the map
|
68
|
+
* the blank space is a free field
|
69
|
+
* 's' marks the start
|
70
|
+
* 'e' marks the end
|
71
|
+
* '#' is the obstacle
|
72
|
+
* the 'x' characters mark the path from start to end
|
73
|
+
|
74
|
+
This is the whole example:
|
75
|
+
```ruby
|
76
|
+
require 'pathfinding'
|
77
|
+
|
78
|
+
matrix = [
|
79
|
+
[0, 0, 0],
|
80
|
+
[0, 1, 0],
|
81
|
+
[0, 0, 0]
|
82
|
+
]
|
83
|
+
grid = Grid.new(matrix)
|
84
|
+
|
85
|
+
start_node = grid.node(0, 0)
|
86
|
+
end_node = grid.node(2, 2)
|
87
|
+
|
88
|
+
finder = AStarFinder.new()
|
89
|
+
path = finder.find_path(start_node, end_node, grid)
|
90
|
+
|
91
|
+
puts grid.to_s(path, start_node, end_node)
|
92
|
+
```
|
93
|
+
|
94
|
+
Take a look at the `examples/` folder for more examples.
|
95
|
+
|
96
|
+
## Links
|
97
|
+
- GitHub: https://github.com/Quentin18/pathfinding.rb
|
98
|
+
- RubyGems: https://rubygems.org/gems/pathfinding
|
99
|
+
- Documentation: https://www.rubydoc.info/gems/pathfinding/0.0.1
|
100
|
+
|
101
|
+
## Author
|
102
|
+
[Quentin Deschamps](mailto:quentindeschamps18@gmail.com)
|
103
|
+
|
104
|
+
## License
|
105
|
+
[MIT](https://choosealicense.com/licenses/mit/)
|
data/lib/pathfinding.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: diagonal_movement.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
#
|
10
|
+
# Constants to set diagonal movements.
|
11
|
+
#
|
12
|
+
module DiagonalMovement
|
13
|
+
# Always accept diagonal movements.
|
14
|
+
ALWAYS = 1
|
15
|
+
|
16
|
+
# Never accept diagonal movements.
|
17
|
+
NEVER = 2
|
18
|
+
|
19
|
+
# Accept a diagonal movement if there is at most one obstacle.
|
20
|
+
IF_AT_MOST_ONE_OBSTACLE = 3
|
21
|
+
|
22
|
+
# Accept a diagonal movement only when there is no obstacle.
|
23
|
+
ONLY_WHEN_NO_OBSTACLE = 4
|
24
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: grid.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathfinding/core/node'
|
10
|
+
require 'pathfinding/core/diagonal_movement'
|
11
|
+
|
12
|
+
#
|
13
|
+
# Represents the grid as a 2d-list of nodes.
|
14
|
+
#
|
15
|
+
class Grid
|
16
|
+
include Enumerable
|
17
|
+
|
18
|
+
#
|
19
|
+
# Creates a grid from a matrix:
|
20
|
+
# * 0 (or less) represents a walkable node
|
21
|
+
# * A number greater than 0 does not represents a walkable node
|
22
|
+
# The +width+ represents the number of columns whereas the +height+
|
23
|
+
# is the number of rows of the grid. The +node+ attribute
|
24
|
+
# is the list of nodes.
|
25
|
+
#
|
26
|
+
def initialize(matrix)
|
27
|
+
@height = matrix.length
|
28
|
+
@width = matrix[0].length
|
29
|
+
@nodes = Grid.build_nodes(@width, @height, matrix)
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Gets the node at position (+x+, +y+).
|
34
|
+
#
|
35
|
+
def node(x, y)
|
36
|
+
@nodes[y][x]
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Yields all nodes of the grid.
|
41
|
+
#
|
42
|
+
def each_node
|
43
|
+
@height.times do |y|
|
44
|
+
@width.times do |x|
|
45
|
+
yield node(x, y)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Creates a printable string from the grid using ASCII characters.
|
52
|
+
# Params:
|
53
|
+
# +path+:: list of nodes that show the path
|
54
|
+
# +start_node+:: start node
|
55
|
+
# +end_node+:: end node
|
56
|
+
# +border+:: create a border around the grid
|
57
|
+
# +start_chr+:: character for the start (default "s")
|
58
|
+
# +end_chr+:: character for the end (default "e")
|
59
|
+
# +path_chr+:: character for the path (default "x")
|
60
|
+
# +empty_chr+:: character for the empty fields (default " ")
|
61
|
+
# +block_chr+:: character for the blocking elements (default "#")
|
62
|
+
#
|
63
|
+
def to_s(
|
64
|
+
path = nil, start_node = nil, end_node = nil, border = true,
|
65
|
+
start_chr = 's', end_chr = 'e', path_chr = 'x', empty_chr = ' ', block_chr = '#'
|
66
|
+
)
|
67
|
+
data = []
|
68
|
+
data << '+' + '-' * @width + '+' if border
|
69
|
+
@height.times do |y|
|
70
|
+
line = ''
|
71
|
+
line += '|' if border
|
72
|
+
@width.times do |x|
|
73
|
+
current = node(x, y)
|
74
|
+
if current == start_node
|
75
|
+
line += start_chr
|
76
|
+
elsif current == end_node
|
77
|
+
line += end_chr
|
78
|
+
elsif path&.include?(current)
|
79
|
+
line += path_chr
|
80
|
+
elsif current.walkable
|
81
|
+
line += empty_chr
|
82
|
+
else
|
83
|
+
line += block_chr
|
84
|
+
end
|
85
|
+
end
|
86
|
+
line += '|' if border
|
87
|
+
data << line
|
88
|
+
end
|
89
|
+
data << '+' + '-' * @width + '+' if border
|
90
|
+
data.join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Returns if the (+x+, +y+) position is in the grid.
|
95
|
+
#
|
96
|
+
def inside?(x, y)
|
97
|
+
x >= 0 && x < @width && y >= 0 && y < @height
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Returns if a node at position (+x+, +y+) is walkable.
|
102
|
+
#
|
103
|
+
def walkable?(x, y)
|
104
|
+
inside?(x, y) && node(x, y).walkable
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Get all neighbors of a node.
|
109
|
+
#
|
110
|
+
def neighbors(node, diagonal_movement=DiagonalMovement::NEVER)
|
111
|
+
x = node.x
|
112
|
+
y = node.y
|
113
|
+
neighbors = []
|
114
|
+
s0 = d0 = s1 = d1 = s2 = d2 = s3 = d3 = false
|
115
|
+
|
116
|
+
# ↑
|
117
|
+
if walkable?(x, y - 1)
|
118
|
+
neighbors << node(x, y - 1)
|
119
|
+
s0 = true
|
120
|
+
end
|
121
|
+
|
122
|
+
# →
|
123
|
+
if walkable?(x + 1, y)
|
124
|
+
neighbors << node(x + 1, y)
|
125
|
+
s1 = true
|
126
|
+
end
|
127
|
+
|
128
|
+
# ↓
|
129
|
+
if walkable?(x, y + 1)
|
130
|
+
neighbors << node(x, y + 1)
|
131
|
+
s2 = true
|
132
|
+
end
|
133
|
+
|
134
|
+
# ←
|
135
|
+
if walkable?(x - 1, y)
|
136
|
+
neighbors << node(x - 1, y)
|
137
|
+
s3 = true
|
138
|
+
end
|
139
|
+
|
140
|
+
return neighbors if diagonal_movement == DiagonalMovement::NEVER
|
141
|
+
|
142
|
+
if diagonal_movement == DiagonalMovement::ONLY_WHEN_NO_OBSTACLE
|
143
|
+
d0 = s3 && s0
|
144
|
+
d1 = s0 && s1
|
145
|
+
d2 = s1 && s2
|
146
|
+
d3 = s2 && s3
|
147
|
+
elsif diagonal_movement == DiagonalMovement::IF_AT_MOST_ONE_OBSTACLE
|
148
|
+
d0 = s3 || s0
|
149
|
+
d1 = s0 || s1
|
150
|
+
d2 = s1 || s2
|
151
|
+
d3 = s2 || s3
|
152
|
+
elsif diagonal_movement == DiagonalMovement::ALWAYS
|
153
|
+
d0 = d1 = d2 = d3 = true
|
154
|
+
else
|
155
|
+
raise 'Incorrect value of diagonal_movement'
|
156
|
+
end
|
157
|
+
|
158
|
+
# ↖
|
159
|
+
neighbors << node(x - 1, y - 1) if d0 && walkable?(x - 1, y - 1)
|
160
|
+
|
161
|
+
# ↗
|
162
|
+
neighbors << node(x + 1, y - 1) if d1 && walkable?(x + 1, y - 1)
|
163
|
+
|
164
|
+
# ↘
|
165
|
+
neighbors << node(x + 1, y + 1) if d2 && walkable?(x + 1, y + 1)
|
166
|
+
|
167
|
+
# ↙
|
168
|
+
neighbors << node(x - 1, y + 1) if d3 && walkable?(x - 1, y + 1)
|
169
|
+
|
170
|
+
neighbors
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# Builds and returns the nodes.
|
175
|
+
#
|
176
|
+
def self.build_nodes(width, height, matrix)
|
177
|
+
nodes = []
|
178
|
+
height.times do |y|
|
179
|
+
nodes << []
|
180
|
+
width.times do |x|
|
181
|
+
walkable = matrix[y][x] <= 0
|
182
|
+
nodes[y] << Node.new(x, y, walkable)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
nodes
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: heuristic.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
#
|
10
|
+
# A collection of heuristic functions.
|
11
|
+
#
|
12
|
+
module Heuristic
|
13
|
+
#
|
14
|
+
# Manhattan distance.
|
15
|
+
#
|
16
|
+
def self.manhattan(dx, dy)
|
17
|
+
dx + dy
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Euclidean distance.
|
22
|
+
#
|
23
|
+
def self.euclidean(dx, dy)
|
24
|
+
Math.sqrt(dx * dx + dy * dy)
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Octile distance.
|
29
|
+
#
|
30
|
+
def self.octile(dx, dy)
|
31
|
+
f = Math.sqrt(2) - 1
|
32
|
+
dx < dy ? f * dx + dy : f * dy + dx
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Chebyshev distance.
|
37
|
+
#
|
38
|
+
def self.chebyshev(dx, dy)
|
39
|
+
[dx, dy].max
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: node.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
|
9
|
+
#
|
10
|
+
# Represents a node in the grid.
|
11
|
+
#
|
12
|
+
class Node
|
13
|
+
# Gets the x coordinate in the grid.
|
14
|
+
attr_reader :x
|
15
|
+
|
16
|
+
# Gets the y coordinate in the grid.
|
17
|
+
attr_reader :y
|
18
|
+
|
19
|
+
# Gets whether the node is walkable.
|
20
|
+
attr_reader :walkable
|
21
|
+
|
22
|
+
#
|
23
|
+
# Creates a node.
|
24
|
+
#
|
25
|
+
def initialize(x, y, walkable = true)
|
26
|
+
@x = x
|
27
|
+
@y = y
|
28
|
+
@walkable = walkable
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Makes the string format of a node.
|
33
|
+
#
|
34
|
+
def to_s
|
35
|
+
"(#{@x}, #{@y})"
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# File: astar.rb
|
5
|
+
# Author: Quentin Deschamps
|
6
|
+
# Date: August 2020
|
7
|
+
#
|
8
|
+
require 'pathfinding/core/grid'
|
9
|
+
require 'pathfinding/core/diagonal_movement'
|
10
|
+
require 'pathfinding/core/heuristic'
|
11
|
+
|
12
|
+
#
|
13
|
+
# A* path-finder.
|
14
|
+
#
|
15
|
+
class AStarFinder
|
16
|
+
#
|
17
|
+
# Initializes the A* path-finder. Params:
|
18
|
+
# * +heuristic+: heuristic function (see the +Heuristic+ module)
|
19
|
+
# * +diagonal_movement+: set diagonal movements (see the +DiagonalMovement+ module)
|
20
|
+
#
|
21
|
+
def initialize(
|
22
|
+
heuristic = Heuristic::method(:manhattan),
|
23
|
+
diagonal_movement = DiagonalMovement::NEVER
|
24
|
+
)
|
25
|
+
@diagonal_movement = diagonal_movement
|
26
|
+
if diagonal_movement == DiagonalMovement::NEVER
|
27
|
+
@heuristic = heuristic
|
28
|
+
else
|
29
|
+
@heuristic = Heuristic::method(:octile)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Finds and returns the path as a list of node objects.
|
35
|
+
#
|
36
|
+
def find_path(start_node, end_node, grid)
|
37
|
+
open_set = [start_node]
|
38
|
+
came_from = {}
|
39
|
+
g_score = {}
|
40
|
+
f_score = {}
|
41
|
+
grid.each_node do |node|
|
42
|
+
g_score[node] = Float::INFINITY
|
43
|
+
f_score[node] = Float::INFINITY
|
44
|
+
end
|
45
|
+
g_score[start_node] = 0
|
46
|
+
f_score[start_node] = @heuristic.call(
|
47
|
+
(start_node.x - end_node.x).abs, (start_node.y - end_node.y).abs)
|
48
|
+
|
49
|
+
until open_set.empty?
|
50
|
+
current = open_set[0]
|
51
|
+
open_set.each do |node|
|
52
|
+
current = node if f_score[node] < f_score[current]
|
53
|
+
end
|
54
|
+
|
55
|
+
if current == end_node
|
56
|
+
return reconstruct_path(came_from, current)
|
57
|
+
end
|
58
|
+
|
59
|
+
current = open_set.delete_at(open_set.index(current))
|
60
|
+
|
61
|
+
grid.neighbors(current, @diagonal_movement).each do |neighbor|
|
62
|
+
tentative_g_score = g_score[current] + d(current, neighbor)
|
63
|
+
next if tentative_g_score >= g_score[neighbor]
|
64
|
+
|
65
|
+
came_from[neighbor] = current
|
66
|
+
g_score[neighbor] = tentative_g_score
|
67
|
+
f_score[neighbor] = g_score[neighbor] + @heuristic.call(
|
68
|
+
(neighbor.x - end_node.x).abs, (neighbor.y - end_node.y).abs)
|
69
|
+
unless open_set.include?(neighbor)
|
70
|
+
open_set << neighbor
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Returns the distance between two nodes.
|
78
|
+
#
|
79
|
+
def d(n1, n2)
|
80
|
+
(n1.x == n2.x || n1.y == n2.y) ? 1 : Math.sqrt(2)
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Reconstructs the path from the current node.
|
85
|
+
#
|
86
|
+
def reconstruct_path(came_from, current)
|
87
|
+
total_path = [current]
|
88
|
+
while came_from.include?(current)
|
89
|
+
current = came_from[current]
|
90
|
+
total_path << current
|
91
|
+
end
|
92
|
+
total_path.reverse
|
93
|
+
end
|
94
|
+
end
|
data/pathfinding.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'pathfinding'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.license = 'MIT'
|
5
|
+
s.summary = 'A pathfinding library based on A* algorithm.'
|
6
|
+
s.description = <<-DESCRIPTION
|
7
|
+
A pathfinding library based on A* algorithm.
|
8
|
+
Different options about heuristic and diagonal movements can be used.
|
9
|
+
The grid can be printed in the command prompt.
|
10
|
+
DESCRIPTION
|
11
|
+
s.author = 'Quentin Deschamps'
|
12
|
+
s.email = 'quentindeschamps18@gmail.com'
|
13
|
+
s.homepage = 'https://github.com/Quentin18/pathfinding.rb'
|
14
|
+
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
s.files = [
|
17
|
+
'lib/pathfinding.rb',
|
18
|
+
'lib/pathfinding/core/diagonal_movement.rb',
|
19
|
+
'lib/pathfinding/core/grid.rb',
|
20
|
+
'lib/pathfinding/core/heuristic.rb',
|
21
|
+
'lib/pathfinding/core/node.rb',
|
22
|
+
'lib/pathfinding/finder/astar.rb',
|
23
|
+
'LICENSE',
|
24
|
+
'README.md',
|
25
|
+
'pathfinding.gemspec'
|
26
|
+
]
|
27
|
+
|
28
|
+
s.rdoc_options = ['--main', 'README.md']
|
29
|
+
s.extra_rdoc_files = ['LICENSE', 'README.md']
|
30
|
+
|
31
|
+
s.post_install_message = 'Thanks for installing!'
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pathfinding
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Quentin Deschamps
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-18 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
A pathfinding library based on A* algorithm.
|
15
|
+
Different options about heuristic and diagonal movements can be used.
|
16
|
+
The grid can be printed in the command prompt.
|
17
|
+
email: quentindeschamps18@gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files:
|
21
|
+
- LICENSE
|
22
|
+
- README.md
|
23
|
+
files:
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- lib/pathfinding.rb
|
27
|
+
- lib/pathfinding/core/diagonal_movement.rb
|
28
|
+
- lib/pathfinding/core/grid.rb
|
29
|
+
- lib/pathfinding/core/heuristic.rb
|
30
|
+
- lib/pathfinding/core/node.rb
|
31
|
+
- lib/pathfinding/finder/astar.rb
|
32
|
+
- pathfinding.gemspec
|
33
|
+
homepage: https://github.com/Quentin18/pathfinding.rb
|
34
|
+
licenses:
|
35
|
+
- MIT
|
36
|
+
metadata: {}
|
37
|
+
post_install_message: Thanks for installing!
|
38
|
+
rdoc_options:
|
39
|
+
- "--main"
|
40
|
+
- README.md
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubygems_version: 3.0.3
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: A pathfinding library based on A* algorithm.
|
58
|
+
test_files: []
|