def execute_scans(players, subjects): # TODO: account for world wrapping for player in players: (radius,) = player.scan # TODO: subtract energy cost (and signal death if it proved fatal) for subject in subjects: # calculate distance to all subjects, signal detect if within scan distance = util.distance(player.location, subject.location) if distance <= radius: player.signal_detect( subject.name, util.angle(player.location, subject.location), distance, subject.energy )
def execute_scans(players, subjects): # TODO: account for world wrapping for player in players: (radius, ) = player.scan # TODO: subtract energy cost (and signal death if it proved fatal) for subject in subjects: # calculate distance to all subjects, signal detect if within scan distance = util.distance(player.location, subject.location) if distance <= radius: player.signal_detect( subject.name, util.angle(player.location, subject.location), distance, subject.energy)
def execute_fires(players, subjects): # TODO: account for world wrapping for player in players: # unpack required information (angle, distance, radius, charge) = player.fire loc_x, loc_y = player.location lim_x, lim_y = config.game.field_dimensions # calculate the epicenter of the blast epicenter = ((loc_x + cos(angle) * distance) % lim_x, (loc_y + sin(angle) * distance) % lim_y) # TODO: subtract energy cost (and signal death if it proved fatal) for subject in subjects: # calculate distance to epicenter for all subjects, signal hit if ... hit if util.distance(epicenter, subject.location) <= radius: subject.signal_hit(player.name, util.angle(subject.location, epicenter), charge)
def execute_scans(self, players): result_signals = [] for player in players: (radius, ) = player.scan_action logging.info('player {} at {} scanned with radius {}'.format( player.name, player.location, radius)) # subtract energy cost cost = game.scan_cost(radius) prev_energy = player.energy player.energy -= cost self.emit_event(type='player_scan', player=player.name, location=player.location, radius=radius, cost=cost, energy=(prev_energy, player.energy)) if player.energy <= 0.0: # signal player is dead result_signals.append(self.player_death(player)) self.emit_event(type='player_suicide', action='scan', cost=cost, energy=(prev_energy, player.energy)) logging.info('player {} died from exhaustion (scan)'.format( player.name)) else: x, y = player.location # calculate the bounding box for the scan bounds = (x - radius, y - radius, x + radius, y + radius) # collect all players in the bounding box for the blast subjects = set() for region in util.generate_wrapped_bounds( (0, 0, self.width, self.height), bounds): subjects = subjects.union(self.find_players(region)) radius = util.WrappedRadius(player.location, radius, (self.width, self.height)) # check if subject in scan radius (bounding box possibly selects too many players) for subject in subjects: # calculate distance to all subjects, signal detect if within scan # TODO: using radius twice runs the expensive operation twice (distance, wrapped_location) = radius.distance(subject.location) if subject is not player and subject.location in radius: result_signals.append( (player.signal_detect, subject.name, util.angle(player.location, wrapped_location), util.distance(player.location, wrapped_location), subject.energy)) self.emit_event(type='player_detect', player=player.name, energy=player.energy, location=player.location, radius=radius, detected=subject.name, detected_location=subject.location, detected_energy=subject.energy) logging.info('player {} detected {}'.format( player.name, subject.name)) return result_signals
def execute_fires(self, players): result_signals = [] for player in players: # unpack required information (angle, distance, radius, charge) = player.fire_action # TODO: log fire action for player # calculate the epicenter of the blast epicenter = util.move_wrapped(player.location, angle, distance, (self.width, self.height)) # subtract energy cost cost = game.fire_cost(distance, radius, charge) logging.info( 'player {} at {} fired at {} (radius: {}, charge: {})'.format( player.name, player.location, epicenter, radius, charge)) prev_energy = player.energy player.energy -= cost # emit player fire event self.emit_event(type='player_fire', player=player.name, location=player.location, angle=angle, distance=distance, radius=radius, charge=charge, cost=cost, epicenter=epicenter, energy=(prev_energy, player.energy)) if player.energy <= 0.0: # signal player is dead result_signals.append(self.player_death(player)) self.emit_event(type='player_suicide', action='fire', cost=cost, energy=(prev_energy, player.energy)) # XXX: possibly more to do with hitting one's self logging.info('player {} died from exhaustion (fire)'.format( player.name)) # calculate the bounding box for the blast bounds = (epicenter[0] - radius, epicenter[1] - radius, epicenter[0] + radius, epicenter[1] + radius) # collect all players in the bounding box for the blast subjects = set() for region in util.generate_wrapped_bounds( (0, 0, self.width, self.height), bounds): subjects = subjects.union(self.find_players(region)) # create a wrapped radius to check distance against radius = util.WrappedRadius(epicenter, radius, (self.width, self.height)) # check if subject in blast radius (bounding box possibly selects too many players) for subject in subjects: # calculate distance to epicenter for all subjects, signal hit if ... hit if subject.location in radius: # subtract energy equal to charge from subject that was hit prev_energy = subject.energy subject.energy -= charge # emit player hit event self.emit_event(type='player_hit', player=subject.name, location=subject.location, epicenter=epicenter, radius=radius, charge=charge, energy=(prev_energy, subject.energy), fatal=subject.energy <= 0.0, attacker=player.name, attacker_location=player.location, attacker_energy=player.energy) # signal the subject it was hit result_signals.append( (player.signal_hit, player.name, util.angle( radius.distance(subject.location)[1], epicenter), charge)) logging.info( 'player {} hit {} for {} (new energy: {})'.format( player.name, subject.name, charge, subject.energy)) # check to see if the subject died from this hit if subject.energy <= 0.0: logging.info("player {} died from {}'s bomb".format( subject.name, player.name)) result_signals.append(self.player_death(subject)) return result_signals
def execute_scans(self, players): result_signals = [] for player in players: (radius,) = player.scan_action logging.info('player {} at {} scanned with radius {}'.format( player.name, player.location, radius )) # subtract energy cost cost = game.scan_cost(radius) prev_energy = player.energy player.energy -= cost self.emit_event( type = 'player_scan', player = player.name, location = player.location, radius = radius, cost = cost, energy = (prev_energy, player.energy) ) if player.energy <= 0.0: # signal player is dead result_signals.append(self.player_death(player)) self.emit_event( type = 'player_suicide', action = 'scan', cost = cost, energy = (prev_energy, player.energy) ) logging.info('player {} died from exhaustion (scan)'.format(player.name)) else: x, y = player.location # calculate the bounding box for the scan bounds = ( x - radius, y - radius, x + radius, y + radius ) # collect all players in the bounding box for the blast subjects = set() for region in util.generate_wrapped_bounds((0, 0, self.width, self.height), bounds): subjects = subjects.union(self.find_players(region)) radius = util.WrappedRadius(player.location, radius, (self.width, self.height)) # check if subject in scan radius (bounding box possibly selects too many players) for subject in subjects: # calculate distance to all subjects, signal detect if within scan # TODO: using radius twice runs the expensive operation twice (distance, wrapped_location) = radius.distance(subject.location) if subject is not player and subject.location in radius: result_signals.append((player.signal_detect, subject.name, util.angle(player.location, wrapped_location), util.distance(player.location, wrapped_location), subject.energy )) self.emit_event( type = 'player_detect', player = player.name, energy = player.energy, location = player.location, radius = radius, detected = subject.name, detected_location = subject.location, detected_energy = subject.energy ) logging.info('player {} detected {}'.format(player.name, subject.name)) return result_signals
def execute_fires(self, players): result_signals = [] for player in players: # unpack required information (angle, distance, radius, charge) = player.fire_action # TODO: log fire action for player # calculate the epicenter of the blast epicenter = util.move_wrapped(player.location, angle, distance, (self.width, self.height)) # subtract energy cost cost = game.fire_cost(distance, radius, charge) logging.info('player {} at {} fired at {} (radius: {}, charge: {})'.format( player.name, player.location, epicenter, radius, charge )) prev_energy = player.energy player.energy -= cost # emit player fire event self.emit_event( type = 'player_fire', player = player.name, location = player.location, angle = angle, distance = distance, radius = radius, charge = charge, cost = cost, epicenter = epicenter, energy = (prev_energy, player.energy) ) if player.energy <= 0.0: # signal player is dead result_signals.append(self.player_death(player)) self.emit_event( type = 'player_suicide', action = 'fire', cost = cost, energy = (prev_energy, player.energy) ) # XXX: possibly more to do with hitting one's self logging.info('player {} died from exhaustion (fire)'.format(player.name)) # calculate the bounding box for the blast bounds = ( epicenter[0] - radius, epicenter[1] - radius, epicenter[0] + radius, epicenter[1] + radius ) # collect all players in the bounding box for the blast subjects = set() for region in util.generate_wrapped_bounds((0, 0, self.width, self.height), bounds): subjects = subjects.union(self.find_players(region)) # create a wrapped radius to check distance against radius = util.WrappedRadius(epicenter, radius, (self.width, self.height)) # check if subject in blast radius (bounding box possibly selects too many players) for subject in subjects: # calculate distance to epicenter for all subjects, signal hit if ... hit if subject.location in radius: # subtract energy equal to charge from subject that was hit prev_energy = subject.energy subject.energy -= charge # emit player hit event self.emit_event( type = 'player_hit', player = subject.name, location = subject.location, epicenter = epicenter, radius = radius, charge = charge, energy = (prev_energy, subject.energy), fatal = subject.energy <= 0.0, attacker = player.name, attacker_location = player.location, attacker_energy = player.energy ) # signal the subject it was hit result_signals.append((player.signal_hit, player.name, util.angle(radius.distance(subject.location)[1], epicenter), charge )) logging.info('player {} hit {} for {} (new energy: {})'.format(player.name, subject.name, charge, subject.energy)) # check to see if the subject died from this hit if subject.energy <= 0.0: logging.info("player {} died from {}'s bomb".format(subject.name, player.name)) result_signals.append(self.player_death(subject)) return result_signals