brawl 0.0.0.alpha → 0.0.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.
Files changed (63) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +0 -0
  3. data/README.md +43 -0
  4. data/_design/ClassDescriptions.txt +98 -0
  5. data/_design/Psudo_Program.rb +113 -0
  6. data/_design/array.rb +4 -0
  7. data/_design/threads.rb +71 -0
  8. data/_spike/Communications/communications.rb +2 -0
  9. data/_spike/Communications/lib/communications/com_linker.rb +11 -0
  10. data/_spike/Communications/lib/communications/null_modem.rb +11 -0
  11. data/_spike/Communications/spec/communications/com_linker_spec.rb +37 -0
  12. data/_spike/DRb/arena.rb +32 -0
  13. data/_spike/DRb/battle_controller.rb +54 -0
  14. data/_spike/DRb/bot.rb +23 -0
  15. data/_spike/DRb/bot_runner.rb +110 -0
  16. data/_spike/DRb/comment.txt +11 -0
  17. data/_spike/DRb/server.rb +28 -0
  18. data/_spike/DRb/test_bot.rb +6 -0
  19. data/_spike/array.rb +7 -0
  20. data/_spike/atan2.rb +39 -0
  21. data/_spike/battle.rb +202 -0
  22. data/_spike/break.rb +10 -0
  23. data/_spike/circles.rb +29 -0
  24. data/_spike/cleaner_attribs.rb +13 -0
  25. data/_spike/comlink.rb +61 -0
  26. data/_spike/concat.rb +27 -0
  27. data/_spike/example_bot.rb +42 -0
  28. data/_spike/forwarding_instance.rb +32 -0
  29. data/_spike/hash_loop.rb +17 -0
  30. data/_spike/hashing.rb +7 -0
  31. data/_spike/hook.rb +19 -0
  32. data/_spike/mod.rb +10 -0
  33. data/_spike/point_in_cone.rb +20 -0
  34. data/_spike/runner.rb +44 -0
  35. data/_spike/safe.rb +28 -0
  36. data/brawl.gemspec +4 -3
  37. data/example/example_battle.rb +173 -0
  38. data/example/logview.txt +6394 -0
  39. data/lib/brawl.rb +14 -3
  40. data/lib/brawl/_helper.rb +65 -0
  41. data/lib/brawl/arena.rb +118 -0
  42. data/lib/brawl/basic_arena_object.rb +35 -0
  43. data/lib/brawl/basic_bot.rb +69 -0
  44. data/lib/brawl/battle_controller.rb +97 -0
  45. data/lib/brawl/bot_proxy.rb +60 -0
  46. data/lib/brawl/clock.rb +36 -0
  47. data/lib/brawl/parts.rb +3 -0
  48. data/lib/brawl/parts/basic_motor.rb +55 -0
  49. data/lib/brawl/parts/basic_scanner.rb +33 -0
  50. data/lib/brawl/parts/basic_weapon.rb +47 -0
  51. data/lib/brawl/version.rb +1 -1
  52. data/lib/brawl/wall.rb +9 -0
  53. data/spec/brawl/arena_spec.rb +163 -0
  54. data/spec/brawl/basic_arena_object_spec.rb +40 -0
  55. data/spec/brawl/basic_bot_spec.rb +84 -0
  56. data/spec/brawl/battle_controller_spec.rb +138 -0
  57. data/spec/brawl/clock_spec.rb +28 -0
  58. data/spec/brawl/helper_spec.rb +23 -0
  59. data/spec/brawl/parts/basic_motor_spec.rb +220 -0
  60. data/spec/brawl/parts/basic_scanner_spec.rb +101 -0
  61. data/spec/brawl/parts/basic_weapon_spec.rb +146 -0
  62. data/spec/spec_helper.rb +5 -0
  63. metadata +101 -10
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ $DEBUG=true
3
+ Thread.abort_on_exception
4
+
5
+ describe Brawl::BattleController do
6
+
7
+ let(:arena_data) {{size: {width: 10, length: 10}}}
8
+ let(:clock_data) {{tick_rate: 0.01}}
9
+
10
+ let(:motor) { {Brawl::BasicMotor=>{move_max: 1, turn_max: 360}} }
11
+ let(:scanner) { {Brawl::BasicScanner=>{scan_max: 30, angle_max: 360}} }
12
+ let(:weapon) { {Brawl::BasicWeapon=>{range: 20, power: 1}} }
13
+ let(:parts) { motor.merge(scanner).merge(weapon) }
14
+
15
+ let(:bot_code) do
16
+ <<-CODE
17
+ code do |bot|
18
+ # puts
19
+ # puts "Basic bot... meh."
20
+ if rand(0) > 0.5
21
+ bot.turn [:left,:right,:around].sample
22
+ end
23
+ bot.move rand(3) + 1
24
+ end
25
+ CODE
26
+ end
27
+ let(:bot1) do
28
+ {
29
+ name: "Basic Bot 1",
30
+ class: Brawl::BasicBot,
31
+ params: {parts: parts},
32
+ code: bot_code
33
+ }
34
+ end
35
+
36
+
37
+ let(:helpless_bot_code) do
38
+ <<-CODE
39
+ code do |bot|
40
+ sleep(0.05)
41
+ end
42
+ CODE
43
+ end
44
+ let(:helpless_bot1) do
45
+ {
46
+ name: "Helpless Bot 1",
47
+ class: Brawl::BasicBot,
48
+ params: {parts: parts},
49
+ code: helpless_bot_code
50
+ }
51
+ end
52
+
53
+ let(:battle_bot_code) do
54
+ <<-CODE
55
+ code do |bot|
56
+ @dir ||= 0
57
+ # puts
58
+ # puts "Battle Bot!"
59
+ # puts "scan: \#{@dir}"
60
+ targets = bot.scan direction: @dir, angle: 90
61
+ @dir += 45
62
+ @dir %= 360
63
+ targets.each do |target|
64
+ unless target[:class] == Brawl::Wall
65
+ # puts " target: \#{target[:name]}"
66
+ # puts " bearing: \#{target[:bearing]}"
67
+ # puts "distance: \#{target[:distance]}"
68
+ results = shoot(target[:bearing])
69
+ # puts "shoot results: \#{results}"
70
+ end
71
+ end
72
+ end
73
+ CODE
74
+ end
75
+ let(:battle_bot1) do
76
+ {
77
+ name: "Battle Bot 1",
78
+ class: Brawl::BasicBot,
79
+ params: {parts: parts},
80
+ code: battle_bot_code
81
+ }
82
+ end
83
+
84
+ context "when configuring the controller" do
85
+
86
+ it "should create an arena object" do
87
+ battle = Brawl::BattleController.new
88
+ battle.make_arena(arena_data)
89
+ battle.arena.should be_a(Brawl::Arena)
90
+ end
91
+
92
+ it "should create a clock object" do
93
+ battle = Brawl::BattleController.new
94
+ battle.make_clock(clock_data)
95
+ battle.clock.should be_a(Brawl::Clock)
96
+ end
97
+
98
+ it "should set the arena's clock to the created clock" do
99
+ battle = Brawl::BattleController.new
100
+ battle.make_arena(arena_data)
101
+ battle.make_clock(clock_data)
102
+ battle.arena.clock.should == battle.clock
103
+ end
104
+
105
+ it "should create bots" do
106
+ battle = Brawl::BattleController.new
107
+ battle.make_arena(arena_data)
108
+ battle.make_clock(clock_data)
109
+
110
+ bot_data = [bot1]
111
+ battle.make_bots(bot_data)
112
+
113
+ battle.bots.should_not be_empty
114
+ end
115
+
116
+ end
117
+
118
+ context "when running bots" do
119
+
120
+ it "should stop when one bot reaches 0 health" do
121
+ battle = Brawl::BattleController.new
122
+ battle.make_arena(arena_data)
123
+ battle.make_clock(clock_data)
124
+
125
+ bot_data = [helpless_bot1, battle_bot1]
126
+ battle.make_bots(bot_data)
127
+ # puts "victory? #{battle.victory?}"
128
+ battle.start
129
+ until battle.victory?
130
+ sleep(0.5)
131
+ end
132
+ battle.victory?.should be_true
133
+ # puts "victory? #{battle.victory?}"
134
+ end
135
+
136
+ end
137
+
138
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brawl::Clock do
4
+
5
+ let(:clock){Brawl::Clock.new(0.01)}
6
+
7
+ it "should start counting" do
8
+ expect{clock.start; sleep(0.05)}.should change(clock, :ticks)
9
+ clock.stop
10
+ end
11
+
12
+ it "should stop counting" do
13
+ clock.start
14
+ sleep(0.02)
15
+ clock.stop
16
+ sleep(0.02)
17
+ expect{sleep(0.05)}.should_not change(clock, :ticks)
18
+ end
19
+
20
+ it "should increment 'tick' at the specified interval" do
21
+ clock = Brawl::Clock.new(0.01)
22
+ clock.start
23
+ sleep(0.10)
24
+ clock.stop
25
+ clock.ticks.should be_within(1.1).of(10)
26
+ end
27
+
28
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brawl::Helper do
4
+
5
+ let(:helper){Brawl::Helper}
6
+
7
+ context "when wrapping angles" do
8
+
9
+ # no change
10
+ it {helper.wrap_angle(45).should == 45.0}
11
+ it {helper.wrap_angle(179).should == 179.0 }
12
+ it {helper.wrap_angle(-40).should == -40.0}
13
+ it {helper.wrap_angle(-179).should == -179.0 }
14
+
15
+ # complement angle, "Have you been working out? You look less obtuse!"
16
+ it {helper.wrap_angle(270).should == -90.0 }
17
+ it {helper.wrap_angle(-320).should == 40.0 }
18
+ it {helper.wrap_angle(-280).should == 80.0 }
19
+ it {helper.wrap_angle(185).should == -175.0 }
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,220 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brawl::BasicMotor do
4
+
5
+ let(:arena){Brawl::Arena.new(size: {width: 100, length: 100})}
6
+ let(:bot) do
7
+ Brawl::BasicBot.new(
8
+ arena: arena,
9
+ parts: {Brawl::BasicMotor=>{move_max: 1, turn_max: 360}}
10
+ )
11
+ end
12
+
13
+ context "when moving" do
14
+
15
+ it "should move forward one space" do
16
+ expect{bot.move 1}.should change(bot, :location).
17
+ from({x: 0.0, y: 0.0}).
18
+ to({x: 0.0, y: 1.0})
19
+ end
20
+
21
+ it "should move forward one space" do
22
+ bot.turn :right
23
+
24
+ expect{bot.move}.should change(bot, :location).
25
+ from({x: 0.0, y: 0.0}).
26
+ to({x: 1.0, y: 0.0})
27
+ end
28
+
29
+ it "should move in the direction it is facing" do
30
+ bot.turn to_angle: 45
31
+ expect{bot.move}.should change(bot, :location).
32
+ from({x: 0.0, y: 0.0}).
33
+ to({x: 0.7, y: 0.7})
34
+ end
35
+
36
+ it "should not move more than the maximum allowed" do
37
+ expect{bot.move 5}.should change(bot, :location).
38
+ from({x: 0.0, y: 0.0}).
39
+ to({x: 0.0, y: 1.0})
40
+ end
41
+
42
+ it "should not move into walls" do
43
+ bot = Brawl::BasicBot.new(
44
+ arena: arena,
45
+ location: {x: 0, y:99},
46
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 360}}
47
+ )
48
+ expect{bot.move}.should_not change(bot, :location)
49
+ end
50
+
51
+ it "should move in reverse" do
52
+ bot = Brawl::BasicBot.new(
53
+ arena: arena,
54
+ location: {x: 50, y:50},
55
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 360}}
56
+ )
57
+ expect{bot.move -1}.should change(bot, :location).
58
+ from({x: 50.0, y: 50.0}).
59
+ to({x: 50.0, y: 49.0})
60
+ end
61
+
62
+ it "should not move in reverse more than the maximum allowed" do
63
+ bot = Brawl::BasicBot.new(
64
+ arena: arena,
65
+ location: {x: 50, y:50},
66
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 360}}
67
+ )
68
+ expect{bot.move -5}.should change(bot, :location).
69
+ from({x: 50.0, y: 50.0}).
70
+ to({x: 50.0, y: 47.0})
71
+ end
72
+
73
+
74
+ end
75
+
76
+ context "when turning" do
77
+
78
+ context "and given an angle" do
79
+
80
+ it "should 'wrap-around' degrees given" do
81
+ expect{bot.turn to_angle: 390}.should change(bot, :heading).
82
+ from(0).
83
+ to(30)
84
+ end
85
+
86
+ it "should turn by negative degrees" do
87
+ expect{bot.turn to_angle: -90}.should change(bot, :heading).
88
+ from(0).
89
+ to(270)
90
+ end
91
+
92
+ it "should turn to a positive angle within its maximum turn rate" do
93
+ bot = Brawl::BasicBot.new(
94
+ arena: arena,
95
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 90}}
96
+ )
97
+ bot.turn to_angle: 40
98
+ expect{bot.turn to_angle: 320}.should change(bot, :heading).
99
+ from(40).
100
+ to(320)
101
+ end
102
+
103
+ it "should turn by negative degrees within its maximum turn rate" do
104
+ bot = Brawl::BasicBot.new(
105
+ arena: arena,
106
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 90}}
107
+ )
108
+ bot.turn to_angle: 40
109
+ expect{bot.turn to_angle: -40}.should change(bot, :heading).
110
+ from(40).
111
+ to(320)
112
+ end
113
+
114
+ it "should not turn more than its maximum turn rate" do
115
+ bot = Brawl::BasicBot.new(
116
+ arena: arena,
117
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 90}}
118
+ )
119
+ expect{bot.turn to_angle: 91}.should change(bot, :heading).
120
+ from(0).
121
+ to(90)
122
+ end
123
+
124
+ it "should not turn more than its maximum turn rate counter-clockwise" do
125
+ bot = Brawl::BasicBot.new(
126
+ arena: arena,
127
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 90}}
128
+ )
129
+ expect{bot.turn to_angle: -91}.should change(bot, :heading).
130
+ from(0).
131
+ to(270)
132
+ end
133
+
134
+
135
+ end
136
+
137
+ context "and given degrees" do
138
+
139
+ it "should turn to the angle specified" do
140
+ expect{bot.turn to_angle: 45}.should change(bot, :heading).
141
+ from(0).
142
+ to(45)
143
+ end
144
+
145
+ it "should turn in the direction specified" do
146
+ bot.turn to_angle: 45
147
+ expect{bot.turn by_degrees: 45}.should change(bot, :heading).
148
+ from(45).
149
+ to(90)
150
+ end
151
+
152
+ it "should convert heading 360 to 0" do
153
+ bot.turn to_angle: 359
154
+ expect{bot.turn by_degrees: 1}.should change(bot, :heading).
155
+ from(359).
156
+ to(0)
157
+ end
158
+
159
+ it "should 'wrap-around' degrees" do
160
+ bot.turn to_angle: 300
161
+ expect{bot.turn by_degrees: 90}.should change(bot, :heading).
162
+ from(300).
163
+ to(30)
164
+ end
165
+
166
+ it "should 'wrap-around' degrees larger than 360" do
167
+ expect{bot.turn by_degrees: 390}.should change(bot, :heading).
168
+ from(0).
169
+ to(30)
170
+ end
171
+
172
+ it "should turn using negative degrees" do
173
+ bot = Brawl::BasicBot.new(
174
+ arena: arena,
175
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 90}}
176
+ )
177
+
178
+ bot.turn to_angle: 20
179
+ expect{bot.turn by_degrees: -40}.should change(bot, :heading).
180
+ from(20).
181
+ to(340)
182
+ end
183
+
184
+ it "should not turn more than its maximum turn rate" do
185
+ bot = Brawl::BasicBot.new(
186
+ arena: arena,
187
+ parts: {Brawl::BasicMotor=>{move_max: 3, turn_max: 90}}
188
+ )
189
+ expect{bot.turn by_degrees: 91}.should change(bot, :heading).
190
+ from(0).
191
+ to(90)
192
+ end
193
+
194
+ end
195
+
196
+ context "and given a direction name" do
197
+
198
+ it "should turn left" do
199
+ expect{bot.turn :left}.should change(bot, :heading).
200
+ from(0).
201
+ to(270)
202
+ end
203
+
204
+ it "should turn right" do
205
+ expect{bot.turn :right}.should change(bot, :heading).
206
+ from(0).
207
+ to(90)
208
+ end
209
+
210
+ it "should turn around" do
211
+ expect{bot.turn :around}.should change(bot, :heading).
212
+ from(0).
213
+ to(180)
214
+ end
215
+
216
+ end
217
+
218
+ end
219
+
220
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brawl::BasicScanner do
4
+
5
+ let(:arena){Brawl::Arena.new(size: {width: 10, length: 10})}
6
+ let(:bot) do
7
+ Brawl::BasicBot.new(
8
+ arena: arena,
9
+ parts: {Brawl::BasicScanner=>{scan_max: 10, angle_max: 90}}
10
+ )
11
+ end
12
+
13
+ it "should set its maximum scan distance initialized" do
14
+ bot.scan_max.should == 10
15
+ end
16
+
17
+ it "should set its maximum scan angle initialized" do
18
+ bot.angle_max.should == 90
19
+ end
20
+
21
+ context "when scanning" do
22
+
23
+ it "should return an empty array of contacts if nothing is in range" do
24
+ bot = Brawl::BasicBot.new(
25
+ arena: arena,
26
+ location: {x: 5, y: 5},
27
+ parts: {Brawl::BasicScanner=>{scan_max: 1, angle_max: 90}}
28
+ )
29
+ bot.scan(direction: 0, angle: 1).should be_empty
30
+ end
31
+
32
+ it "should find walls if in range" do
33
+ bot = Brawl::BasicBot.new(
34
+ arena: arena,
35
+ location: {x: 5, y: 5},
36
+ parts: {Brawl::BasicScanner=>{scan_max: 5, angle_max: 180}}
37
+ )
38
+ bot.scan(direction: 0, angle: 1).should_not be_empty
39
+ end
40
+
41
+ it "should find enemies if in range" do
42
+ bot = Brawl::BasicBot.new(
43
+ arena: arena,
44
+ location: {x: 5, y: 5},
45
+ parts: {Brawl::BasicScanner=>{scan_max: 1, angle_max: 180}}
46
+ )
47
+ enemy = Brawl::BasicBot.new(
48
+ arena: arena,
49
+ location: {x: 5, y: 6},
50
+ parts: {Brawl::BasicScanner=>{scan_max: 1, angle_max: 180}}
51
+ )
52
+ scan = bot.scan(direction: 0, angle: 1)
53
+ scan.any?{|contact| contact[:id] = enemy.id}
54
+ end
55
+
56
+ it "should not find enemies if out of range" do
57
+ bot = Brawl::BasicBot.new(
58
+ arena: arena,
59
+ location: {x: 5, y: 5},
60
+ parts: {Brawl::BasicScanner=>{scan_max: 1, angle_max: 180}}
61
+ )
62
+ enemy = Brawl::BasicBot.new(
63
+ arena: arena,
64
+ location: {x: 5, y: 7},
65
+ parts: {Brawl::BasicScanner=>{scan_max: 1, angle_max: 180}}
66
+ )
67
+ bot.scan(direction: 0, angle: 1).should be_empty
68
+ end
69
+
70
+ it "should find enemies to the side with a wide scan" do
71
+ bot = Brawl::BasicBot.new(
72
+ arena: arena,
73
+ location: {x: 5, y: 5},
74
+ parts: {Brawl::BasicScanner=>{scan_max: 3, angle_max: 180}}
75
+ )
76
+ enemy = Brawl::BasicBot.new(
77
+ arena: arena,
78
+ location: {x: 5, y: 7},
79
+ parts: {Brawl::BasicScanner=>{scan_max: 10, angle_max: 180}}
80
+ )
81
+ scan = bot.scan(direction: 0, angle: 180)
82
+ scan.any?{|contact| contact[:id] = enemy.id}
83
+ end
84
+
85
+ it "should find enemies to the side with a wide scan" do
86
+ bot = Brawl::BasicBot.new(
87
+ arena: arena,
88
+ location: {x: 0, y: 0},
89
+ parts: {Brawl::BasicScanner=>{scan_max: 10, angle_max: 180}}
90
+ )
91
+ enemy = Brawl::BasicBot.new(
92
+ arena: arena,
93
+ location: {x: 7, y: 7},
94
+ parts: {Brawl::BasicScanner=>{scan_max: 10, angle_max: 180}}
95
+ )
96
+ scan = bot.scan(direction: 0, angle: 180)
97
+ scan.any?{|contact| contact[:id] = enemy.id}
98
+ end
99
+ end
100
+
101
+ end