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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d5905265e59f555d40f77ca80734ca2817bf181f
4
- data.tar.gz: 7a39008793acafb2210cbb86b65afa62a7962518
3
+ metadata.gz: 4e8cd2e0c5b9c4e076e821f8671207013a3dbf55
4
+ data.tar.gz: 4935ad855d64830a333886885a1045eda83a7b8c
5
5
  SHA512:
6
- metadata.gz: 09dc4135a6379f593c84096aef0855c49073040b6d51e8157a3f5d2badade4befb5e34f440a961bf158308d654c74f7676e3d325cbc479b8e26d9cf37d006c5c
7
- data.tar.gz: 0eed28da1c204fec071e320f049390ccac15d03c3e4bc3800e13bbc3a482326621aa194192bec3337e38e166aa824803a72943385cf69ee66b39578772165704
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
- public:
117
- path_t find_path(long int x1, long int y1, long int x2, long int y2) {
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/2) {
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 x;
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
  }
@@ -1,5 +1,16 @@
1
1
  class Pathfinding
2
- VERSION = '1.0'
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.0'
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-05 00:00:00.000000000 Z
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