Example #1
0
    def attack(self, robot_id):
        """
        Attacking is modelled on a Claymore. Damage is determined by the
        `inverse square`_ of the distance.


        .. _inverse square: http://en.wikipedia.org/wiki/Inverse-square_law
        """
        loop = asyncio.get_event_loop()
        now = loop.time()
        attacker = self._robots[robot_id]
        if (
            attacker['attacked_at'] is not None and
            (now - attacker['attacked_at']) * 1000 < settings['attack_interval']
        ):
            # Attacker must wait a second before firing
            logger.info('{robot} unable to attack yet'.format(robot=attacker['instance']))
            return
        attacker['attacked_at'] = now
        logger.info('{robot} attack'.format(robot=attacker['instance']))
        for target in self.active_robots():
            if is_in_angle(attacker['coords'],
                           attacker['heading'],
                           settings['attack_angle'],
                           target['coords']):
                dist = get_dist(attacker['coords'], target['coords'])
                dist = max(dist, 1)  # Make sure distance between robots is reasonable
                # Inverse square law. Drop values < 0
                damage = int(settings['attack_damage'] / dist ** 2)
                if damage:
                    logger.info('{robot} suffered {damage} damage'.format(
                        robot=target['instance'],
                        damage=damage))
                    target['damage'] += damage
                    target['instance'].attacked().send(attacker['instance'].__class__.__name__)
Example #2
0
 def radar_updated(self):
     """
     Stops when the robot is close to the middle
     """
     while True:
         _ = yield
         # Are we there yet?
         dist = get_dist(self.coords, self._get_middle())
         # TODO: Reduce speed as we approach
         if dist < 10:
             # Stop
             self.speed = 0
Example #3
0
    def _find_closest(self, radar, coords=None):
        """
        Find the closest other robot.

        Returns coordinates, distance.
        """
        if coords is None:
            coords = self.coords
        dist = closest = None
        for robot in radar:
            name = robot['name']
            if name == self.__class__.__name__:
                continue
            d = get_dist(coords, robot['coords'])
            if dist is None or d < dist:
                dist = d
                closest = robot['coords']
        return closest, dist