Skip to content

Instantly share code, notes, and snippets.

@neilmiddleton
Created March 31, 2015 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neilmiddleton/7909f1a361e6004c4cfe to your computer and use it in GitHub Desktop.
Save neilmiddleton/7909f1a361e6004c4cfe to your computer and use it in GitHub Desktop.
class DodgeitAndScarper < RTanque::Bot::Brain
NAME = 'dodgeit_and_scarper'
include RTanque::Bot::BrainHelper
RUN_AND_COVER = 80
def tick!
nearest = nearest_victim
command.speed = RTanque::Bot::MAX_SPEED
at_tick_interval(100) do
puts "Tick ##{sensors.ticks}!"
puts " Gun Energy: #{sensors.gun_energy}"
puts " Health: #{sensors.health}"
puts " Position: (#{sensors.position.x}, #{sensors.position.y})"
puts sensors.position.on_wall? ? " On Wall" : " Not on wall"
puts " Speed: #{sensors.speed}"
puts " Heading: #{sensors.heading.inspect}"
puts " Turret Heading: #{sensors.turret_heading.inspect}"
puts " Radar Heading: #{sensors.radar_heading.inspect}"
puts " Radar Reflections (#{sensors.radar.count}):"
sensors.radar.each do |reflection|
puts " #{reflection.name} #{reflection.heading.inspect} #{reflection.distance}"
end
end
if (!defined?(@direction))
@direction, @previousTargetY, @previousTargetX = 0, 0, 0
end
if (nearest)
# borrowed targeting code
targetX = sensors.position.x + Math.sin(nearest.heading) * nearest.distance
targetY = sensors.position.y + Math.cos(nearest.heading) * nearest.distance
power = RTanque::Bot::MAX_FIRE_POWER
predictedTargetX = targetX + (targetX - @previousTargetX) * nearest.distance / (5.0 * power)
predictedTargetY = targetY + (targetY - @previousTargetY) * nearest.distance / (5.0 * power)
deltaX = predictedTargetX - sensors.position.x
deltaY = predictedTargetY - sensors.position.y
tan = deltaX / deltaY
if (deltaX > 0 && deltaY > 0)
angle = Math.atan(tan)
elsif (deltaX > 0 && deltaY < 0)
angle = Math::PI - Math.atan(-tan)
elsif (deltaX < 0 && deltaY > 0)
angle = Math::PI * 2 - Math.atan(-tan)
elsif (deltaX < 0 && deltaY < 0)
angle = Math::PI + Math.atan(tan)
end
@previousTargetX, @predictedTargetY = targetX, targetY
command.radar_heading = nearest.heading
command.turret_heading = angle
command.fire power
else
command.radar_heading = sensors.radar_heading + RTanque::Heading::ONE_DEGREE * 10.0
end
# on wall logic
onWall = false
command.heading = if (sensors.position.on_top_wall?)
RTanque::Heading::SOUTH
elsif (sensors.position.on_bottom_wall?)
RTanque::Heading::NORTH
elsif (sensors.position.on_left_wall?)
RTanque::Heading::EAST
elsif (sensors.position.on_right_wall?)
RTanque::Heading::WEST
end
onWall = true if (sensors.position.on_top_wall? ||
sensors.position.on_bottom_wall? ||
sensors.position.on_left_wall? ||
sensors.position.on_right_wall?)
if (onWall)
# turn in a direction away from scary
if (sensors.heading.delta(command.heading) > 0)
@direction = 1
else
@direction = -1
end
else
# turn if on the right spaced tick
@direction = 0 - @direction if (Random.rand(RUN_AND_COVER) < 1)
command.heading = sensors.heading + @direction * RTanque::Heading::FULL_ANGLE/70
end
end
def target_position(position, heading, distance)
position + heading * distance
end
def delta(target, position)
target - position
end
def nearest_victim
sensors.radar.sort_by{|r| r.distance }[1]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment