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.
- data/.gitignore +1 -0
- data/.rspec +0 -0
- data/README.md +43 -0
- data/_design/ClassDescriptions.txt +98 -0
- data/_design/Psudo_Program.rb +113 -0
- data/_design/array.rb +4 -0
- data/_design/threads.rb +71 -0
- data/_spike/Communications/communications.rb +2 -0
- data/_spike/Communications/lib/communications/com_linker.rb +11 -0
- data/_spike/Communications/lib/communications/null_modem.rb +11 -0
- data/_spike/Communications/spec/communications/com_linker_spec.rb +37 -0
- data/_spike/DRb/arena.rb +32 -0
- data/_spike/DRb/battle_controller.rb +54 -0
- data/_spike/DRb/bot.rb +23 -0
- data/_spike/DRb/bot_runner.rb +110 -0
- data/_spike/DRb/comment.txt +11 -0
- data/_spike/DRb/server.rb +28 -0
- data/_spike/DRb/test_bot.rb +6 -0
- data/_spike/array.rb +7 -0
- data/_spike/atan2.rb +39 -0
- data/_spike/battle.rb +202 -0
- data/_spike/break.rb +10 -0
- data/_spike/circles.rb +29 -0
- data/_spike/cleaner_attribs.rb +13 -0
- data/_spike/comlink.rb +61 -0
- data/_spike/concat.rb +27 -0
- data/_spike/example_bot.rb +42 -0
- data/_spike/forwarding_instance.rb +32 -0
- data/_spike/hash_loop.rb +17 -0
- data/_spike/hashing.rb +7 -0
- data/_spike/hook.rb +19 -0
- data/_spike/mod.rb +10 -0
- data/_spike/point_in_cone.rb +20 -0
- data/_spike/runner.rb +44 -0
- data/_spike/safe.rb +28 -0
- data/brawl.gemspec +4 -3
- data/example/example_battle.rb +173 -0
- data/example/logview.txt +6394 -0
- data/lib/brawl.rb +14 -3
- data/lib/brawl/_helper.rb +65 -0
- data/lib/brawl/arena.rb +118 -0
- data/lib/brawl/basic_arena_object.rb +35 -0
- data/lib/brawl/basic_bot.rb +69 -0
- data/lib/brawl/battle_controller.rb +97 -0
- data/lib/brawl/bot_proxy.rb +60 -0
- data/lib/brawl/clock.rb +36 -0
- data/lib/brawl/parts.rb +3 -0
- data/lib/brawl/parts/basic_motor.rb +55 -0
- data/lib/brawl/parts/basic_scanner.rb +33 -0
- data/lib/brawl/parts/basic_weapon.rb +47 -0
- data/lib/brawl/version.rb +1 -1
- data/lib/brawl/wall.rb +9 -0
- data/spec/brawl/arena_spec.rb +163 -0
- data/spec/brawl/basic_arena_object_spec.rb +40 -0
- data/spec/brawl/basic_bot_spec.rb +84 -0
- data/spec/brawl/battle_controller_spec.rb +138 -0
- data/spec/brawl/clock_spec.rb +28 -0
- data/spec/brawl/helper_spec.rb +23 -0
- data/spec/brawl/parts/basic_motor_spec.rb +220 -0
- data/spec/brawl/parts/basic_scanner_spec.rb +101 -0
- data/spec/brawl/parts/basic_weapon_spec.rb +146 -0
- data/spec/spec_helper.rb +5 -0
- metadata +101 -10
data/_spike/break.rb
ADDED
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
|
data/_spike/hash_loop.rb
ADDED
@@ -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
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,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
|
12
|
-
s.description = %q{
|
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.
|
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
|