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
data/_spike/break.rb ADDED
@@ -0,0 +1,10 @@
1
+
2
+ def foo(stop_at)
3
+ (0...100).each do |index|
4
+ break index if index == stop_at
5
+ end
6
+
7
+ end
8
+
9
+
10
+ puts foo(20)
data/_spike/circles.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "bigdecimal"
2
+ require "bigdecimal/math"
3
+
4
+ include BigMath
5
+
6
+ def to_radians(angle)
7
+ big_angle = BigDecimal(angle.to_s)
8
+ big_angle * (PI(100) / 180.0)
9
+ end
10
+
11
+ def to_degree(angle)
12
+ big_angle = BigDecimal(angle.to_s)
13
+ big_angle * (180.0 / PI(100))
14
+ end
15
+
16
+
17
+ angle = -320
18
+ puts "angle: #{angle}"
19
+ radians = to_radians angle
20
+ sin = Math.sin(radians).abs
21
+ puts "rad: #{radians}"
22
+ puts "sin: #{sin}"
23
+ asin = Math.asin(sin)
24
+ puts "asin: #{asin}"
25
+ wrap_angle = to_degree asin
26
+ puts "wrap: #{wrap_angle.round}"
27
+ # radian90 = to radian: 90
28
+ # puts "90 degrees to radian: #{radian90}"
29
+ # puts "90 radians to degrees: #{to degree: radian90}"
@@ -0,0 +1,13 @@
1
+ class Foo
2
+ attr_accessor :bar
3
+ def initialize(args={})
4
+ args.each do |key, value|
5
+ instance_variable_set("@#{key}", value) if public_methods(false).include? key
6
+ end
7
+ end
8
+ end
9
+
10
+ puts Foo.instance_methods(false)
11
+
12
+ f = Foo.new(bar: "foo!")
13
+ puts f.bar
data/_spike/comlink.rb ADDED
@@ -0,0 +1,61 @@
1
+ class Foo
2
+ def bar(value)
3
+ "doh!"
4
+ end
5
+ def baz(value1, value2)
6
+ "Oh, noos!"
7
+ end
8
+ def qux
9
+ "Fudge!"
10
+ end
11
+ def quux(value1, value2, &block)
12
+ "Nope, nope, nope"
13
+ end
14
+ end
15
+
16
+ class FooProxy
17
+ def bar(value)
18
+ "#{value}"
19
+ end
20
+ def baz(value1, value2)
21
+ "#{value1}, #{value2}"
22
+ end
23
+ def qux
24
+ yield "FooProxy"
25
+ end
26
+ def quux(value1, value2, &block)
27
+ yield ["FooProxy", "#{value1}, #{value2}"]
28
+ end
29
+ end
30
+
31
+ class NullModem
32
+ def link_method(client, server, method)
33
+ client.class.send :define_method, method do |*params, &block|
34
+ server.send method, *params, &block
35
+ end
36
+ end
37
+ end
38
+
39
+ class ComLinker
40
+ def self.link(comlayer, client, server)
41
+ client.public_methods(false).each do |method|
42
+ comlayer.link_method(client, server, method)
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ foo = Foo.new
49
+ proxy = FooProxy.new
50
+ comlayer = NullModem.new
51
+
52
+ ComLinker.link(comlayer, foo, proxy)
53
+
54
+ puts foo.bar("hello!")
55
+ puts foo.baz("howdy", "ho")
56
+ puts foo.qux {|value| value}
57
+ puts (foo.quux("look", "at this") {|value| value}).inspect
58
+
59
+
60
+
61
+
data/_spike/concat.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'benchmark'
2
+
3
+ x = [1,2,3]
4
+ puts x.object_id
5
+
6
+ x.concat [4,5] # same object
7
+ puts x.object_id
8
+
9
+ x += [6,7] # different object
10
+ puts x.object_id
11
+
12
+
13
+ Benchmark.bmbm do |bm|
14
+ x = ("X"*100).split("")
15
+ y = ("Y"*100).split("")
16
+ times = 1000
17
+
18
+ bm.report{times.times {x.concat y}}
19
+ bm.report{times.times {x += y}} # substantially slower
20
+
21
+ end
22
+
23
+ =begin
24
+ user system total real
25
+ 0.000000 0.000000 0.000000 ( 0.001476)
26
+ 2.950000 2.140000 5.090000 ( 6.061063)
27
+ =end
@@ -0,0 +1,42 @@
1
+ class BasicBot
2
+
3
+ end
4
+
5
+ # this isn't meant to be a good bot, just to show the features of bots
6
+ code.loop do |bot|
7
+
8
+ scan_results = bot.scan direction: 0, angle: 45
9
+
10
+ unless (enemies = scan_results.contacts.select
11
+ {|contact| contact.type == :enemy}).empty?
12
+
13
+ # you should get the closest probably, not just the first in the array
14
+ enemy = enemies.first
15
+
16
+ if enemy.distance <= bot.weapon.range do
17
+ bot.fire direction: enemy.direction
18
+ else
19
+ bot.turn direction: enemy.direction
20
+ bot.move
21
+ end
22
+
23
+ else
24
+
25
+ # No enemy spotted so move around randomly
26
+ # mostly go straight but turn randomly sometimes
27
+ unless rand(100) > 70 and scan_result.any?
28
+ {|contact| contact.direction == :front && contact.distance == 1}
29
+ bot.move direction: :forward
30
+ else
31
+ [:right, :left].sample do |direction|
32
+ # if the enemy gets right behind you, you could go into an endless loop
33
+ bot.turn direction until
34
+ (bot.scan direction: 0, angle: 0).contacts.empty
35
+
36
+ bot.move
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,32 @@
1
+ require 'forwardable'
2
+
3
+ class Bar
4
+ def baz
5
+ puts "baz!"
6
+ end
7
+ end
8
+
9
+ class Foo
10
+ extend Forwardable
11
+
12
+ attr_accessor :parts
13
+
14
+ def initialize(args)
15
+
16
+ @parts = args[:parts]
17
+
18
+ @parts.each do |part, instance|
19
+ instance_variable_set("@#{part}", instance)
20
+ self.class.def_delegators "@#{part}", *(instance.public_methods(false))
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+
27
+
28
+ f = Foo.new(parts: {bar: Bar.new})
29
+ puts f.public_methods(false)
30
+ puts
31
+ puts f.instance_variables
32
+ f.baz
@@ -0,0 +1,17 @@
1
+ x = [{a: "a"}, {b: "b"}, {c: "c"}]
2
+
3
+ class Hash
4
+ def each_hash
5
+ self.each_pair do |key, value|
6
+ yield key => value
7
+ end
8
+ end
9
+ end
10
+
11
+ def foo(hashes)
12
+ hashes.each_hash do |hash|
13
+ puts hash.inspect
14
+ end
15
+ end
16
+
17
+ foo(a: "a", b: "b", c: "c")
data/_spike/hashing.rb ADDED
@@ -0,0 +1,7 @@
1
+ x = [:a, :b, :c, :d, :e]
2
+
3
+ y = x.each_with_object({}) do |key, hash|
4
+ hash[key] = key.to_s.ord
5
+ end
6
+
7
+ puts y
data/_spike/hook.rb ADDED
@@ -0,0 +1,19 @@
1
+ class Foo
2
+
3
+ def initialize
4
+ singleton_class.send :alias_method, :__hook__, :bar
5
+ singleton_class.send :define_method, :bar do |*params|
6
+ puts "no mo ba"
7
+ send :__hook__
8
+ end
9
+ end
10
+
11
+ def bar
12
+ puts "bar"
13
+ end
14
+
15
+ end
16
+
17
+ f = Foo.new
18
+
19
+ f.bar
data/_spike/mod.rb ADDED
@@ -0,0 +1,10 @@
1
+ def foo
2
+
3
+ class Doo
4
+ def something
5
+ puts "somthing"
6
+ end
7
+ end
8
+
9
+ end
10
+
@@ -0,0 +1,20 @@
1
+
2
+ def point_in_cone(args)
3
+ radius, angle, direction, bot, target = args[:radius], args[:angle], args[:direction], args[:bot], args[:target]
4
+ x1, y1, x2, y2 = bot[:x], bot[:y], target[:x], target[:y]
5
+ distance = Math.sqrt((x1 - target[:x])**2 + (y1 - y2)**2)
6
+ return false if distance > radius
7
+
8
+ azimuth = Math.atan2(x2 - x1, y2 - y1)
9
+
10
+ min = (Math::PI / 180) * ((direction - (angle / 2)) % 360)
11
+ max = (Math::PI / 180) * ((direction + (angle / 2)) % 360)
12
+
13
+ if min > max
14
+ azimuth >= min || azimuth <= max
15
+ else
16
+ azimuth >= min && azimuth <= max
17
+ end
18
+ end
19
+
20
+ puts point_in_cone radius: 10, angle: 90, direction: 0, bot: {x: 0, y: 0}, target: {x: 10, y: 0}
data/_spike/runner.rb ADDED
@@ -0,0 +1,44 @@
1
+ class Arena
2
+ def initialize
3
+ @secret = "super secret"
4
+ end
5
+
6
+ def protected
7
+ puts "protected called"
8
+ end
9
+
10
+ end
11
+
12
+ class ArenaProxy
13
+ def initialize(arena)
14
+ @arena = arena
15
+ end
16
+ end
17
+
18
+ class BasicBot
19
+ def initialize(arena_proxy)
20
+ @arena_proxy = arena_proxy
21
+ end
22
+ end
23
+
24
+ class Code
25
+ def self.loop
26
+ arena = Arena.new
27
+ ap = ArenaProxy.new(arena)
28
+ bot = BasicBot.new(ap)
29
+ yield bot
30
+ end
31
+ end
32
+
33
+ module Runner
34
+ secret = ""
35
+ Thread.start {
36
+ $SAFE = 4
37
+ Code.loop do |bot|
38
+ ap = bot.instance_variable_get(:@arena_proxy)
39
+ a = ap.instance_variable_get(:@arena)
40
+ secret = a.instance_variable_get(:@secret)
41
+ end
42
+ }.join
43
+ puts secret
44
+ end
data/_spike/safe.rb ADDED
@@ -0,0 +1,28 @@
1
+ class Bar
2
+ def private_parts
3
+ "huge"
4
+ end
5
+ end
6
+
7
+ class Foo
8
+ def initialize
9
+ @bar = Bar.new
10
+ @secret = ["secret"]
11
+ end
12
+
13
+ end
14
+
15
+ f = Foo.new
16
+ vars = []
17
+ vars.taint
18
+ Thread.start {
19
+ $SAFE = 3
20
+ bar = Bar.new
21
+ f.instance_variable_set :@secret, "hahahaha"
22
+ vars = f.instance_variable_get(:@secret)
23
+ bar = f.instance_variable_get(:@bar)
24
+ vars << "#{vars}, #{bar.private_parts}"
25
+ }.join
26
+
27
+ puts "vars: #{vars}"
28
+ puts "Done"
data/brawl.gemspec CHANGED
@@ -8,10 +8,11 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["Mike Bethany"]
9
9
  s.email = ["mikbe.tk@gmail.com"]
10
10
  s.homepage = "http://mikbe.tk"
11
- s.summary = %q{A work in progress}
12
- s.description = %q{nothing to see here, move along}
11
+ s.summary = %q{A robot combat game where you write Ruby programs to control your robots.}
12
+ s.description = %q{Write robotic assassins using Ruby and watch them as they do your evil bidding.}
13
13
 
14
- s.rubyforge_project = "brawl"
14
+ s.add_dependency "uuidtools"
15
+ s.add_dependency "eventable"
15
16
 
16
17
  s.files = `git ls-files`.split("\n")
17
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,173 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "/../lib"))
2
+ $: << '.'
3
+
4
+ require 'brawl'
5
+
6
+ battle_bot_code = <<CODE
7
+ code do |bot|
8
+ @dir ||= 0
9
+ targets = bot.scan direction: @dir, angle: 90
10
+ @dir += 45
11
+ @dir %= 360
12
+ unless targets.each do |target|
13
+ unless target[:class] == Brawl::Wall
14
+ results = shoot(target[:bearing])
15
+ end
16
+ end.empty?
17
+ else
18
+ if rand(0) > 0.5
19
+ bot.turn [:left,:right,:around].sample
20
+ end
21
+ bot.move rand(3) + 1
22
+ end
23
+ end
24
+ CODE
25
+
26
+ arena_data = {size: {width: 10, length: 10}}
27
+ clock_data = {tick_rate: 0.01}
28
+
29
+ motor = {Brawl::BasicMotor=>{move_max: 3, turn_max: 360}}
30
+ scanner = {Brawl::BasicScanner=>{scan_max: 10, angle_max: 180}}
31
+ weapon = {Brawl::BasicWeapon=>{range: 11, power: 1}}
32
+ parts = motor.merge(scanner).merge(weapon)
33
+
34
+ battle_bot1 =
35
+ {
36
+ name: "Battle Bot 1",
37
+ class: Brawl::BasicBot,
38
+ params: {parts: parts},
39
+ code: battle_bot_code
40
+ }
41
+
42
+ battle_bot2 =
43
+ {
44
+ name: "Battle Bot 2",
45
+ class: Brawl::BasicBot,
46
+ params: {parts: parts},
47
+ code: battle_bot_code
48
+ }
49
+
50
+ battle_bot3 =
51
+ {
52
+ name: "Battle Bot 3",
53
+ class: Brawl::BasicBot,
54
+ params: {parts: parts},
55
+ code: battle_bot_code
56
+ }
57
+
58
+ battle_bot4 =
59
+ {
60
+ name: "Battle Bot 4",
61
+ class: Brawl::BasicBot,
62
+ params: {parts: parts},
63
+ code: battle_bot_code
64
+ }
65
+
66
+ class LogView
67
+
68
+ def initialize(logfile)
69
+ @logfile = logfile
70
+ @file = nil
71
+ @verbosity_throttle = 0
72
+ @verbosity_level = 25
73
+ end
74
+
75
+ def open
76
+ @file = File.open(@logfile, "w")
77
+ end
78
+
79
+ def close
80
+ @file.flush
81
+ @file.close
82
+ end
83
+
84
+ def write(msg="")
85
+ @file.puts msg
86
+ end
87
+
88
+ def bot_msg_callback(*params)
89
+
90
+ bot_info = params[0]
91
+ method = params[1]
92
+ method_params = params[2]
93
+ @verbosity_throttle += 1
94
+
95
+ case method
96
+ when :damage
97
+ text = "#{bot_info[:name]}" +
98
+ " at #{bot_info[:location]}" +
99
+ " was hit for #{method_params} damage" +
100
+ " and now has #{bot_info[:health]} health."
101
+ text += " #{bot_info[:name]} is dead!" if bot_info[:health] == 0
102
+ @file.puts
103
+ @file.puts text
104
+ puts
105
+ puts text
106
+ when :scan
107
+ text = "#{bot_info[:name]}" +
108
+ " at #{bot_info[:location]}" +
109
+ " scans #{method_params}"
110
+ @file.puts
111
+ @file.puts text
112
+ if speak?
113
+ puts
114
+ puts text
115
+ end
116
+ when :move
117
+ text = "#{bot_info[:name]}" +
118
+ " at #{bot_info[:location]}" +
119
+ " moves #{method_params}"
120
+ @file.puts
121
+ @file.puts text
122
+ if speak?
123
+ puts
124
+ puts text
125
+ end
126
+ when :shoot
127
+ text = "#{bot_info[:name]}" +
128
+ " at #{bot_info[:location]}" +
129
+ " shoots at bearing #{method_params.round(1)}."
130
+ @file.puts
131
+ @file.puts text
132
+ puts
133
+ puts text
134
+ end
135
+ end
136
+
137
+ def speak?
138
+ @verbosity_throttle % @verbosity_level == 0
139
+ end
140
+
141
+ end
142
+
143
+ battle = Brawl::BattleController.new
144
+ battle.make_arena(arena_data)
145
+ battle.make_clock(clock_data)
146
+
147
+ bot_data = [battle_bot1, battle_bot2, battle_bot3, battle_bot4]
148
+ battle.make_bots(bot_data)
149
+ log = LogView.new("logview.txt")
150
+ log.open
151
+ battle.register_for_event(
152
+ event: :bot_msg,
153
+ listener: log,
154
+ callback: :bot_msg_callback
155
+ )
156
+
157
+ battle.start
158
+ until battle.victory?
159
+ sleep(0.5)
160
+ end
161
+
162
+ winner = battle.arena.get_object(class: Brawl::BasicBot)
163
+ if winner
164
+ done_text = "Battle won!\n#{winner[:name]} is the champion!"
165
+ else
166
+ done_text = "Battle draw! The last two bots killed other simultaniously! Doh!"
167
+ end
168
+
169
+ puts
170
+ puts done_text
171
+ log.write
172
+ log.write done_text
173
+ log.close