def get_unit_visibility(unit): tiles_in_view = [unit.coordinate] west_to_east = [i for i in range(unit.coordinate.latitude - VISIBILITY_DISTANCE, unit.coordinate.latitude + VISIBILITY_DISTANCE+1)] south_to_north = [i for i in range(unit.coordinate.longitude - VISIBILITY_DISTANCE, unit.coordinate.longitude + VISIBILITY_DISTANCE+1)] for latitude, longitude in itertools.product(west_to_east, south_to_north): coordinate = Coordinate(latitude, longitude) if coord_in_arena(coord=coordinate, arena=unit.arena): tiles_in_view.append(coordinate) return tiles_in_view
def move(self, direction): """Move attacker into new valid position: # Direction must be one of ((0, 1), (0, -1), (1, 0), (-1, 0)) # New position must be part of the arena grid # New position must be occupied by other attack unit of same player, or empty @return: :dict: indicating the destination and end { 'from': <coord>, 'to': <coord>, } """ if not direction_is_valid(direction): return { 'from': self.coordinate, 'to': self.coordinate, 'error': 'Direction {} is invalid'.format(direction), } delta_x, delta_y = direction latitude = self.coordinate.latitude + delta_x longitude = self.coordinate.longitude + delta_y desired_coordinate = Coordinate(latitude, longitude) if not coord_in_arena(desired_coordinate, self.arena): return { 'from': self.coordinate, 'to': desired_coordinate, 'error': 'Invalid position ({}, {})'.format(latitude, longitude), } destination_tile = self.arena[desired_coordinate] if not destination_tile.reachable: return { 'from': self.coordinate, 'to': desired_coordinate, 'error': 'Blocked position ({}, {})'.format(latitude, longitude), } if destination_tile.hq_for(self.player_id) and not destination_tile.empty: return { 'from': self.coordinate, 'to': desired_coordinate, 'error': 'You can place only one unit on your base', } if not self.can_invade(destination_tile): return { 'from': self.coordinate, 'to': desired_coordinate, 'error': 'All occupiers must be of the same team', } # Move from current position to next one self.arena.move(self, self.coordinate, desired_coordinate) origin = self.coordinate self.coordinate = desired_coordinate return { 'from': origin, 'to': self.coordinate, 'error': '', }
def _tiles_in_arena(self, tiles, arena): if not all(coord_in_arena(t, arena) for t in tiles): raise RuntimeError("Invalid coordinates")