def __init__(self, bzrc): self.bzrc = bzrc self.constants = self.bzrc.get_constants() self.commands = [] self.my_tanks = [] self.other_tanks = [] self.flags = [] self.shots = [] self.enemies = [] self.angle_diffs_by_tank = {} self.track_enemy_strategy = MasterFieldGen(bzrc, [(TrackEnemyFieldGen(bzrc))]) self.last_time_diff = 0 self.k_p = 0.1 self.k_d = 0.5
class Agent(object): """Class handles all command and control logic for a teams tanks.""" def __init__(self, bzrc): self.bzrc = bzrc self.constants = self.bzrc.get_constants() self.commands = [] self.my_tanks = [] self.other_tanks = [] self.flags = [] self.shots = [] self.enemies = [] self.angle_diffs_by_tank = {} self.track_enemy_strategy = MasterFieldGen(bzrc, [(TrackEnemyFieldGen(bzrc))]) self.last_time_diff = 0 self.k_p = 0.1 self.k_d = 0.5 def tick(self, time_diff): """Some time has passed; decide what to do next.""" # clear the commands self.commands = [] # calculate the time differential d_t = time_diff - self.last_time_diff # save the current time_diff for next time (no pun intended) self.last_time_diff = time_diff for tank in self.bzrc.get_mytanks(): if tank.status.startswith('alive'): # and tank.index == 0: self.direct_tank(tank, d_t) self.bzrc.do_commands(self.commands) def direct_tank(self, tank, time_diff): # get vector(s) for the potential fields around the tank (this is the vector I want the tank to have) field_vector, shoot = self.get_field_vector(tank) # print "vector to target: %s" % field_vector # print "vector to target angle: %s" % math.degrees(field_vector.angle) # get the tank's current velocity vector # tank_vector = Vec2d(tank.vx, tank.vy) # if tank_vector[0] == 0 and tank_vector[1] == 0: # tank_vector[0] = 1 # tank_vector.angle = math.degrees(tank.angle) # print "my angle: %s" % math.degrees(tank.angle) # get the angle between the desired and current vectors angle_diff = self.normalize_angle(field_vector.angle - tank.angle) # angle_diff = field_vector.angle - tank.angle # print "angle diff: %s" % math.degrees(angle_diff) # if tank.callsign in self.angle_diffs_by_tank: # last_angle_diff = self.angle_diffs_by_tank[tank.callsign] # else: # last_angle_diff = angle_diff # self.angle_diffs_by_tank[tank.callsign] = angle_diff # d_e = (angle_diff - last_angle_diff) / (time_diff if time_diff != 0 else 0.01) # angvel = (self.k_p * angle_diff) + (self.k_d * d_e) # for Kalman lab, the agent can only rotate, so keep velocity at 0 self.commands.append(Command(tank.index, 0, angle_diff, abs(angle_diff) < math.radians(3.0))) def get_field_vector(self, tank): return self.track_enemy_strategy.vector_at(tank.x, tank.y) @staticmethod def normalize_angle(angle): """Make any angle be between +/- pi.""" angle -= 2 * math.pi * int(angle / (2 * math.pi)) if angle <= -math.pi: angle += 2 * math.pi elif angle > math.pi: angle -= 2 * math.pi return angle