예제 #1
0
    def __init__(self, cat_ai, dog_ai, field_size=(16,16), num_dogs=5):
        """Initialize the simulation.

        Sets up the entities in the simulation (cat and dogs) with the passed in
        AIs. Refer to simulation.ai for predefined AIs as well as the signature
        used for the AI functions.

        Arguments:
        - `cat_ai`: The AI used for the cat.
        - `dog_ai`: The AI used for the dog.
        - `field_size`: The size of the field.
        - `num_dogs`: The amount of dogs to put on the board.
        """
        self._last_tick = datetime.now()
        self._gameover = False
        self._win = False
        self._field_size = field_size
        self._ticks = 0

        # Set up the field and place entities within
        height = field_size[1]
        width = field_size[0]
        # We want the cat to start flush with the bottom, in the center
        self._cat = Entity(Circle((random.uniform(self.CAT_RADIUS,
                                                  width-self.CAT_RADIUS),
                                   height-self.CAT_RADIUS),
                                  self.CAT_RADIUS),
                           self.CAT_SPEED)

        # The goal is flush with the top, also centered
        self._goal = Entity(Rect((width/2.0, self.GOAL_SIZE[1]/2.0),
                                 self.GOAL_SIZE),
                            0.0)

        # The dogs are arranged randomly within the top half of the screen
        self._dogs = []
        dog_padding = (self.DOG_SIZE[0]/2.0,self.DOG_SIZE[1]/2.0)
        x_range = (dog_padding[0], width-dog_padding[0])
        y_range = (dog_padding[1], (height/2.0)-dog_padding[1])
        for i in range(num_dogs):
            dogx = random.uniform(x_range[0], x_range[1])
            dogy = random.uniform(y_range[0], y_range[1])
            dog = Entity(Rect((dogx, dogy), self.DOG_SIZE),
                         self.DOG_SPEED)
            self._dogs.append(dog)

        self._cat_ai = cat_ai
        self._dog_ai = dog_ai
예제 #2
0
    def __init__(self, cat_ai, dog_ai, field_size=(16, 16), num_dogs=5):
        """Initialize the simulation.

        Sets up the entities in the simulation (cat and dogs) with the passed in
        AIs. Refer to simulation.ai for predefined AIs as well as the signature
        used for the AI functions.

        Arguments:
        - `cat_ai`: The AI used for the cat.
        - `dog_ai`: The AI used for the dog.
        - `field_size`: The size of the field.
        - `num_dogs`: The amount of dogs to put on the board.
        """
        self._last_tick = datetime.now()
        self._gameover = False
        self._win = False
        self._field_size = field_size
        self._ticks = 0

        # Set up the field and place entities within
        height = field_size[1]
        width = field_size[0]
        # We want the cat to start flush with the bottom, in the center
        self._cat = Entity(
            Circle((random.uniform(self.CAT_RADIUS, width - self.CAT_RADIUS),
                    height - self.CAT_RADIUS), self.CAT_RADIUS),
            self.CAT_SPEED)

        # The goal is flush with the top, also centered
        self._goal = Entity(
            Rect((width / 2.0, self.GOAL_SIZE[1] / 2.0), self.GOAL_SIZE), 0.0)

        # The dogs are arranged randomly within the top half of the screen
        self._dogs = []
        dog_padding = (self.DOG_SIZE[0] / 2.0, self.DOG_SIZE[1] / 2.0)
        x_range = (dog_padding[0], width - dog_padding[0])
        y_range = (dog_padding[1], (height / 2.0) - dog_padding[1])
        for i in range(num_dogs):
            dogx = random.uniform(x_range[0], x_range[1])
            dogy = random.uniform(y_range[0], y_range[1])
            dog = Entity(Rect((dogx, dogy), self.DOG_SIZE), self.DOG_SPEED)
            self._dogs.append(dog)

        self._cat_ai = cat_ai
        self._dog_ai = dog_ai
예제 #3
0
class Simulation(object):
    """Represents the simulation part of the test bed.

    This is the part that contains all the logic for the game and handles the
    decision making for the entities.
    """

    CAT_RADIUS = 0.75
    DOG_SIZE = (1.5, 1.5)
    GOAL_SIZE = (5, 2)
    CAT_SPEED = 2.0
    DOG_SPEED = CAT_SPEED * 3.0 / 4.0

    def __init__(self, cat_ai, dog_ai, field_size=(16, 16), num_dogs=5):
        """Initialize the simulation.

        Sets up the entities in the simulation (cat and dogs) with the passed in
        AIs. Refer to simulation.ai for predefined AIs as well as the signature
        used for the AI functions.

        Arguments:
        - `cat_ai`: The AI used for the cat.
        - `dog_ai`: The AI used for the dog.
        - `field_size`: The size of the field.
        - `num_dogs`: The amount of dogs to put on the board.
        """
        self._last_tick = datetime.now()
        self._gameover = False
        self._win = False
        self._field_size = field_size
        self._ticks = 0

        # Set up the field and place entities within
        height = field_size[1]
        width = field_size[0]
        # We want the cat to start flush with the bottom, in the center
        self._cat = Entity(
            Circle((random.uniform(self.CAT_RADIUS, width - self.CAT_RADIUS),
                    height - self.CAT_RADIUS), self.CAT_RADIUS),
            self.CAT_SPEED)

        # The goal is flush with the top, also centered
        self._goal = Entity(
            Rect((width / 2.0, self.GOAL_SIZE[1] / 2.0), self.GOAL_SIZE), 0.0)

        # The dogs are arranged randomly within the top half of the screen
        self._dogs = []
        dog_padding = (self.DOG_SIZE[0] / 2.0, self.DOG_SIZE[1] / 2.0)
        x_range = (dog_padding[0], width - dog_padding[0])
        y_range = (dog_padding[1], (height / 2.0) - dog_padding[1])
        for i in range(num_dogs):
            dogx = random.uniform(x_range[0], x_range[1])
            dogy = random.uniform(y_range[0], y_range[1])
            dog = Entity(Rect((dogx, dogy), self.DOG_SIZE), self.DOG_SPEED)
            self._dogs.append(dog)

        self._cat_ai = cat_ai
        self._dog_ai = dog_ai

    def setCatMove(self, direction):
        """Set the cat's move if using ai.ControlAI.

        Arguments:
        - `direction`:
        """
        ai._cat_move = direction

    def getState(self, ):
        """Get the state of the simulation.

        Returns a simplified version of the simulation state, containing only
        the positions of all the entities, whether the game is over and if it
        was won or lost.
        """
        state = {}
        state["updated"] = self._last_tick
        state["cat"] = self._cat.getPosition()
        state["dogs"] = [d.getPosition() for d in self._dogs]
        state["goal"] = self._goal.getPosition()
        state["gameover"] = self._gameover
        state["win"] = self._win
        return state

    def getFieldSize(self, ):
        """Get the size of the game field.
        """
        return self._field_size

    def simtick(self, ):
        """Do one tick of the simulation.
        """
        if self._ticks >= 50:
            self._gameover = True
            self._win = True
        if not self._gameover:
            self._last_tick = datetime.now()
            moves = self._aiStep()
            self._updateState(moves)
            collisions = self._checkCollisions()
            if collisions:
                self._gameover = True
                if "goal" in collisions:
                    self._win = True
                elif "dog" in collisions:
                    self._win = False
        self._ticks += 1
        return self.getState()

    def _aiStep(self, ):
        """Do one AI step.

        Call the AI functions for all the entities and gather up their movement
        decisions, then return them.
        """
        moves = []
        moves.append(
            self._cat_ai(self._cat, self._cat, self._dogs, self._goal,
                         self._field_size))
        for dog in self._dogs:
            moves.append(
                self._dog_ai(dog, self._cat, self._dogs, self._goal,
                             self._field_size))
        return moves

    def _updateState(self, moves):
        """Update the positions of entities according to the moves.

        Arguments:
        - `moves`: The list of moves to do. The first element is for the cat,
        the remaining are for the dogs.
        """
        self._cat.move(moves[0])
        self._ensureInside(self._cat)
        for i, dog in enumerate(self._dogs):
            dog.move(moves[i + 1])
            self._ensureInside(dog)

    def _ensureInside(self, entity):
        """Ensure that the entity is inside the field.

        Arguments:
        - `entity`: The given entity
        - `size`: The bounding box of the entity
        """
        pos = entity.getPosition()
        shape = entity.getShape()
        new_pos = list(pos)

        width = shape.getRight() - shape.getLeft()
        height = shape.getBottom() - shape.getTop()

        if shape.getLeft() < 0:
            new_pos[0] = width * 0.5
        elif shape.getRight() > self._field_size[0]:
            new_pos[0] = self._field_size[0] - width * 0.5
        else:
            new_pos[0] = pos[0]

        if shape.getTop() < 0:
            new_pos[1] = height * 0.5
        elif shape.getBottom() > self._field_size[1]:
            new_pos[1] = self._field_size[1] - height * 0.5
        else:
            new_pos[1] = pos[1]

        entity.setPosition(new_pos)

    def _checkCollisions(self, ):
        """Check for collisions between cat and other entities.
        """
        collisions = []
        for dog in self._dogs:
            if collide(self._cat, dog):
                collisions.append("dog")
        if collide(self._cat, self._goal):
            collisions.append("goal")
        return collisions
예제 #4
0
class Simulation(object):
    """Represents the simulation part of the test bed.

    This is the part that contains all the logic for the game and handles the
    decision making for the entities.
    """

    CAT_RADIUS = 0.75
    DOG_SIZE = (1.5, 1.5)
    GOAL_SIZE = (5, 2)
    CAT_SPEED = 2.0
    DOG_SPEED = CAT_SPEED*3.0/4.0


    def __init__(self, cat_ai, dog_ai, field_size=(16,16), num_dogs=5):
        """Initialize the simulation.

        Sets up the entities in the simulation (cat and dogs) with the passed in
        AIs. Refer to simulation.ai for predefined AIs as well as the signature
        used for the AI functions.

        Arguments:
        - `cat_ai`: The AI used for the cat.
        - `dog_ai`: The AI used for the dog.
        - `field_size`: The size of the field.
        - `num_dogs`: The amount of dogs to put on the board.
        """
        self._last_tick = datetime.now()
        self._gameover = False
        self._win = False
        self._field_size = field_size
        self._ticks = 0

        # Set up the field and place entities within
        height = field_size[1]
        width = field_size[0]
        # We want the cat to start flush with the bottom, in the center
        self._cat = Entity(Circle((random.uniform(self.CAT_RADIUS,
                                                  width-self.CAT_RADIUS),
                                   height-self.CAT_RADIUS),
                                  self.CAT_RADIUS),
                           self.CAT_SPEED)

        # The goal is flush with the top, also centered
        self._goal = Entity(Rect((width/2.0, self.GOAL_SIZE[1]/2.0),
                                 self.GOAL_SIZE),
                            0.0)

        # The dogs are arranged randomly within the top half of the screen
        self._dogs = []
        dog_padding = (self.DOG_SIZE[0]/2.0,self.DOG_SIZE[1]/2.0)
        x_range = (dog_padding[0], width-dog_padding[0])
        y_range = (dog_padding[1], (height/2.0)-dog_padding[1])
        for i in range(num_dogs):
            dogx = random.uniform(x_range[0], x_range[1])
            dogy = random.uniform(y_range[0], y_range[1])
            dog = Entity(Rect((dogx, dogy), self.DOG_SIZE),
                         self.DOG_SPEED)
            self._dogs.append(dog)

        self._cat_ai = cat_ai
        self._dog_ai = dog_ai

    def setCatMove(self, direction):
        """Set the cat's move if using ai.ControlAI.

        Arguments:
        - `direction`:
        """
        ai._cat_move = direction

    def getState(self, ):
        """Get the state of the simulation.

        Returns a simplified version of the simulation state, containing only
        the positions of all the entities, whether the game is over and if it
        was won or lost.
        """
        state = {}
        state["updated"] = self._last_tick
        state["cat"] = self._cat.getPosition()
        state["dogs"] = [d.getPosition() for d in self._dogs]
        state["goal"] = self._goal.getPosition()
        state["gameover"] = self._gameover
        state["win"] = self._win
        return state


    def getFieldSize(self, ):
        """Get the size of the game field.
        """
        return self._field_size


    def simtick(self, ):
        """Do one tick of the simulation.
        """
        if self._ticks >= 50:
            self._gameover = True
            self._win = True
        if not self._gameover:
            self._last_tick = datetime.now()
            moves = self._aiStep()
            self._updateState(moves)
            collisions = self._checkCollisions()
            if collisions:
                self._gameover = True
                if "goal" in collisions:
                    self._win = True
                elif "dog" in collisions:
                    self._win = False
        self._ticks += 1
        return self.getState()


    def _aiStep(self, ):
        """Do one AI step.

        Call the AI functions for all the entities and gather up their movement
        decisions, then return them.
        """
        moves = []
        moves.append(self._cat_ai(self._cat, self._cat,
                                  self._dogs, self._goal,
                                  self._field_size))
        for dog in self._dogs:
            moves.append(self._dog_ai(dog, self._cat,
                                      self._dogs, self._goal,
                                      self._field_size))
        return moves

    def _updateState(self, moves):
        """Update the positions of entities according to the moves.

        Arguments:
        - `moves`: The list of moves to do. The first element is for the cat,
        the remaining are for the dogs.
        """
        self._cat.move(moves[0])
        self._ensureInside(self._cat)
        for i, dog in enumerate(self._dogs):
            dog.move(moves[i+1])
            self._ensureInside(dog)


    def _ensureInside(self, entity):
        """Ensure that the entity is inside the field.

        Arguments:
        - `entity`: The given entity
        - `size`: The bounding box of the entity
        """
        pos = entity.getPosition()
        shape = entity.getShape()
        new_pos = list(pos)

        width = shape.getRight() - shape.getLeft()
        height = shape.getBottom() - shape.getTop()

        if shape.getLeft() < 0:
            new_pos[0] = width*0.5
        elif shape.getRight() > self._field_size[0]:
            new_pos[0] = self._field_size[0]-width*0.5
        else:
            new_pos[0] = pos[0]

        if shape.getTop() < 0:
            new_pos[1] = height*0.5
        elif shape.getBottom() > self._field_size[1]:
            new_pos[1] = self._field_size[1]-height*0.5
        else:
            new_pos[1] = pos[1]

        entity.setPosition(new_pos)


    def _checkCollisions(self, ):
        """Check for collisions between cat and other entities.
        """
        collisions = []
        for dog in self._dogs:
            if collide(self._cat, dog):
                collisions.append("dog")
        if collide(self._cat, self._goal):
            collisions.append("goal")
        return collisions