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