chingu-pathfinding 1.1.2 → 1.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8858650c171257bdd67fb05a33dd949d39571085
4
- data.tar.gz: d4752cef76413e77f5eed22aa64826688c90b222
3
+ metadata.gz: acbba82b0ce19c59d1968606277fca2f0ce65794
4
+ data.tar.gz: 3d4aa10838504fa9ce82a7116fcca2afe3a35868
5
5
  SHA512:
6
- metadata.gz: ec0100d0ac4eb14e8e76121b3c2949310971a6bf9ce825580c0e6d12300c667a29f3c20750436d97212b71342b918db2f22e5689283c2e8da061320cabbb2856
7
- data.tar.gz: 16617428a3c769015618d6b89579a525f15dc65db5ad0a73a10b64257489807ed0e6b80a3aa896058ca4539fd96b32856244775a694d2cbe356993c0a337be8b
6
+ metadata.gz: 4ba0c8c9f2905de61d1c7491fd222a073b0dc161221dc772ca6803e593d497641e46a666a7f05aa7bb97591293e678c67046616f7fd53a408ec5b768e5188898
7
+ data.tar.gz: 42bd5a22cc0b2ea8cb93b25d78e1fdd66fdc820e6c096a73fc9e86f2216a719cafc5904d65feb81e7cc20992e7233996a138f4b35120a6fec685654e9c5ff2e2
@@ -1,9 +1,9 @@
1
1
  #include <ruby.h>
2
2
  #include <math.h>
3
3
  #include <vector>
4
- #include <map>
4
+ #include <unordered_map>
5
5
  #include <queue>
6
- #include <set>
6
+ #include <unordered_set>
7
7
  #include <iostream>
8
8
  #include <algorithm>
9
9
  #include <functional>
@@ -19,16 +19,30 @@ extern "C" {
19
19
  }
20
20
  }
21
21
 
22
- int dir(const long int a, const long int b) {
22
+ namespace std {
23
+ template<typename a, typename b>
24
+ struct hash< std::pair<a, b> > {
25
+ private:
26
+ const hash<a> ah;
27
+ const hash<b> bh;
28
+ public:
29
+ hash() : ah(), bh() {}
30
+ size_t operator()(const std::pair<a, b> &p) const {
31
+ return ah(p.first) ^ bh(p.second) << 5 ^ bh(p.second);
32
+ }
33
+ };
34
+ }
35
+
36
+ inline int dir(const int a, const int b) {
23
37
  if (a == b) return 0;
24
38
  if (a < b) return 1;
25
39
  return -1;
26
40
  }
27
41
 
28
42
  struct point_t {
29
- long int x, y;
43
+ int x, y;
30
44
  bool valid;
31
- point_t(long int xx, long int yy) {
45
+ point_t(int xx, int yy) {
32
46
  x = xx;
33
47
  y = yy;
34
48
  valid = true;
@@ -36,7 +50,7 @@ struct point_t {
36
50
  point_t() : x(0), y(0), valid(false) { }
37
51
  point_t(const point_t& p) : x(p.x), y(p.y), valid(p.valid) { }
38
52
  };
39
- typedef std::pair<long int, long int> location_t;
53
+ typedef std::pair<int, int> location_t;
40
54
 
41
55
  float dist(const location_t& a, const location_t& b) {
42
56
  float dx = a.first-b.first;
@@ -45,19 +59,19 @@ float dist(const location_t& a, const location_t& b) {
45
59
  }
46
60
 
47
61
  class path_t {
48
- std::map< location_t, point_t >* map_p;
49
- std::multimap< location_t, location_t >* connectivity_p;
62
+ std::unordered_map< location_t, point_t >* map_p;
63
+ std::unordered_multimap< location_t, location_t >* connectivity_p;
50
64
  float cost_paid;
51
65
 
52
66
  public:
53
67
  std::vector<location_t> path;
54
- path_t() : cost_paid(0) { }
68
+ path_t() : cost_paid(0), map_p(NULL), connectivity_p(NULL) { }
55
69
  path_t(const path_t& p) : map_p(p.map_p), connectivity_p(p.connectivity_p), path(p.path), cost_paid(p.cost_paid) { }
56
- path_t(std::map< location_t, point_t >* mm,
57
- std::multimap< location_t, location_t >* cc)
70
+ path_t(std::unordered_map< location_t, point_t >* mm,
71
+ std::unordered_multimap< location_t, location_t >* cc)
58
72
  : map_p(mm), connectivity_p(cc), cost_paid(0), path() { }
59
73
  float get_cost_paid() const { return cost_paid; }
60
- void add_loc(location_t l, const location_t& goal) {
74
+ void add_loc(const location_t& l, const location_t& goal) {
61
75
  if (!path.empty()) {
62
76
  location_t last = *path.crbegin();
63
77
  cost_paid += dist(last, l);
@@ -87,23 +101,23 @@ class by_estimated_cost {
87
101
 
88
102
 
89
103
  class pathfinder_t {
90
- std::map< location_t, point_t > map; // Spartial hashing
91
- std::multimap< location_t, location_t > connectivity; // sparse connectivity
92
- long int height, width, block_size;
104
+ std::unordered_map< location_t, point_t > map; // Spartial hashing
105
+ std::unordered_multimap< location_t, location_t > connectivity; // sparse connectivity
106
+ int height, width, block_size;
93
107
  ID blocked_method;
94
108
  VALUE self;
95
109
 
96
- bool is_blocked(const long int x, const long int y) {
110
+ bool is_blocked(const int x, const int y) {
97
111
  VALUE blocked = rb_funcall(self, blocked_method, 2, INT2NUM(x), INT2NUM(y));
98
112
  return blocked != Qfalse && blocked != Qnil;
99
113
  }
100
114
 
101
- bool line_blocked(const long int x1, const long int y1, const long int x2, const long int y2) {
115
+ bool line_blocked(const int x1, const int y1, const int x2, const int y2) {
102
116
  if (block_size == 1) return false;
103
- long int dx = dir(x1, x2);
104
- long int dy = dir(y1, y2);
105
- long int runner_x = x1;
106
- long int runner_y = y1;
117
+ int dx = dir(x1, x2);
118
+ int dy = dir(y1, y2);
119
+ int runner_x = x1;
120
+ int runner_y = y1;
107
121
  while (runner_x * dx <= x2 * dx &&
108
122
  runner_y * dy <= y2 * dy) {
109
123
  if (is_blocked(runner_x, runner_y)) {
@@ -116,11 +130,11 @@ class pathfinder_t {
116
130
  }
117
131
 
118
132
  typedef std::priority_queue<path_t, std::vector<path_t>, by_estimated_cost> queue_t;
119
- path_t find_path_internal(queue_t queue, location_t goal) {
120
- std::set<location_t> visited;
133
+ path_t find_path_internal(queue_t& queue, location_t& goal) {
134
+ std::unordered_set<location_t> visited;
121
135
  while (!queue.empty()) {
122
136
  path_t current = queue.top();
123
- location_t end = current.end();
137
+ const location_t& end = current.end();
124
138
  queue.pop();
125
139
  if (visited.find(end) != visited.end()) continue;
126
140
  visited.insert(end);
@@ -136,7 +150,7 @@ class pathfinder_t {
136
150
  if (visited.find(to) != visited.end()){
137
151
  continue;
138
152
  }
139
- path_t new_path = current;
153
+ path_t new_path(current);
140
154
  new_path.add_loc(to, goal);
141
155
  queue.push(new_path);
142
156
  }
@@ -145,14 +159,14 @@ class pathfinder_t {
145
159
  }
146
160
 
147
161
  public:
148
- path_t find_path(long int x1, long int y1, long int x2, long int y2) {
162
+ path_t find_path(int x1, int y1, int x2, int y2) {
149
163
  location_t start(x1,y1);
150
164
  location_t goal(x2,y2);
151
165
  by_estimated_cost estimator(goal);
152
166
  queue_t queue(estimator);
153
167
  path_t init_path(&map, &connectivity);
154
- long int next_node_x = (x1 / block_size)*block_size + block_size/2;
155
- long int next_node_y = (y1 / block_size)*block_size + block_size/2;
168
+ int next_node_x = (x1 / block_size)*block_size + block_size/2;
169
+ int next_node_y = (y1 / block_size)*block_size + block_size/2;
156
170
  init_path.add_loc(start, goal);
157
171
  location_t start_block(next_node_x, next_node_y);
158
172
  if (start != start_block) {
@@ -162,7 +176,7 @@ class pathfinder_t {
162
176
  return find_path_internal(queue, goal);
163
177
  }
164
178
 
165
- path_t find_path_update(long int x1, long int y1, long int x2, long int y2, std::vector<location_t> current) {
179
+ path_t find_path_update(int x1, int y1, int x2, int y2, std::vector<location_t> current) {
166
180
  location_t start(x1,y1);
167
181
  location_t goal(x2,y2);
168
182
  path_t init_path;
@@ -190,15 +204,17 @@ class pathfinder_t {
190
204
  return find_path_internal(queue, goal);
191
205
  }
192
206
 
193
- void Init(VALUE self, long int width, long int height, long int block_size) {
207
+ void Init(VALUE self, int width, int height, int block_size) {
194
208
  this->width = width;
195
209
  this->height = height;
196
210
  this->block_size = block_size;
197
211
  this->self = self;
212
+ this->map.reserve(width/block_size * height/block_size);
213
+ this->connectivity.reserve(width/block_size * height/block_size*4);
198
214
  blocked_method = rb_intern("blocked?");
199
215
  // Build internal map:
200
- for (long int x = block_size/2; x < width; x += block_size) {
201
- for (long int y = block_size/2; y < height; y += block_size) {
216
+ for (int x = block_size/2; x < width; x += block_size) {
217
+ for (int y = block_size/2; y < height; y += block_size) {
202
218
  // add point if it is not blocked
203
219
  if (is_blocked(x, y)) continue;
204
220
  auto cur_loc = location_t(x,y);
@@ -236,20 +252,19 @@ class pathfinder_t {
236
252
  }
237
253
  }
238
254
  }
239
- // print_map();
240
255
  } // END Init
241
256
 
242
257
  std::string print_map() {
243
258
  // DEBUGGING
244
259
 
245
- auto mapp = std::map<location_t, char>();
246
- for (long int x = 0; x < width; x++) {
247
- for (long int y = 0; y < height; y++) {
260
+ auto mapp = std::unordered_map<location_t, char>();
261
+ for (int x = 0; x < width; x++) {
262
+ for (int y = 0; y < height; y++) {
248
263
  mapp[location_t(x, y)] = ' ';
249
264
  }
250
265
  }
251
- for (long int x = block_size/2; x < width; x += block_size) {
252
- for (long int y = block_size/2; y < height; y += block_size) {
266
+ for (int x = block_size/2; x < width; x += block_size) {
267
+ for (int y = block_size/2; y < height; y += block_size) {
253
268
  if (!map[location_t(x, y)].valid) {
254
269
  mapp[location_t(x, y)] = '~';
255
270
  continue;
@@ -269,9 +284,9 @@ class pathfinder_t {
269
284
  }
270
285
  std::stringstream out;
271
286
  out << "map:";
272
- for (long int y = 0; y < height; y++) {
287
+ for (int y = 0; y < height; y++) {
273
288
  out << std::endl;
274
- for (long int x = 0; x < width; x++) {
289
+ for (int x = 0; x < width; x++) {
275
290
  out << mapp[location_t(x, y)];
276
291
  }
277
292
  }
@@ -293,8 +308,6 @@ static VALUE alloc_pathfinder(VALUE klass) {
293
308
 
294
309
  static VALUE init(VALUE self, VALUE width_a, VALUE height_a, VALUE block_size_a) {
295
310
  pathfinder_t* pf;
296
- long int width, height, block_size;
297
- long int x, y;
298
311
  Data_Get_Struct(self, pathfinder_t, pf);
299
312
  pf->Init(self, NUM2INT(width_a), NUM2INT(height_a), NUM2INT(block_size_a));
300
313
  return self;
@@ -320,8 +333,8 @@ static VALUE find_path_update(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2
320
333
  std::vector<location_t> p;
321
334
  for (int i = 0; i < len; i++) {
322
335
  VALUE pt = rb_ary_shift(prev);
323
- long int x = NUM2INT(rb_ary_shift(pt));
324
- long int y = NUM2INT(rb_ary_shift(pt));
336
+ int x = NUM2INT(rb_ary_shift(pt));
337
+ int y = NUM2INT(rb_ary_shift(pt));
325
338
  p.push_back(location_t(x, y));
326
339
  }
327
340
  path_t path = pf->find_path_update(NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), p);
@@ -14,4 +14,5 @@ end
14
14
  have_header("ruby.h")
15
15
  have_library("stdc++")
16
16
  try_compiler_option('-std=c++11')
17
+ try_compiler_option('-O3')
17
18
  create_makefile('chingu_pathfinding/chingu_pathfinding')
@@ -1,5 +1,5 @@
1
1
  class Pathfinding
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  def find_path(x1, y1, x2, y2)
4
4
  throw "Require points to be numeric, got #{[x1, y1, x2, y2]}." unless [x1,y1,x2,y2].all? {|x| x.kind_of?(Numeric)}
5
5
  _find_path(x1, y1, x2, y2)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chingu-pathfinding
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - zombiecalypse