chingu-pathfinding 1.0 → 1.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 +4 -4
- data/ext/chingu_pathfinding/chingu_pathfinding.cpp +60 -19
- data/lib/chingu_pathfinding.rb +12 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e8cd2e0c5b9c4e076e821f8671207013a3dbf55
|
4
|
+
data.tar.gz: 4935ad855d64830a333886885a1045eda83a7b8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cba97a18f7017d06a47f1a6e3687dc60fefe24ccc720ceb21630ac65c5336746ee244d275ed2591f7afa0d95e6cd2fed51ef52d7bfbb870ef564934bebf991e2
|
7
|
+
data.tar.gz: 7ec84c3902cefa5b7313e289777ccb73bfc42646750e26d4ef7011bbcf3831a9f77d47803b420c80691ef371f5ff2b56647ef67789a28f925a730c87b92272b7
|
@@ -113,30 +113,16 @@ class pathfinder_t {
|
|
113
113
|
return false;
|
114
114
|
}
|
115
115
|
|
116
|
-
|
117
|
-
path_t
|
118
|
-
typedef std::priority_queue<path_t, std::vector<path_t>, by_estimated_cost> queue_t;
|
119
|
-
location_t start(x1,y1);
|
120
|
-
location_t goal(x2,y2);
|
121
|
-
by_estimated_cost estimator(goal);
|
122
|
-
queue_t queue(estimator);
|
116
|
+
typedef std::priority_queue<path_t, std::vector<path_t>, by_estimated_cost> queue_t;
|
117
|
+
path_t find_path_internal(queue_t queue, location_t goal) {
|
123
118
|
std::set<location_t> visited;
|
124
|
-
path_t init_path(&map, &connectivity);
|
125
|
-
long int next_node_x = (x1 / block_size)*block_size + block_size/2;
|
126
|
-
long int next_node_y = (y1 / block_size)*block_size + block_size/2;
|
127
|
-
init_path.add_loc(start, goal);
|
128
|
-
location_t start_block(next_node_x, next_node_y);
|
129
|
-
if (start != start_block) {
|
130
|
-
init_path.add_loc(start_block, goal);
|
131
|
-
}
|
132
|
-
queue.push(init_path);
|
133
119
|
while (!queue.empty()) {
|
134
120
|
path_t current = queue.top();
|
135
121
|
location_t end = current.end();
|
136
122
|
queue.pop();
|
137
123
|
if (visited.find(end) != visited.end()) continue;
|
138
124
|
visited.insert(end);
|
139
|
-
if (dist(end, goal) < block_size
|
125
|
+
if (dist(end, goal) < block_size) {
|
140
126
|
if (end != goal) {
|
141
127
|
current.add_loc(goal, goal);
|
142
128
|
}
|
@@ -156,10 +142,43 @@ class pathfinder_t {
|
|
156
142
|
return path_t();
|
157
143
|
}
|
158
144
|
|
145
|
+
public:
|
146
|
+
path_t find_path(long int x1, long int y1, long int x2, long int y2) {
|
147
|
+
location_t start(x1,y1);
|
148
|
+
location_t goal(x2,y2);
|
149
|
+
by_estimated_cost estimator(goal);
|
150
|
+
queue_t queue(estimator);
|
151
|
+
path_t init_path(&map, &connectivity);
|
152
|
+
long int next_node_x = (x1 / block_size)*block_size + block_size/2;
|
153
|
+
long int next_node_y = (y1 / block_size)*block_size + block_size/2;
|
154
|
+
init_path.add_loc(start, goal);
|
155
|
+
location_t start_block(next_node_x, next_node_y);
|
156
|
+
if (start != start_block) {
|
157
|
+
init_path.add_loc(start_block, goal);
|
158
|
+
}
|
159
|
+
queue.push(init_path);
|
160
|
+
return find_path_internal(queue, goal);
|
161
|
+
}
|
162
|
+
|
159
163
|
path_t find_path_update(long int x1, long int y1, long int x2, long int y2, std::vector<location_t> current) {
|
164
|
+
location_t current_location(x1,y1);
|
165
|
+
location_t goal(x2,y2);
|
160
166
|
path_t x;
|
167
|
+
by_estimated_cost estimator(goal);
|
168
|
+
queue_t queue(estimator);
|
169
|
+
// Cut out the part of the path already visited
|
170
|
+
bool drop = true;
|
171
|
+
for (location_t l : current) {
|
172
|
+
if (dist(l, current_location) < 2) {
|
173
|
+
drop = false;
|
174
|
+
}
|
175
|
+
if (!drop) {
|
176
|
+
x.add_loc(l, goal);
|
177
|
+
queue.push(x);
|
178
|
+
}
|
179
|
+
}
|
161
180
|
// Add every prefix of current to initial guess and converge to new location.
|
162
|
-
return
|
181
|
+
return find_path_internal(queue, goal);
|
163
182
|
}
|
164
183
|
|
165
184
|
void Init(VALUE self, long int width, long int height, long int block_size) {
|
@@ -285,6 +304,27 @@ static VALUE find_path(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2) {
|
|
285
304
|
return rb_ary_new4(i, path_ruby);
|
286
305
|
}
|
287
306
|
|
307
|
+
static VALUE find_path_update(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE prev) {
|
308
|
+
pathfinder_t* pf;
|
309
|
+
Data_Get_Struct(self, pathfinder_t, pf);
|
310
|
+
unsigned int len = RARRAY_LEN(prev);
|
311
|
+
std::vector<location_t> p;
|
312
|
+
for (int i = 0; i < len; i++) {
|
313
|
+
VALUE pt = rb_ary_shift(prev);
|
314
|
+
long int x = NUM2INT(rb_ary_shift(pt));
|
315
|
+
long int y = NUM2INT(rb_ary_shift(pt));
|
316
|
+
p.push_back(location_t(x, y));
|
317
|
+
}
|
318
|
+
path_t path = pf->find_path_update(NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), p);
|
319
|
+
if (path.path.empty()) return Qnil;
|
320
|
+
VALUE* path_ruby = new VALUE[path.path.size()];
|
321
|
+
int i = 0;
|
322
|
+
for (auto loc: path.path) {
|
323
|
+
path_ruby[i++] = rb_ary_new3(2, INT2NUM(loc.first), INT2NUM(loc.second));
|
324
|
+
}
|
325
|
+
return rb_ary_new4(i, path_ruby);
|
326
|
+
}
|
327
|
+
|
288
328
|
static VALUE print_map(VALUE self) {
|
289
329
|
pathfinder_t* pf;
|
290
330
|
Data_Get_Struct(self, pathfinder_t, pf);
|
@@ -299,6 +339,7 @@ static void Init_pathfinding() {
|
|
299
339
|
klass = rb_const_get(rb_cObject, rb_intern("Pathfinding"));
|
300
340
|
rb_define_alloc_func(klass, alloc_pathfinder);
|
301
341
|
rb_define_method(klass, "initialize", (rb_method) init, 3);
|
302
|
-
rb_define_method(klass, "find_path", (rb_method) find_path, 4);
|
303
342
|
rb_define_method(klass, "to_s", (rb_method) print_map, 0);
|
343
|
+
rb_define_private_method(klass, "_find_path", (rb_method) find_path, 4);
|
344
|
+
rb_define_private_method(klass, "_find_path_update", (rb_method) find_path_update, 5);
|
304
345
|
}
|
data/lib/chingu_pathfinding.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
class Pathfinding
|
2
|
-
VERSION = '1.
|
2
|
+
VERSION = '1.1'
|
3
|
+
def find_path(x1, y1, x2, y2)
|
4
|
+
throw "Require points to be numeric, got #{[x1, y1, x2, y2]}." unless [x1,y1,x2,y2].all? {|x| x.kind_of?(Numeric)}
|
5
|
+
_find_path(x1, y1, x2, y2)
|
6
|
+
end
|
7
|
+
def find_path_update(x1, y1, x2, y2, current)
|
8
|
+
throw "Require points to be numeric, got #{[x1, y1, x2, y2]}." unless [x1,y1,x2,y2].all? {|x| x.kind_of?(Numeric)}
|
9
|
+
unless current.kind_of?(Array) and current.all? {|p| p.kind_of?(Array) and p.length == 2 and p.all? {|e| e.kind_of?(Numeric)} }
|
10
|
+
throw "Require current to be list of points, got #{current}."
|
11
|
+
end
|
12
|
+
_find_path_update(x1,y1, x2, y2, current.collect(&:dup))
|
13
|
+
end
|
3
14
|
end
|
4
15
|
|
5
16
|
require_relative 'chingu_pathfinding/chingu_pathfinding'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chingu-pathfinding
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zombiecalypse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Find paths C supported on a static map with the A* algorithm.
|
14
14
|
email: maergil@gmail.com
|