Exemple #1
0
 def __init__(self, prevState=None):
     """
     Generates a new state by copying information from its predecessor.
     """
     if prevState != None:  # Initial state
         self.data = GameStateData(prevState.data)
         self.eventQueue = prevState.eventQueue.deepCopy()
     else:
         self.data = GameStateData()
         self.eventQueue = EventQueue()
def tester(buffer_size, rps, num_packets=100, num_tests=1000):

    # we are testing in milliseconds
    # or milli unit time, as it can be scaled naturally.
    lam = rps / 1000

    # beta is average time interval between two arrival events. (measured compared to processing speed)
    beta = 1 / lam

    # just using Rayleigh distribution for processing time of requests.
    # Can play around with other distributions such as Maxwell-Boltzmann.
    arrival_times = np.random.exponential(beta, (num_tests, num_packets))
    process_times = np.random.rayleigh(1, (num_tests, num_packets))

    buffer = Buffer(buffer_size)
    dropped = np.zeros(num_tests)

    for i in range(num_tests):
        arrival_time = 0
        Q = EventQueue()
        for j in range(num_packets):
            arrival_time += arrival_times[i, j]
            process_time = process_times[i, j]
            Q.insert(arrival(arrival_time, process_time))

        while Q.notEmpty():
            e = Q.next()
            e.action(Q, buffer)

        dropped[i] = buffer.num_dropped()
        buffer.reset()  # restarting buffer for next test.
        Q.reset()  # restarting queue for next test.
    return dropped
 def __init__( self, prevState = None ):
     """
     Generates a new state by copying information from its predecessor.
     """
     if prevState != None: # Initial state
         self.data = GameStateData(prevState.data)
         self.eventQueue = prevState.eventQueue.deepCopy()
     else:
         self.data = GameStateData()
         self.eventQueue = EventQueue()
Exemple #4
0
class GameState:
    """
    A GameState specifies the full game state, including the food, capsules,
    agent configurations and score changes.

    GameStates are used by the Game object to capture the actual state of the game and
    can be used by agents to reason about the game.

    Much of the information in a GameState is stored in a GameStateData object.  We
    strongly suggest that you access that data via the accessor methods below rather
    than referring to the GameStateData object directly.

    Note that in classic Pacman, Pacman is always agent 0.
    """

    ####################################################
    # Accessor methods: use these to access state data #
    ####################################################

    # static variable keeps track of which states have had getLegalActions called
    explored = set()

    def getAndResetExplored():
        tmp = GameState.explored.copy()
        GameState.explored = set()
        return tmp

    getAndResetExplored = staticmethod(getAndResetExplored)

    def getLegalActions(self, agentIndex=0):
        """
        Returns the legal actions for the agent specified.
        """
        #        GameState.explored.add(self)
        if self.isWin() or self.isLose(): return []

        if agentIndex == 0:  # Pacman is moving
            return PacmanRules.getLegalActions(self)
        else:
            return GhostRules.getLegalActions(self, agentIndex)

    def generateSuccessor(self, action):
        """
        Returns the successor state after the specified agent takes the action.
        """
        # Check that successors exist
        if self.isWin() or self.isLose() or self.eventQueue.isEmpty():
            raise Exception('Can\'t generate a successor of a terminal state.')

        time, event = self.eventQueue.peek()
        assert event.isAgentMove(
        ), 'Can only generate successors of a state where an agent is about to move'
        state = self.makeAgentMove(action)
        state.resolveEventsUntilAgentEvent()

        # Book keeping
        GameState.explored.add(self.data)
        GameState.explored.add(state.data)
        return state

    def makeAgentMove(self, action):
        # Copy current state
        state = GameState(self)

        time, event = state.eventQueue.pop()
        agentIndex = event.getAgentIndex()
        agentState = state.data.agentStates[agentIndex]
        state.data.time = time
        delay = agentState.powers.timestepsBetweenMoves
        state.registerEventWithDelay(event, delay)

        # Let agent's logic deal with its action's effects on the board
        if agentIndex == 0:  # Pacman is moving
            state.data._eaten = [False for i in range(state.getNumAgents())]
            PacmanRules.applyAction(state, action)
            state.data.scoreChange -= TIME_PENALTY  # Penalty for waiting around
        else:  # A ghost is moving
            GhostRules.applyAction(state, action, agentIndex)
            GhostRules.decrementTimer(agentState)

        # Resolve multi-agent effects
        GhostRules.checkDeath(state, agentIndex)
        if action == Directions.LASER:
            GhostRules.checkLaserShot(state, agentIndex)
        if action == Directions.BLAST:
            GhostRules.checkBlast(state, agentIndex)

        # Book keeping
        state.data._agentMoved = agentIndex
        # Note:  It is important that the following value accurately
        # reflects when Pacman will make the next move, even if the
        # speed changes (such as a speed-up power pellet).  Otherwise
        # the graphics will do weird things.
        state.data._timeTillAgentMovesAgain = delay
        state.data._action = action
        state.data.score += state.data.scoreChange

        return state

    def runEvent(self):
        # Check that successors exist
        if self.eventQueue.isEmpty():
            raise Exception('Can\'t run an event of a terminal state.')

        time, event = self.eventQueue.pop()
        assert not event.isAgentMove(), 'Can\'t run an AgentMoveEvent'
        self.data.time = time
        event.trigger(self)
        return event

    def getNextEvent(self):
        _, event = self.eventQueue.peek()
        return event

    def getLegalPacmanActions(self):
        return self.getLegalActions(0)

    def getPacmanState(self):
        """
        Returns an AgentState object for pacman (in game.py)

        state.pos gives the current position
        state.direction gives the travel vector
        """
        return self.data.agentStates[0].copy()

    def getPacmanPosition(self):
        return self.data.agentStates[0].getPosition()

    def getPacmanDirection(self):
        return self.data.agentStates[0].getDirection()

    def getGhostStates(self):
        return self.data.agentStates[1:]

    def getGhostState(self, agentIndex):
        if agentIndex == 0 or agentIndex >= self.getNumAgents():
            raise Exception("Invalid index passed to getGhostState")
        return self.data.agentStates[agentIndex]

    def getGhostPosition(self, agentIndex):
        if agentIndex == 0:
            raise Exception("Pacman's index passed to getGhostPosition")
        return self.data.agentStates[agentIndex].getPosition()

    def getGhostPositions(self):
        return [s.getPosition() for s in self.getGhostStates()]

    def getNextAgentIndex(self):
        for time, event in self.eventQueue.getSortedTimesAndEvents():
            if event.isAgentMove():
                return event.getAgentIndex()
        assert False, "No more moves can be made"

    def getAgentMoveTime(self, agentIndex):
        for time, event in self.eventQueue.getSortedTimesAndEvents():
            if event.isAgentMove():
                if event.getAgentIndex() == agentIndex:
                    return time
        assert False, "No more moves can be made by agent " + str(agentIndex)

    def getNumAgents(self):
        return len(self.data.agentStates)

    def getScore(self):
        return float(self.data.score)

    def getCapsules(self):
        """
        Returns a list of positions (x,y) of the remaining capsules.
        """
        return self.data.capsules

    def getNumFood(self):
        return self.data.food.count()

    def getFood(self):
        """
        Returns a Grid of boolean food indicator variables.

        Grids can be accessed via list notation, so to check
        if there is food at (x,y), just call

        currentFood = state.getFood()
        if currentFood[x][y] == True: ...
        """
        return self.data.food

    def getWalls(self):
        """
        Returns a Grid of boolean wall indicator variables.

        Grids can be accessed via list notation, so to check
        if there is a wall at (x,y), just call

        walls = state.getWalls()
        if walls[x][y] == True: ...
        """
        return self.data.walls

    def hasFood(self, x, y):
        return self.data.food[x][y]

    def hasWall(self, x, y):
        return self.data.walls[x][y]

    def isLose(self):
        return self.data._lose

    def isWin(self):
        return self.data._win

    #############################################
    #             Helper methods:               #
    # You shouldn't need to call these directly #
    #############################################

    def __init__(self, prevState=None):
        """
        Generates a new state by copying information from its predecessor.
        """
        if prevState != None:  # Initial state
            self.data = GameStateData(prevState.data)
            self.eventQueue = prevState.eventQueue.deepCopy()
        else:
            self.data = GameStateData()
            self.eventQueue = EventQueue()

    def resolveEventsUntilAgentEvent(self):
        # Resolve any events until the next agent event
        while not self.eventQueue.isEmpty():
            time, event = self.eventQueue.peek()
            if event.isAgentMove():
                return
            else:
                self.runEvent()

    def registerEventWithDelay(self, event, delay):
        self.eventQueue.registerEventAtTime(event, self.data.time + delay)

    def deepCopy(self):
        state = GameState(self)
        state.data = self.data.deepCopy()
        # Event queue has already been copied in the constructor
        return state

    def __eq__(self, other):
        """
        Allows two states to be compared.
        """
        return hasattr(other, 'data') and self.data == other.data \
            and hasattr(other, 'eventQueue') and self.eventQueue == other.eventQueue \

    def __hash__(self):
        """
        Allows states to be keys of dictionaries.
        """
        return hash((self.data, self.eventQueue))

    def __str__(self):

        return str(self.data)

    def initialize(self,
                   layout,
                   pacmanPowers,
                   ghostPowers,
                   numGhostAgents=1000):
        """
        Creates an initial game state from a layout array (see layout.py).
        """
        self.data.initialize(layout, pacmanPowers, ghostPowers, numGhostAgents)
        numAgents = self.getNumAgents()
        for i in range(numAgents):
            self.registerEventWithDelay(AgentMoveEvent(i), i)
        self.registerEventWithDelay(WallTimerEvent(), 1)
class GameState:
    """
    A GameState specifies the full game state, including the food, capsules,
    agent configurations and score changes.

    GameStates are used by the Game object to capture the actual state of the game and
    can be used by agents to reason about the game.

    Much of the information in a GameState is stored in a GameStateData object.  We
    strongly suggest that you access that data via the accessor methods below rather
    than referring to the GameStateData object directly.

    Note that in classic Pacman, Pacman is always agent 0.
    """

    ####################################################
    # Accessor methods: use these to access state data #
    ####################################################

    # static variable keeps track of which states have had getLegalActions called
    explored = set()
    def getAndResetExplored():
        tmp = GameState.explored.copy()
        GameState.explored = set()
        return tmp
    getAndResetExplored = staticmethod(getAndResetExplored)

    def getLegalActions( self, agentIndex=0 ):
        """
        Returns the legal actions for the agent specified.
        """
#        GameState.explored.add(self)
        if self.isWin() or self.isLose(): return []

        if agentIndex == 0:  # Pacman is moving
            return PacmanRules.getLegalActions( self )
        else:
            return GhostRules.getLegalActions( self, agentIndex )

    def generateSuccessor( self, action ):
        """
        Returns the successor state after the specified agent takes the action.
        """
        # Check that successors exist
        if self.isWin() or self.isLose() or self.eventQueue.isEmpty():
            raise Exception('Can\'t generate a successor of a terminal state.')

        time, event = self.eventQueue.peek()
        assert event.isAgentMove(), 'Can only generate successors of a state where an agent is about to move'
        state = self.makeAgentMove(action)
        state.resolveEventsUntilAgentEvent()

        # Book keeping
        GameState.explored.add(self.data)
        GameState.explored.add(state.data)
        return state

    def makeAgentMove( self, action ):
        # Copy current state
        state = GameState(self)

        time, event = state.eventQueue.pop()
        agentIndex = event.getAgentIndex()
        agentState = state.data.agentStates[agentIndex]
        state.data.time = time
        delay = agentState.powers.timestepsBetweenMoves
        state.registerEventWithDelay(event, delay)

        # Let agent's logic deal with its action's effects on the board
        if agentIndex == 0:  # Pacman is moving
            state.data._eaten = [False for i in range(state.getNumAgents())]
            PacmanRules.applyAction( state, action )
            state.data.scoreChange -= TIME_PENALTY # Penalty for waiting around
        else:                # A ghost is moving
            GhostRules.applyAction(state, action, agentIndex)
            GhostRules.decrementTimer(agentState)

        # Resolve multi-agent effects
        GhostRules.checkDeath( state, agentIndex )
        if action == Directions.LASER:
            GhostRules.checkLaserShot(state,agentIndex)
        if action == Directions.BLAST:
            GhostRules.checkBlast(state,agentIndex)

        # Book keeping
        state.data._agentMoved = agentIndex
        # Note:  It is important that the following value accurately
        # reflects when Pacman will make the next move, even if the
        # speed changes (such as a speed-up power pellet).  Otherwise
        # the graphics will do weird things.
        state.data._timeTillAgentMovesAgain = delay
        state.data._action = action
        state.data.score += state.data.scoreChange

        return state

    def runEvent( self ):
        # Check that successors exist
        if self.eventQueue.isEmpty():
            raise Exception('Can\'t run an event of a terminal state.')

        time, event = self.eventQueue.pop()
        assert not event.isAgentMove(), 'Can\'t run an AgentMoveEvent'
        self.data.time = time
        event.trigger(self)
        return event

    def getNextEvent( self ):
        _, event = self.eventQueue.peek()
        return event

    def getLegalPacmanActions( self ):
        return self.getLegalActions( 0 )

    def getPacmanState( self ):
        """
        Returns an AgentState object for pacman (in game.py)

        state.pos gives the current position
        state.direction gives the travel vector
        """
        return self.data.agentStates[0].copy()

    def getPacmanPosition( self ):
        return self.data.agentStates[0].getPosition()

    def getPacmanDirection(self):
        return self.data.agentStates[0].getDirection()

    def getGhostStates( self ):
        return self.data.agentStates[1:]

    def getGhostState( self, agentIndex ):
        if agentIndex == 0 or agentIndex >= self.getNumAgents():
            raise Exception("Invalid index passed to getGhostState")
        return self.data.agentStates[agentIndex]

    def getGhostPosition( self, agentIndex ):
        if agentIndex == 0:
            raise Exception("Pacman's index passed to getGhostPosition")
        return self.data.agentStates[agentIndex].getPosition()

    def getGhostPositions(self):
        return [s.getPosition() for s in self.getGhostStates()]

    def getNextAgentIndex(self):
        for time, event in self.eventQueue.getSortedTimesAndEvents():
            if event.isAgentMove():
                return event.getAgentIndex()
        assert False, "No more moves can be made"

    def getAgentMoveTime(self, agentIndex):
        for time, event in self.eventQueue.getSortedTimesAndEvents():
            if event.isAgentMove():
                if event.getAgentIndex() == agentIndex:
                    return time
        assert False, "No more moves can be made by agent " + str(agentIndex)

    def getNumAgents( self ):
        return len( self.data.agentStates )

    def getScore( self ):
        return float(self.data.score)

    def getCapsules(self):
        """
        Returns a list of positions (x,y) of the remaining capsules.
        """
        return self.data.capsules

    def getNumFood( self ):
        return self.data.food.count()

    def getFood(self):
        """
        Returns a Grid of boolean food indicator variables.

        Grids can be accessed via list notation, so to check
        if there is food at (x,y), just call

        currentFood = state.getFood()
        if currentFood[x][y] == True: ...
        """
        return self.data.food

    def getWalls(self):
        """
        Returns a Grid of boolean wall indicator variables.

        Grids can be accessed via list notation, so to check
        if there is a wall at (x,y), just call

        walls = state.getWalls()
        if walls[x][y] == True: ...
        """
        return self.data.walls

    def hasFood(self, x, y):
        return self.data.food[x][y]

    def hasWall(self, x, y):
        return self.data.walls[x][y]

    def isLose( self ):
        return self.data._lose

    def isWin( self ):
        return self.data._win

    #############################################
    #             Helper methods:               #
    # You shouldn't need to call these directly #
    #############################################

    def __init__( self, prevState = None ):
        """
        Generates a new state by copying information from its predecessor.
        """
        if prevState != None: # Initial state
            self.data = GameStateData(prevState.data)
            self.eventQueue = prevState.eventQueue.deepCopy()
        else:
            self.data = GameStateData()
            self.eventQueue = EventQueue()

    def resolveEventsUntilAgentEvent(self):
        # Resolve any events until the next agent event
        while not self.eventQueue.isEmpty():
            time, event = self.eventQueue.peek()
            if event.isAgentMove():
                return
            else:
                self.runEvent()

    def registerEventWithDelay(self, event, delay):
        self.eventQueue.registerEventAtTime(event, self.data.time + delay)

    def deepCopy( self ):
        state = GameState( self )
        state.data = self.data.deepCopy()
        # Event queue has already been copied in the constructor
        return state

    def __eq__( self, other ):
        """
        Allows two states to be compared.
        """
        return hasattr(other, 'data') and self.data == other.data \
            and hasattr(other, 'eventQueue') and self.eventQueue == other.eventQueue \

    def __hash__( self ):
        """
        Allows states to be keys of dictionaries.
        """
        return hash( (self.data, self.eventQueue) )

    def __str__( self ):

        return str(self.data)

    def initialize( self, layout, pacmanPowers, ghostPowers, numGhostAgents=1000 ):
        """
        Creates an initial game state from a layout array (see layout.py).
        """
        self.data.initialize(layout, pacmanPowers, ghostPowers, numGhostAgents)
        numAgents = self.getNumAgents()
        for i in range(numAgents):
            self.registerEventWithDelay(AgentMoveEvent(i), i)
        self.registerEventWithDelay(WallTimerEvent(), 1)