def _give_birth(self, password, args): '''Checks if robot has the permission to give birth to a child. If so, it generates and returns a new password. ''' if len(args) != 1: raise InvalidArgumentsError( "`give_birth' takes exactly one argument.") robot_id = args[0] if not isinstance(robot_id, str): raise InvalidArgumentsError( "Expected {0} as robot_id, found {1}".format( type(str), type(args[0]))) robot = self._database.get_robot(robot_id, for_update=True) required_honor = self._configs.get_robots_birth_required_honor() if robot.get_honor() < required_honor: raise NotEnoughHonorError( "Robot needs {0} honor to give birth, but has {1}.".format( required_honor, robot.get_honor())) robot.set_honor(robot.get_honor() - required_honor) # This while is exists, to prevent generating duplicated passwords. while True: try: new_password = self._id_generator.get_password() self._database.add_password(new_password) break except DuplicatedPasswordError: # pragma: no cover continue return new_password
def do_action(self, robot, args): '''Move the robot in the specified direction.. @param robot: Instance of `objects.robot.Robot'. ''' # Validating arguments. if len(args) != 2: raise InvalidArgumentsError( "Move action takes exactly two argument. {0} given.".format( len(args))) direction = args[1] if not isinstance(direction, str) or direction not in MoveAction.DIRECTIONS: raise InvalidArgumentsError( "Invalid direction passed to Move action.") robot_location = robot.get_location() direction_points = MoveAction.DIRECTIONS[direction] destination = (robot_location[0] + direction_points[0], robot_location[1] + direction_points[1]) try: self._do_move(robot, destination) except LockAlreadyAquiredError: # Waiting for a moment, and trying one more time. # Client shouldn't receive an error if, for example, someone updating a plant on these squares. self._logger.info("Concurrency when trying to move a robot.") time.sleep(0.02) self._do_move(robot, destination)
def do_action(self, robot, args): '''Makes robot eat the plant on the current location. @param robot: Instance of `objects.robot.Robot'. ''' if len(args) != 1: raise InvalidArgumentsError("`eat' action takes no arguments.") try: current_square = self._world.get_square(robot.get_location(), for_update=True) except LockAlreadyAquiredError: # Trying one more time. time.sleep(0.02) current_square = self._world.get_square(robot.get_location(), for_update=True) plant = current_square.get_plant() if plant is None: raise NoPlantToEat("There's no plant on {0}".format(robot.get_location())) if plant.is_matured(): robot.set_energy(robot.get_energy() + self._plant_energy) # Plant will be removed from the world, regardless of its maturity. current_square.set_plant(None)
def do_action(self, robot, args): '''Waters the square robot stands on. @param robot: Instance of `objects.robot.Robot'. ''' if len(args) != 1: raise InvalidArgumentsError("`water' action takes no arguments.") if not robot.get_has_water(): raise RobotHaveNoWaterError("Robot does not carry water.") try: square = self._world.get_square(robot.get_location(), for_update=True) except LockAlreadyAquiredError: # Waiting a little, and trying one more time. time.sleep(0.02) square = self._world.get_square(robot.get_location(), for_update=True) # Note: we don't raise an exception if there's no plant. A robot can waste its water. plant = square.get_plant() if plant is not None: plant.set_water_level(100) robot.set_honor(robot.get_honor() + 1) robot.set_has_water(False)
def do_action(self, robot, args): '''Returns information about the world.. @param robot: Instance of `objects.robot.Robot'. ''' if len(args) != 1: raise InvalidArgumentsError("`info' takes no arguments.") return self._result
def execute_command(self, password, command, args): '''Executes the specified command.''' if not isinstance(password, str): raise InvalidArgumentsError( "Expected {0} as password, found {1}.".format( type(str), type(password))) self._authenticator.authenticate_admin(password) if command == "map_data": return self._get_map_data(args)
def execute_command(self, password, command, args): '''Executes the specified command.''' if not isinstance(password, str): raise InvalidArgumentsError( "Expected {0} as password, found {1}.".format( type(str), type(password))) if command == "born": return self._born(password, args) elif command == "give_birth": return self._give_birth(password, args)
def do_action(self, robot, args): '''Plant a plant where robot stands. @param robot: Instance of `objects.robot.Robot'. ''' if len(args) > 1: raise InvalidArgumentsError("`plant' action takes no arguments.") plant = Plant() self._world.plant(plant, robot.get_location())
def do_action(self, robot, args): '''Fill water tank of the robot. @param robot: Instance of `objects.robot.Robot'. ''' if len(args) != 1: raise InvalidArgumentsError("`take_water' takes no arguments.") current_square = self._world.get_square(robot.get_location()) if current_square.get_type() != MapSquareTypes.WATER: raise NoWaterError("There's no water on square {0}".format( robot.get_location())) robot.set_has_water(True)
def _born(self, password, args): '''Gives birth to a robot for the first time. @param args: List of arguments. The first argument can be a parent robot. If provided, the new robot will be born software near its parent. If not, it will be born on a random place. ''' parent_robot_id = None if len(args) > 0: parent_robot_id = args[0] if parent_robot_id is not None: if not isinstance(parent_robot_id, str): raise InvalidArgumentsError( "`parent_robot_id' must be `str', not {0}".format( type(parent_robot_id))) parent_robot = self._database.get_robot(parent_robot_id) born_location = parent_robot.get_location() else: world_size = self._world.get_size() born_location = (random.randint(0, world_size[0] - 1), random.randint(0, world_size[1] - 1)) robot_name = "" if len(args) == 2: robot_name = args[1] self._authenticator.authenticate_new_robot(password) new_robot = Robot(self._id_generator.get_robot_id(), self._id_generator.get_password(), name=robot_name) self._world.add_robot(new_robot, (born_location[0], born_location[1])) return { 'robot_id': new_robot.get_id(), 'password': new_robot.get_password() }