Skip to content

Instantly share code, notes, and snippets.

@lexun
Last active December 20, 2015 12:09
Show Gist options
  • Save lexun/6128498 to your computer and use it in GitHub Desktop.
Save lexun/6128498 to your computer and use it in GitHub Desktop.
class Lexun < RTanque::Bot::Brain
NAME = 'Lexun'
include RTanque::Bot::BrainHelper
Wall = Struct.new :name, :axis, :position, :opposite
def tick!
@tick = @tick.to_i.succ
setup if @tick == 1
manage_movement
manage_aggression
end
def setup
north_wall = Wall.new 'north_wall', 'y', self.arena.height, RTanque::Heading::S
east_wall = Wall.new 'east_wall', 'x', self.arena.width, RTanque::Heading::W
south_wall = Wall.new 'south_wall', 'y', 0, RTanque::Heading::N
west_wall = Wall.new 'west_wall', 'x', 0, RTanque::Heading::E
@walls = north_wall, east_wall, south_wall, west_wall
end
def manage_movement
command.heading = desired_heading
command.speed = desired_speed
return if transitioning?
@desired_speed = MAX_BOT_SPEED
avoid_walls if near_wall?
evade_attacker if taking_damage?
end
def manage_aggression
if sensors.radar.any?
if lock_on_target
command.fire MAX_FIRE_POWER
end
else
radar_scan
end
end
def lock_on_target
if sensors.radar.none?
radar_scan
else
@target = sensors.radar.first.name != NAME ? sensors.radar.first : sensors.radar.to_a.last
command.turret_heading = @target.heading
command.radar_heading = @target.heading
@target.heading.delta(sensors.turret_heading).abs < RTanque::Heading::ONE_DEGREE * 5.0
end
end
def radar_scan
command.radar_heading = sensors.radar_heading + MAX_RADAR_ROTATION
end
def avoid_walls
@desired_heading = @nearby_walls[0].opposite + (rand(1..2) -1) * RTanque::Heading::EIGHTH_ANGLE
transition 140
end
def evade_attacker
maneuver = rand(1..4) > 1 ? 2 : 1
case maneuver
when 1
@desired_speed = -2
transition 100
when 2
@desired_heading = sensors.heading + RTanque::Heading::rand
transition 40
end
end
def taking_damage?
@health ||= sensors.health
sensors.health < @health ? @health = sensors.health : false
end
def near_wall?
@nearby_walls = []
discover_nearby_walls
@nearby_walls.any?
end
def discover_nearby_walls
@walls.each do |wall|
wall_position = wall.position
tank_position = sensors.position.send(wall.axis)
if distance_between(wall_position, tank_position) < 135
@nearby_walls << wall
end
end
@nearby_walls
end
def desired_heading
@desired_heading ||= RTanque::Heading::rand
end
def desired_speed
@desired_speed ||= MAX_BOT_SPEED
end
def transition(steps)
@transition_time = @tick + steps
end
def transitioning?
@transition_time ||= 0
@transition_time > @tick
end
def distance_between(x, y)
case x <=> y
when -1
y - x
when 0
0
when 1
x - y
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment