brawl 0.0.0.alpha → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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