castar 0.0.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.
@@ -0,0 +1,78 @@
1
+ require "castar/version"
2
+
3
+ module Castar
4
+ require 'heyes' # the .bundle file
5
+ include Heyes # so we don't have to specify Castar::Heyes:: ...
6
+
7
+
8
+ #convenience functions
9
+ module_function #make all the following instance methods module methods
10
+
11
+ def init_map( options={} )
12
+ defaults = {:width => 90, :height => 90}
13
+ options = defaults.merge(options)
14
+ nrow = options[:height]
15
+ ncol = options[:width]
16
+
17
+ # set cost for each cell to 1
18
+ a = Array.new(nrow).fill( Array.new(ncol).fill(1) )
19
+ map = Map.new(ncol, nrow)
20
+ a.each_with_index do |row, y|
21
+ row.each_with_index do |cost, x|
22
+ map.setCost(x,y,cost)
23
+ end
24
+ end
25
+
26
+ return map
27
+ end
28
+
29
+
30
+ def load_map(mapfile)
31
+ map = nil
32
+ y = 0
33
+ File.open(mapfile) do |f|
34
+ f.each_line do |line|
35
+ entries = line.chomp.split(',')
36
+ map ||= Castar::Map.new( entries.size, entries.size )
37
+ x = 0
38
+ line.chomp.split(',').each do |cost|
39
+ map.setCost(x,y,cost.to_i)
40
+ x += 1
41
+ end
42
+ y += 1
43
+ end
44
+ end
45
+ return map
46
+ end
47
+
48
+ def get_path(driver)
49
+ path = [];
50
+ (0..driver.getPathLength-1).each do |i|
51
+ path << {:x => driver.getPathXAtIndex(i), :y => driver.getPathYAtIndex(i)}
52
+ end
53
+ path
54
+ end
55
+
56
+ def get_map_with_path(driver)
57
+ path = get_path(driver)
58
+ pathstr="\n"
59
+ map = driver.getMap
60
+ (0..map.height-1).each do |row|
61
+ (0..map.width-1).each do |col|
62
+ value = map.getCost(col,row)
63
+ if(row==driver.nodeStart.y and col==driver.nodeStart.x)
64
+ pathstr<<"|S"
65
+ elsif(row==driver.nodeEnd.y and col==driver.nodeEnd.x)
66
+ pathstr<<"|G"
67
+ elsif(path.include?(:x => col, :y => row) )
68
+ pathstr<<"|*"
69
+ else
70
+ pathstr<<"|#{value}"
71
+ end
72
+ end
73
+ pathstr<<"|\n"
74
+ end
75
+ return pathstr
76
+ end
77
+
78
+ end
@@ -0,0 +1,3 @@
1
+ module Castar
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,107 @@
1
+ $: << File.join(File.expand_path(File.dirname(__FILE__)), '..')
2
+ require "castar"
3
+ include Castar
4
+
5
+ describe "astar pathfinding wrapper" do
6
+ it "should load a map" do
7
+ num_column = 4
8
+ num_row = 2
9
+ map = init_map(:width => num_column, :height => num_row)
10
+ map.height.should eq(num_row)
11
+ map.width.should eq(num_column)
12
+
13
+ (0..num_column-1).each do |x|
14
+ (0..num_row-1).each do |y|
15
+ num = rand(10)
16
+ map.setCost(x,y,num)
17
+ map.getCost(x,y).should eq(num)
18
+ end
19
+ end
20
+
21
+ map.getCost(4,1).should eq(Map::MAP_OUT_OF_BOUNDS)
22
+ map.getCost(1,2).should eq(Map::MAP_OUT_OF_BOUNDS)
23
+ map.getCost(10,10).should eq(Map::MAP_OUT_OF_BOUNDS)
24
+ end
25
+ it "map saved in driver should work" do
26
+ num_column = 4
27
+ num_row = 2
28
+ map1 = Map.new(num_column, num_row)
29
+ driver = HeyesDriver.new(map1)
30
+ map = driver.getMap
31
+ map.height.should eq(num_row)
32
+ map.width.should eq(num_column)
33
+
34
+ (0..num_column-1).each do |x|
35
+ (0..num_row-1).each do |y|
36
+ num = rand(10)
37
+ map.setCost(x,y,num)
38
+ map.getCost(x,y).should eq(num)
39
+ end
40
+ end
41
+
42
+ map.getCost(4,1).should eq(Map::MAP_OUT_OF_BOUNDS)
43
+ map.getCost(1,2).should eq(Map::MAP_OUT_OF_BOUNDS)
44
+ map.getCost(10,10).should eq(Map::MAP_OUT_OF_BOUNDS)
45
+ end
46
+
47
+ before :each do
48
+ @map = init_map(:width => 4, :height => 2)
49
+ @startx = 0
50
+ @starty = 0
51
+ @goalx = 3
52
+ @goaly = 0
53
+ end
54
+
55
+ it "should allow access to start and goal nodes" do
56
+ driver = HeyesDriver.new(@map)
57
+ driver.run(@startx, @starty, @goalx, @goaly)
58
+ driver.nodeStart.x.should eq @startx
59
+ driver.nodeStart.y.should eq @starty
60
+ driver.nodeEnd.x.should eq @goalx
61
+ driver.nodeEnd.y.should eq @goaly
62
+ end
63
+
64
+ it "should find a path when start and goal are the same" do
65
+ driver = HeyesDriver.new(@map)
66
+ driver.run(@startx, @starty, @startx, @starty)
67
+ path = get_path(driver)
68
+ path.length.should eq(1)
69
+ path.first.should eq({:x => 0, :y => 0})
70
+ end
71
+
72
+ it "should find the shortest path (no obstacle) " do
73
+ driver = HeyesDriver.new(@map)
74
+ driver.run(@startx, @starty, @goalx, @goaly)
75
+ path = get_path(driver)
76
+ path.length.should eq(4)
77
+ path.should eq([ {:x => 0, :y => 0}, {:x => 1, :y => 0}, {:x => 2, :y => 0}, {:x => 3, :y => 0}])
78
+ end
79
+
80
+ it "should find the shortest path allowing diagonal moves(no obstacle) " do
81
+ driver = HeyesDriver.new(@map, HeyesDriver::EIGHT_NEIGHBORS)
82
+ @starty=1
83
+ driver.run(@startx, @starty, @goalx, @goaly)
84
+ path = get_path(driver)
85
+ path.length.should eq(4)
86
+ #path.should eq([ {:x => 0, :y => 0}, {:x => 1, :y => 0}, {:x => 2, :y => 0}, {:x => 3, :y => 0}])
87
+ end
88
+
89
+ it "should find the shortest path (obstacle) " do
90
+ @map.setCost(1,0,Map::MAP_NO_WALK)
91
+ driver = HeyesDriver.new(@map)
92
+ driver.run(@startx, @starty, @goalx, @goaly)
93
+ path = get_path(driver)
94
+ path.length.should eq(6)
95
+ end
96
+
97
+ it "should load mapfile and find path" do
98
+ map =load_map('./spec/map_20.txt')
99
+ astar = HeyesDriver.new(map, HeyesDriver::EIGHT_NEIGHBORS)
100
+ astar.run(0,0,19,19)
101
+ astar.getPathLength.should eq 28
102
+ end
103
+
104
+ it "should have tests for memory management"
105
+
106
+ end
107
+
@@ -0,0 +1,20 @@
1
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
2
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
3
+ 1,1,9,9,9,9,1,1,1,1,1,9,9,9,9,9,9,9,9,9
4
+ 1,1,9,9,9,9,1,1,1,1,1,9,9,9,9,9,9,9,9,9
5
+ 1,1,9,9,9,9,1,1,1,1,1,9,9,9,9,9,9,9,9,9
6
+ 1,1,9,9,9,9,1,1,1,1,1,9,9,9,9,9,9,9,9,9
7
+ 1,1,9,9,9,9,1,1,1,1,1,9,9,9,9,9,9,9,9,9
8
+ 1,1,9,9,9,9,1,1,1,1,1,9,9,9,9,9,9,9,9,9
9
+ 1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9
10
+ 1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9
11
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
12
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
13
+ 1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,1,1,1
14
+ 1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,1,1,1
15
+ 1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,1,1,1
16
+ 1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,1,1,1
17
+ 1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,1,1,1
18
+ 1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,1,1,1
19
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
20
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
@@ -0,0 +1,4 @@
1
+ swig -c++ -ruby heyes.i
2
+ #ruby extconf.rb
3
+ #make
4
+
@@ -0,0 +1,7 @@
1
+ %module heyes
2
+ %{
3
+ #include "../ext/stlastar.h"
4
+ #include "../ext/findpath.h"
5
+ %}
6
+ %include "../ext/stlastar.h"
7
+ %include "../ext/findpath.h"
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: castar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Wilde
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &2156210560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2156210560
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec-core
27
+ requirement: &2156208020 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2156208020
36
+ description: ! "## DESCRIPTION:\n\nRuby interface to a C++ implemention of the A\\*
37
+ search algorithm.\n\nThe C++ implementaion is found here <http://code.google.com/p/a-star-algorithm-implementation/>\n\n\n##
38
+ FEATURES:\n\n\n## SYNOPSIS:\n\nSee `spec\\castar_spec.rb` for usage examples.\n\nCreate
39
+ an empty map and plan a path across it:\n\n require 'castar'\n include
40
+ Castar\n map = init_map(:width => 4, :height => 3)\n astar = HeyesDriver.new(map,
41
+ HeyesDriver::EIGHT_NEIGHBORS)\n astar.run(0,0,3,2)\n puts get_map_with_path(astar)\n\n
42
+ \ |S|1|1|1|\n |1|*|1|1|\n |1|1|*|G|\n \n\nLoad a map
43
+ from a text file and plan a path:\n\n map = load_map('./spec/map_20.txt')\n
44
+ \ astar = HeyesDriver.new(map, HeyesDriver::EIGHT_NEIGHBORS)\n astar.run(0,0,19,19)\n
45
+ \ puts get_map_with_path(astar)\n\n \n |S|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|\n
46
+ \ |1|*|*|*|*|*|1|1|1|1|1|1|1|1|1|1|1|1|1|1|\n |1|1|9|9|9|9|*|1|1|1|1|9|9|9|9|9|9|9|9|9|\n
47
+ \ |1|1|9|9|9|9|1|*|1|1|1|9|9|9|9|9|9|9|9|9|\n |1|1|9|9|9|9|1|1|*|1|1|9|9|9|9|9|9|9|9|9|\n
48
+ \ |1|1|9|9|9|9|1|1|1|*|1|9|9|9|9|9|9|9|9|9|\n |1|1|9|9|9|9|1|1|1|1|*|9|9|9|9|9|9|9|9|9|\n
49
+ \ |1|1|9|9|9|9|1|1|1|1|*|9|9|9|9|9|9|9|9|9|\n |1|1|1|1|1|1|1|1|1|1|*|9|9|9|9|9|9|9|9|9|\n
50
+ \ |1|1|1|1|1|1|1|1|1|1|*|9|9|9|9|9|9|9|9|9|\n |1|1|1|1|1|1|1|1|1|1|1|*|1|1|1|1|1|1|1|1|\n
51
+ \ |1|1|1|1|1|1|1|1|1|1|1|1|*|*|*|*|*|1|1|1|\n |1|1|1|1|1|9|9|9|9|9|9|9|9|9|9|9|9|*|1|1|\n
52
+ \ |1|1|1|1|1|9|9|9|9|9|9|9|9|9|9|9|9|1|*|1|\n |1|1|1|1|1|9|9|9|9|9|9|9|9|9|9|9|9|1|1|*|\n
53
+ \ |1|1|1|1|1|9|9|9|9|9|9|9|9|9|9|9|9|1|1|*|\n |1|1|1|1|1|9|9|9|9|9|9|9|9|9|9|9|9|1|1|*|\n
54
+ \ |1|1|1|1|1|9|9|9|9|9|9|9|9|9|9|9|9|1|1|*|\n |1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|*|\n
55
+ \ |1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|G|\n \n## REQUIREMENTS:\n\n*
56
+ Ruby 1.9 \n* C compiler for C extensions \n\n## DEVELOPMENT\n\nTo modify the gem
57
+ in a cloned repo this is what I'm doing (from root of gem):\n\n bundle install\n
58
+ \ cd ext/\n ruby extconf.rb\n make \n\nThese steps will install
59
+ the development dependencies, build the Makefile and compile the C++ code. Running\n\n
60
+ \ bundle exec rspec ./spec\n\nshould show all tests passing. To clean up the
61
+ autogenerated Makefile and the compiled objects:\n\n cd ext/\n make
62
+ realclean\n\nIf you need to regenerate the ruby interface functions `heyes_wrap.cxx`,
63
+ run:\n\n cd swig/\n swig -c++ -ruby heyes.i\n mv heyes_wrap.cxx
64
+ ../ext\n\nIf you are just trying to run the tests:\n\n rake build\n gem
65
+ install pkg/castar-0.0.1.gem\n\nbuilds the gem and installs it to your local machine.\n\n
66
+ \ gem which castar\n\ntells you where it is. You can then cd to that directory
67
+ and run the tests as above (but since you're not in a git repo you can't commit
68
+ them).\n\nI followed the instructions [here](https://github.com/radar/guides/blob/master/gem-development.md)
69
+ for using Bundler to create the gem.\n\n## INSTALL:\n\n* gem install castar\n\n##
70
+ LICENSE:\n\n(The MIT License)\n"
71
+ email:
72
+ - johnwilde@gmail.com
73
+ executables: []
74
+ extensions:
75
+ - ext/extconf.rb
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .gitignore
79
+ - Gemfile
80
+ - README.markdown
81
+ - Rakefile
82
+ - benchmarks/benchmark_helper.rb
83
+ - benchmarks/benchmarker.rb
84
+ - benchmarks/example.rb
85
+ - benchmarks/map90.0.txt
86
+ - benchmarks/map90.1.txt
87
+ - castar.gemspec
88
+ - ext/extconf.rb
89
+ - ext/findpath.h
90
+ - ext/fsa.h
91
+ - ext/heyes_wrap.cxx
92
+ - ext/stlastar.h
93
+ - lib/castar.rb
94
+ - lib/castar/version.rb
95
+ - spec/castar_spec.rb
96
+ - spec/map_20.txt
97
+ - swig/buildRubyExtension.sh
98
+ - swig/heyes.i
99
+ homepage: ''
100
+ licenses: []
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ - ext
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project: castar
120
+ rubygems_version: 1.8.12
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Ruby interface to a C++ implementation of the A* algorithm
124
+ test_files:
125
+ - spec/castar_spec.rb
126
+ - spec/map_20.txt
127
+ has_rdoc: