chingu-pathfinding 1.1.2 → 1.1.3

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: 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