chingu-pathfinding 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|