def enemiesInRange(self, keyarg='list'): circle = self.circle myfaction = self.states['faction'] self.updatecircle() sobjectsInView = [ sobj for sobj in myfaction.tracker if sobj.pos() in self.circle and sobj.objectclass in ['ship', 'fleet', 'building'] ] # sobjects in your circle enemiesinview = [ sobj for sobj in sobjectsInView if self.diffactions(sobj) ] # enemies in your circle myrange = self.states['range'] enemiesinrange = [ sobj for sobj in enemiesinview if mapmethods.distance(self, sobj) <= myrange ] # enemies in your circle and in weapons' range if keyarg == 'list': return enemiesinrange # a list, btw. elif keyarg == 'number': return len(enemiesinrange) # the number of enemies in range
def checkRange(self, coordinatesOrShip): """Returns Frue if coordinates are in range for firing; False otherwise.""" if isinstance(coordinatesOrShip, Vessel) or isinstance( coordinatesOrShip, Fleet): coordinatesOrShip = coordinatesOrShip.states['position'] elif isinstance(coordinatesOrShip, tuple) and len(coordinatesOrShip) == 2: if type(coordinatesOrShip[0]) != int or type( coordinatesOrShip[1] ) != int or coordinatesOrShip[0] + coordinatesOrShip[1] > 1000: raise VesselMethodsError( "Bad input for checkRange function. Should be a tuple of integers or an object with a 'position' state." ) else: raise VesselMethodsError( "Bad input for checkRange function. Should be a tuple of integers or an object with a 'position' state." ) if self.states['range'] == None: dist = 0 else: dist = mapmethods.distance(self, coordinatesOrShip) if dist <= self.states['range']: return True else: return False
def nearest(self,kwargs = None): """Returns a pointer to the closest enemy vessel or fleet.""" _enemies = [] distances_enemy_dictionary = {} optlist = [] if kwargs == 'fleets': optlist = existing_Fleets elif kwargs == 'vessels': optlist = existing_Ships else: optlist = existing_Ships + existing_Fleets for maybeenemy in optlist: if maybeenemy.states['faction'] == self.states['faction']: # not same faction pass else: _enemies.extend([maybeenemy]) if _enemies == []: print('There is no enemy in view!') return None else: for enemy in _enemies: distance = mapmethods.distance(self,enemy.states['position']) distances_enemy_dictionary[distance] = enemy #adds to the dictionary a pointer to the enemy fleet or ship minimaldistance = min({distance for distance in distances_enemy_dictionary}) return distances_enemy_dictionary[minimaldistance]
def checkRange(self,coordinatesOrShip): """Returns Frue if coordinates are in range for firing; False otherwise.""" if isinstance(coordinatesOrShip,Vessel) or isinstance(coordinatesOrShip,Fleet): coordinatesOrShip = coordinatesOrShip.states['position'] elif isinstance(coordinatesOrShip, tuple) and len(coordinatesOrShip) == 2: if type(coordinatesOrShip[0]) != int or type(coordinatesOrShip[1]) != int or coordinatesOrShip[0] + coordinatesOrShip[1] > 1000: raise VesselMethodsError("Bad input for checkRange function. Should be a tuple of integers or an object with a 'position' state.") else: raise VesselMethodsError("Bad input for checkRange function. Should be a tuple of integers or an object with a 'position' state.") if self.states['range'] == None: dist = 0 else: dist = mapmethods.distance(self,coordinatesOrShip) if dist <= self.states['range']: return True else: return False
def nearest(self, kwargs=None): """Returns a pointer to the closest enemy vessel or fleet.""" _enemies = [] distances_enemy_dictionary = {} optlist = [] if kwargs == 'fleets': optlist = existing_Fleets elif kwargs == 'vessels': optlist = existing_Ships else: optlist = existing_Ships + existing_Fleets for maybeenemy in optlist: if maybeenemy.states['faction'] == self.states[ 'faction']: # not same faction pass else: _enemies.extend([maybeenemy]) if _enemies == []: print('There is no enemy in view!') return None else: for enemy in _enemies: distance = mapmethods.distance(self, enemy.states['position']) distances_enemy_dictionary[distance] = enemy #adds to the dictionary a pointer to the enemy fleet or ship minimaldistance = min( {distance for distance in distances_enemy_dictionary}) return distances_enemy_dictionary[minimaldistance]
def attack(self, enemy): """Computes the damages of a battle. Should update the hullIntegrity and 'health' states of both accordingly.""" if self is enemy: raise VesselMethodsError('SelfDestruct is not yet supported.') if self.checkDifferentFaction(enemy) != True: raise VesselMethodsError( 'Cannot attack ships of the same Faction.') if enemy == 'nearest': tempodict = {} for ship in existing_Ships: if self.checkDifferentFaction(ship) == True: dist_self_ship = mapmethods.distance(self, ship) tempodict[dist_self_ship] = ship vsl = tempodict[min(tempodict.keys())] enemy = vsl enemy.updateStates self.updateStates if self.checkRange(enemy.states['position']) == True: pass else: print('Enemy out of range.') return None if enemy.states['can_be_attacked'] == False: print("Enemy can't be attacked!") return None elif self.states['can_attack'] == False: print("This ship cannot attack!") return None else: if enemy.checkRange(self.states['position']) == True: enemy_damagedealt = enemy.attackValue pass else: enemy_damagedealt = 0 self_damagedealt = self.attackValue self.states['hull_integrity'] = self.states[ 'hull_integrity'] - enemy_damagedealt enemy.states['hull_integrity'] = enemy.states[ 'hull_integrity'] - self_damagedealt enemy.updateStates self.updateStates if self_damagedealt == 0 and enemy_damagedealt == 0: print('No damage whatsoever!') return None elif self_damagedealt != 0 and enemy_damagedealt == 0: print('> ' + self.name + ' fires... Hit! ' + str(self_damagedealt) + ' damage to ' + enemy.name + ' which is now ' + enemy.states['health']) return None elif enemy_damagedealt != 0: print('> ' + self.name + ' Has been hit! ' + str(enemy_damagedealt) + ' damage to ' + enemy.name + ' which is now ' + self.states['health']) return None else: print('> ' + self.name + ' Hit! ' + str(self_damagedealt) + ' damage to ' + enemy.name + ' which is now ' + enemy.states['health']) print(' Enemy replied! ' + str(enemy_damagedealt) + ' damage to ' + self.name + ' which is now ' + self.states['health']) return None
def move(self, arg): """Takes as input a position tuple, a direction, a sobject or a list of instructions. position tuple: goes there if it is not out of range, otherwise it moves as close as possible. direction: goes in that direction as far as it can list of instructions: it follows it as far as it can sobject: transforms it into a tuple (its position).""" if self.canMove(arg) == True: pass else: return None if arg != None: if isinstance(arg, Sobject): arg = arg.states['position'] else: raise Exception('No direction to move to. Arg is None.') if self.states.get('position') == None: # only for utility self.warp(arg, ['silent', 'override']) if self.states['position'] == arg: return None oripos = deepcopy(self.states['position']) instructionsDict = { 'u': (0, -1), 'd': (0, 1), 'l': (-1, 0), 'r': (1, 0), 'ul': (-1, -1), 'ur': (1, -1), 'dl': (-1, 1), 'dr': (1, 1) } if isinstance(arg, str): if not [letter in 'udlr' for letter in arg ] == [True for i in range(len(arg))]: # checks the syntax raise Exception('Input error for move function: received' + arg) else: counter = 0 while counter < len( arg ): # until the end of the string or the end of its speed; the shortest if counter >= self.states['speed']: print('The object cannot move that much: breaking...') break syllable = 'guruguru' if len(arg) >= counter + 2: syllable = arg[counter] + arg[ counter + 1] # picks the next two letters. if syllable in ['ul', 'ur', 'dl', 'dr']: # recognize X, Y = self.states['position'] X = X + instructionsDict[letter][0] Y = Y + instructionsDict[letter][1] if self.ap_pay('move2') == True: # AP checkpoint pass else: return 'The ship has no more action_points' self.states['position'] = mapmethods.torusize((X, Y)) counter + 2 # counter goes 2 up else: letter = arg[ counter] # parses the string from 0 to end X, Y = self.states['position'] X = X + instructionsDict[letter][0] Y = Y + instructionsDict[letter][1] if self.ap_pay('move1') == True: # AP checkpoint pass else: return 'The ship has no more action_points' self.states['position'] = mapmethods.torusize((X, Y)) counter += 1 elif isinstance(arg, tuple): arg = self.closestTowards(arg) dist = mapmethods.distance(oripos, arg) if self.ap_pay(dist) == True: # AP checkpoint pass else: raise Exception( 'Something wrong here. My APs are {}; oripos = {}, arg = {}' .format(self.actionpoints(), oripos, arg)) self.states['position'] = arg pass else: raise Exception('Unrecognized argument for move routine: ' + str(arg)) if self.objectclass != 'fleet': pass else: for ship in self.states['shiplist']: ship.states['position'] = self.states[ 'position'] # moves all ships in the shiplist at its new position newpos = deepcopy(self.states['position']) mapmethods.updatePoints(oripos, self) mapmethods.updatePoints(newpos, self) # important! updates the mapcode_tracker
def attack(self,enemy): """Computes the damages of a battle. Should update the hullIntegrity and 'health' states of both accordingly.""" if self is enemy: raise VesselMethodsError('SelfDestruct is not yet supported.') if self.checkDifferentFaction(enemy) != True: raise VesselMethodsError('Cannot attack ships of the same Faction.') if enemy == 'nearest': tempodict = {} for ship in existing_Ships: if self.checkDifferentFaction(ship) == True: dist_self_ship = mapmethods.distance(self,ship) tempodict[dist_self_ship] = ship vsl = tempodict[min(tempodict.keys())] enemy = vsl enemy.updateStates self.updateStates if self.checkRange(enemy.states['position']) == True: pass else: print('Enemy out of range.') return None if enemy.states['can_be_attacked'] == False: print("Enemy can't be attacked!") return None elif self.states['can_attack'] == False: print("This ship cannot attack!") return None else: if enemy.checkRange(self.states['position']) == True: enemy_damagedealt = enemy.attackValue pass else: enemy_damagedealt = 0 self_damagedealt = self.attackValue self.states['hull_integrity'] = self.states['hull_integrity'] - enemy_damagedealt enemy.states['hull_integrity'] = enemy.states['hull_integrity'] - self_damagedealt enemy.updateStates self.updateStates if self_damagedealt == 0 and enemy_damagedealt == 0: print('No damage whatsoever!') return None elif self_damagedealt != 0 and enemy_damagedealt == 0: print('> ' + self.name + ' fires... Hit! ' + str(self_damagedealt) + ' damage to '+ enemy.name + ' which is now ' + enemy.states['health']) return None elif enemy_damagedealt != 0: print('> ' + self.name + ' Has been hit! ' + str(enemy_damagedealt) + ' damage to '+ enemy.name + ' which is now ' + self.states['health']) return None else: print('> ' + self.name + ' Hit! ' + str(self_damagedealt) + ' damage to '+ enemy.name + ' which is now ' + enemy.states['health']) print(' Enemy replied! ' + str(enemy_damagedealt) + ' damage to '+ self.name + ' which is now ' + self.states['health']) return None