Class: RobotRunner

Inherits:
Object
  • Object
show all
Defined in:
lib/rrobots/robot_runner.rb

Constant Summary collapse

STATE_IVARS =
[ :x, :y, :gun_heat, :heading, :gun_heading, :radar_heading, :time, :size, :speed, :energy, :team ]
NUMERIC_ACTIONS =
[ :fire, :turn, :turn_gun, :turn_radar, :accelerate ]
STRING_ACTIONS =
[ :say, :broadcast ]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(robot, bf, team = 0) ⇒ RobotRunner

Returns a new instance of RobotRunner.



31
32
33
34
35
36
37
38
39
# File 'lib/rrobots/robot_runner.rb', line 31

def initialize robot, bf, team=0
  @robot = robot
  @battlefield = bf
  @team = team
  set_action_limits
  set_initial_state
  @events = Hash.new{|h, k| h[k]=[]}
  @actions = Hash.new(0)
end

Instance Attribute Details

#actionsObject (readonly)

Returns the value of attribute actions.



29
30
31
# File 'lib/rrobots/robot_runner.rb', line 29

def actions
  @actions
end

#damage_givenObject

keeps track of total damage done by this robot



24
25
26
# File 'lib/rrobots/robot_runner.rb', line 24

def damage_given
  @damage_given
end

#killsObject

keeps track of the kills



27
28
29
# File 'lib/rrobots/robot_runner.rb', line 27

def kills
  @kills
end

#robotObject

AI of this robot



18
19
20
# File 'lib/rrobots/robot_runner.rb', line 18

def robot
  @robot
end

#speechObject (readonly)

Returns the value of attribute speech.



29
30
31
# File 'lib/rrobots/robot_runner.rb', line 29

def speech
  @speech
end

#teamObject

team of this robot



21
22
23
# File 'lib/rrobots/robot_runner.rb', line 21

def team
  @team
end

Instance Method Details

#broadcastObject



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/rrobots/robot_runner.rb', line 213

def broadcast
  @battlefield.robots.each do |other|
    if (other != self) && (!other.dead)
      msg = other.actions[:broadcast]
      if msg != 0
        a = Math.atan2(@y - other.y, other.x - @x) / Math::PI * 180 % 360
        dir = 'east'
        dir = 'north' if a.between? 45,135
        dir = 'west' if a.between? 135,225
        dir = 'south' if a.between? 225,315
        @events['broadcasts'] << [msg, dir]
      end
    end
  end
end

#clamp(var, min, max) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/rrobots/robot_runner.rb', line 90

def clamp(var, min, max)
  val = 0 + var # to guard against poisoned vars
  if val > max
    max
  elsif val < min
    min
  else
    val
  end
end

#deadObject



86
87
88
# File 'lib/rrobots/robot_runner.rb', line 86

def dead
  @energy < 0
end

#fireObject



154
155
156
157
158
159
160
161
162
163
# File 'lib/rrobots/robot_runner.rb', line 154

def fire
  if (@actions[:fire] > 0) && (@gun_heat == 0)
    bullet = Bullet.new(@battlefield, @x, @y, @gun_heading, 30, @actions[:fire]*3.0, self)
    3.times{bullet.tick}
    @battlefield << bullet
    @gun_heat = @actions[:fire]
  end
  @gun_heat -= 0.1
  @gun_heat = 0 if @gun_heat < 0
end

#hit(bullet) ⇒ Object



79
80
81
82
83
84
# File 'lib/rrobots/robot_runner.rb', line 79

def hit bullet
  damage = bullet.energy
  @energy -= damage
  @events['got_hit'] << [@energy]
  damage
end

#internal_tickObject



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rrobots/robot_runner.rb', line 101

def internal_tick
  update_state
  robot_tick
  parse_actions
  fire
  turn
  move
  scan
  speak
  broadcast
  @time += 1
end

#moveObject



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/rrobots/robot_runner.rb', line 177

def move
  @speed += @actions[:accelerate]
  @speed = 8 if @speed > 8
  @speed = -8 if @speed < -8

  @x += Math::cos(@heading.to_rad) * @speed
  @y -= Math::sin(@heading.to_rad) * @speed

  @x = @size if @x - @size < 0
  @y = @size if @y - @size < 0
  @x = @battlefield.width - @size if @x + @size >= @battlefield.width
  @y = @battlefield.height - @size if @y + @size >= @battlefield.height
end

#nameObject



233
234
235
# File 'lib/rrobots/robot_runner.rb', line 233

def name
  @robot.class.name
end

#parse_actionsObject



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/rrobots/robot_runner.rb', line 114

def parse_actions
  @actions.clear
  NUMERIC_ACTIONS.each{|an|
    @actions[an] = clamp(@robot.actions[an], send("#{an}_min"), send("#{an}_max"))
  }
  STRING_ACTIONS.each{|an|
    if @robot.actions[an] != 0
      @actions[an] = String(@robot.actions[an])[0, send("#{an}_max")]
    end
  }
  @actions
end

#robot_tickObject



149
150
151
152
# File 'lib/rrobots/robot_runner.rb', line 149

def robot_tick
  @robot.tick @robot.events
  @events.clear
end

#scanObject



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/rrobots/robot_runner.rb', line 191

def scan
  @battlefield.robots.each do |other|
    if (other != self) && (!other.dead)
      a = Math.atan2(@y - other.y, other.x - @x) / Math::PI * 180 % 360
      if (@old_radar_heading <= a && a <= @new_radar_heading) || (@old_radar_heading >= a && a >= @new_radar_heading) ||
        (@old_radar_heading <= a+360 && a+360 <= @new_radar_heading) || (@old_radar_heading >= a+360 && a+360 >= new_radar_heading) ||
        (@old_radar_heading <= a-360 && a-360 <= @new_radar_heading) || (@old_radar_heading >= a-360 && a-360 >= @new_radar_heading)
         @events['robot_scanned'] << [Math.hypot(@y - other.y, other.x - @x)]
      end
    end
  end
end

#set_action_limitsObject



68
69
70
71
72
73
74
75
76
77
# File 'lib/rrobots/robot_runner.rb', line 68

def set_action_limits
  @fire_min, @fire_max = 0, 3
  @turn_min, @turn_max = -10, 10
  @turn_gun_min, @turn_gun_max = -30, 30
  @turn_radar_min, @turn_radar_max = -60, 60
  @accelerate_min, @accelerate_max = -1, 1
  @teleport_min, @teleport_max = 0, 100
  @say_max = 256
  @broadcast_max = 16
end

#set_initial_stateObject



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rrobots/robot_runner.rb', line 45

def set_initial_state
  @x = @battlefield.width / 2
  @y = @battlefield.height / 2
  @speech_counter = -1
  @speech = nil
  @time = 0
  @size = 60
  @speed = 0
  @energy = 100
  @damage_given = 0
  @kills = 0
  teleport
end

#skin_prefixObject



41
42
43
# File 'lib/rrobots/robot_runner.rb', line 41

def skin_prefix
  @robot.skin_prefix
end

#speakObject



204
205
206
207
208
209
210
211
# File 'lib/rrobots/robot_runner.rb', line 204

def speak
  if @actions[:say] != 0
    @speech = @actions[:say]
    @speech_counter = 50
  elsif @speech and (@speech_counter -= 1) < 0
    @speech = nil
  end
end

#stateObject



127
128
129
130
131
132
133
134
135
136
# File 'lib/rrobots/robot_runner.rb', line 127

def state
  current_state = {}
  STATE_IVARS.each{|iv|
    current_state[iv] = send(iv)
  }
  current_state[:battlefield_width] = @battlefield.width
  current_state[:battlefield_height] = @battlefield.height
  current_state[:game_over] = @battlefield.game_over
  current_state
end

#teleport(distance_x = @battlefield.width / 2, distance_y = @battlefield.height / 2) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/rrobots/robot_runner.rb', line 59

def teleport(distance_x=@battlefield.width / 2, distance_y=@battlefield.height / 2)
  @x += ((rand-0.5) * 2 * distance_x).to_i
  @y += ((rand-0.5) * 2 * distance_y).to_i
  @gun_heat = 3
  @heading = (rand * 360).to_i
  @gun_heading = @heading
  @radar_heading = @heading
end

#to_sObject



229
230
231
# File 'lib/rrobots/robot_runner.rb', line 229

def to_s
  @robot.class.name
end

#turnObject



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/rrobots/robot_runner.rb', line 165

def turn
  @old_radar_heading = @radar_heading
  @heading += @actions[:turn]
  @gun_heading += (@actions[:turn] + @actions[:turn_gun])
  @radar_heading += (@actions[:turn] + @actions[:turn_gun] + @actions[:turn_radar])
  @new_radar_heading = @radar_heading

  @heading %= 360
  @gun_heading %= 360
  @radar_heading %= 360
end

#update_stateObject



138
139
140
141
142
143
144
145
146
147
# File 'lib/rrobots/robot_runner.rb', line 138

def update_state
  new_state = state
  @robot.state = new_state
  new_state.each{|k,v|
    @robot.send("#{k}=", v)
  }
  @robot.events = @events.dup
  @robot.actions ||= Hash.new(0)
  @robot.actions.clear
end