Ejemplo n.º 1
0
    def __init__(self):
        self._world = World()
        configs = Configs()

        self._result = {'world_size': '{0},{1}'.format(*self._world.get_size()),
                        'plant_max_age': configs.get_plant_max_age(),
                        'plant_matured_age': configs.get_plant_matured_age(),
                        'action_delay': configs.get_robots_actions_delay(),
                        'maximum_energy': configs.get_robots_maximum_energy(),
                        'birth_required_honor': configs.get_robots_birth_required_honor()}
Ejemplo n.º 2
0
    def __init__(self):
        self._world = World()
        configs = Configs()

        self._result = {
            'world_size': '{0},{1}'.format(*self._world.get_size()),
            'plant_max_age': configs.get_plant_max_age(),
            'plant_matured_age': configs.get_plant_matured_age(),
            'action_delay': configs.get_robots_actions_delay(),
            'maximum_energy': configs.get_robots_maximum_energy(),
            'birth_required_honor': configs.get_robots_birth_required_honor()
        }
    def test_info(self):
        '''Test received information.'''
        action = InfoAction()
        world = World()
        configs = Configs()
        robot = Robot("test_info_action_1293", "123")

        info = action.do_action(robot, [robot.get_id()])

        self.assertEqual(info['world_size'], '{0},{1}'.format(*world.get_size()))
        self.assertEqual(info['plant_max_age'], configs.get_plant_max_age())
        self.assertEqual(info['plant_matured_age'], configs.get_plant_matured_age())
        self.assertEqual(info['action_delay'], configs.get_robots_actions_delay())
        self.assertEqual(info['birth_required_honor'], configs.get_robots_birth_required_honor())
Ejemplo n.º 4
0
    def test_info(self):
        '''Test received information.'''
        action = InfoAction()
        world = World()
        configs = Configs()
        robot = Robot("test_info_action_1293", "123")

        info = action.do_action(robot, [robot.get_id()])

        self.assertEqual(info['world_size'],
                         '{0},{1}'.format(*world.get_size()))
        self.assertEqual(info['plant_max_age'], configs.get_plant_max_age())
        self.assertEqual(info['plant_matured_age'],
                         configs.get_plant_matured_age())
        self.assertEqual(info['action_delay'],
                         configs.get_robots_actions_delay())
        self.assertEqual(info['birth_required_honor'],
                         configs.get_robots_birth_required_honor())
Ejemplo n.º 5
0
class ObjectUpdater(DatabaseHook):
    '''This class checks objects in the world, and updates them
    if required.

    Responsibilities of this class:
        * Killing and removing a robot from the world, if its
          energy reached zero or it ran out of life.
        * Removing a plant from the world if its water level
          reached zero or it became too old.
        * Maturing a plant if it reached a certain age.
        * Updating a plant's water level during time.
    '''
    def __init__(self):
        self._database = MemcachedDatabase()
        self._configs = Configs()

    def robot_got(self, robot_object, locked_for_update):
        '''Checks and updates the specified robot's object.'''
        if robot_object.get_energy() <= 0 or robot_object.get_life() <= 0:

            if not locked_for_update:
                # This would call this method again, and robot will be updated.
                return self._database.get_robot(robot_object.get_id(),
                                                for_update=True)

            robot_object.set_alive(False)

            # Removing the robot from its location.
            try:
                square = self._database.get_square(robot_object.get_location(),
                                                   for_update=True)
            except LockAlreadyAquiredError:
                # Trying one more time.
                time.sleep(0.02)
                square = self._database.get_square(robot_object.get_location(),
                                                   for_update=True)

            square.set_robot_id(None)

            # XXX: Though it's a very dirty thing to do, we have to commit these changes, because
            #      later this robot will face an Authentication Exception, and our changes will be
            #      lost.
            self._database.commit()

            # Immediately, locking the robot object. It's not atomic, so there's a little chance
            # that concurrency happens. But, it shouldn't be a problem, since the robot is already
            # dead, and can't do anything anyway.
            self._database.get_lock(robot_object.get_id())

        return robot_object

    def square_got(self, location, square_object, locked_for_update):
        '''Checks and updates specified square object.'''
        plant = square_object.get_plant()

        if plant is None:
            return square_object

        # Time passed from the last time this plant updated.
        last_update = time.time() - plant.get_last_update()
        passed_cycles = math.floor(last_update /
                                   (self._configs.get_plant_cylce() / 1000))

        if passed_cycles <= 0:
            # No cycle passed, no need to be updated.
            return square_object

        if not locked_for_update:
            # This will call this method again.
            try:
                return self._database.get_square(location, for_update=True)
            except LockAlreadyAquiredError:
                # Trying one more time.
                time.sleep(0.02)
                return self._database.get_square(location, for_update=True)

        plant.set_age(plant.get_age() + passed_cycles)
        plant.set_water_level(plant.get_water_level() -
                              (passed_cycles *
                               self._configs.get_plant_lose_water_in_cycle()))

        if plant.get_age() > self._configs.get_plant_max_age(
        ) or plant.get_water_level() <= 0:
            # Plant is dead! Removing it from the world.
            square_object.set_plant(None)

        plant.set_last_update(time.time())

        return square_object
Ejemplo n.º 6
0
class ObjectUpdater(DatabaseHook):
    '''This class checks objects in the world, and updates them
    if required.

    Responsibilities of this class:
        * Killing and removing a robot from the world, if its
          energy reached zero or it ran out of life.
        * Removing a plant from the world if its water level
          reached zero or it became too old.
        * Maturing a plant if it reached a certain age.
        * Updating a plant's water level during time.
    '''

    def __init__(self):
        self._database = MemcachedDatabase()
        self._configs = Configs()

    def robot_got(self, robot_object, locked_for_update):
        '''Checks and updates the specified robot's object.'''
        if robot_object.get_energy() <= 0 or robot_object.get_life() <= 0:

            if not locked_for_update:
                # This would call this method again, and robot will be updated.
                return self._database.get_robot(robot_object.get_id(), for_update=True)

            robot_object.set_alive(False)

            # Removing the robot from its location.
            try:
                square = self._database.get_square(robot_object.get_location(), for_update=True)
            except LockAlreadyAquiredError:
                # Trying one more time.
                time.sleep(0.02)
                square = self._database.get_square(robot_object.get_location(), for_update=True)

            square.set_robot_id(None)

            # XXX: Though it's a very dirty thing to do, we have to commit these changes, because
            #      later this robot will face an Authentication Exception, and our changes will be
            #      lost.
            self._database.commit()

            # Immediately, locking the robot object. It's not atomic, so there's a little chance
            # that concurrency happens. But, it shouldn't be a problem, since the robot is already
            # dead, and can't do anything anyway.
            self._database.get_lock(robot_object.get_id())

        return robot_object

    def square_got(self, location, square_object, locked_for_update):
        '''Checks and updates specified square object.'''
        plant = square_object.get_plant()

        if plant is None:
            return square_object

        # Time passed from the last time this plant updated.
        last_update = time.time() - plant.get_last_update()
        passed_cycles = math.floor(last_update / (self._configs.get_plant_cylce() / 1000))

        if passed_cycles <= 0:
            # No cycle passed, no need to be updated.
            return square_object

        if not locked_for_update:
            # This will call this method again.
            try:
                return self._database.get_square(location, for_update=True)
            except LockAlreadyAquiredError:
                # Trying one more time.
                time.sleep(0.02)
                return self._database.get_square(location, for_update=True)

        plant.set_age(plant.get_age() + passed_cycles)
        plant.set_water_level(plant.get_water_level() - (passed_cycles * self._configs.get_plant_lose_water_in_cycle()))

        if plant.get_age() > self._configs.get_plant_max_age() or plant.get_water_level() <= 0:
            # Plant is dead! Removing it from the world.
            square_object.set_plant(None)

        plant.set_last_update(time.time())

        return square_object