Example #1
0
class ItemSetTest(unittest.TestCase):
    """
    Tests ItemSet class.
    """
    INITIAL_COUNT = 3
    INITIAL_WEIGHT = 4

    def setUp(self):
        from items.item import Item
        from items.item_set import ItemSet

        sword = Item("sword", "made by elves", 2)
        helmet = Item("helmet", "made by men", 1)
        potion = Item("potion", "restores health", 1)

        self._itemList = [sword, helmet, potion]
        self._items = ItemSet([sword, helmet, potion])

    def tearDown(self):
        self._itemList = self._items = None

    def testInitItemSet(self):
        errorMsg = "ItemSet object has more objects than it was given " \
                    "during initialization."
        self.assertEqual(len(self._items._items), ItemSetTest.INITIAL_COUNT,
                         errorMsg)

        errorMsg = "ItemSet object does not include all objects given " \
                    "during initialization."
        for item in self._itemList:
            self.assertTrue(item in self._items._items, errorMsg)

    def testCountItems(self):
        expectedCount = ItemSetTest.INITIAL_COUNT
        actualCount = self._items.count()

        errorMsg = "Actual count and expected count different for ItemSet object."
        self.assertEqual(expectedCount, actualCount, errorMsg)

    def testAddRemoveContainsItems(self):
        from items.item import Item
        antidote = Item("antidote", "cures poison", 1)

        #Verify item not included in collection
        errorMsg = "ItemSet.containsItem() claimed to contain item not present."
        self.assertFalse(self._items.containsItem(antidote), errorMsg)

        #Add item
        self._items.addItem(antidote)

        errorMsg = "ItemSet.containsItem() failed to identify existing item."
        self.assertTrue(self._items.containsItem(antidote), errorMsg)

        #Remove item
        self._items.removeItem(antidote)

        errorMsg = "ItemSet.containsItem() claimed to contain item not present."
        self.assertFalse(self._items.containsItem(antidote), errorMsg)

    def testItemsWeight(self):
        from items.item import Item

        errorMsg = "Initial weight of ItemSet object incorrect."
        expectedWeight = ItemSetTest.INITIAL_WEIGHT
        actualWeight = self._items.weight()
        self.assertEqual(expectedWeight, actualWeight, errorMsg)

        heavyRock = Item("heavy rock", "weighs a ton", 2000)

        #Add item
        self._items.addItem(heavyRock)

        errorMsg = "ItemSet.weight() reported incorrect weight."
        expectedWeight += 2000
        actualWeight = self._items.weight()
        self.assertEqual(expectedWeight, actualWeight, errorMsg)

        #Remove item
        self._items.removeItem(heavyRock)

        expectedWeight -= 2000
        actualWeight = self._items.weight()
        self.assertEqual(expectedWeight, actualWeight, errorMsg)

    def testItemSetIter(self):
        #Verify iterator returns by ItemSet object visits the exact
        #collection of objects added to ItemSet

        #(Implicitly) use iterator in for loop
        for item in self._items:
            #Verify item returned is recognized
            errorMsg = "ItemSet iterator returned unrecognized object."
            self.assertTrue(item in self._itemList, errorMsg)

            #Remove item from original list of items
            self._itemList.remove(item)

        #Assert all items are accounted for
        errorMsg = "ItemSet object contained Item not added during initialization."
        self.assertEqual(len(self._itemList), 0, errorMsg)
Example #2
0
class Space(object):
    """
    A given location on the map. Connects with other spaces
    to form larger geographic areas.
    """
    def __init__(self, name, description, items = None, city = None, uniquePlaces = None):
        """
        Initialize a Space object.

        @param name:            Name of space.
        @param description:     Description of space.

        @keyword items:         (Optional) Items found in the space.
                                May be a reference to a single item or an ItemSet.
        @keyword city:          (Optional) Reference to unique place(s).
                                May be a reference to an object or a list.
        @keyword uniquePlaces:  (Optional) Reerence to city/cities. 
                                May be a reference to an object or a list.

        """
        self._exits = { Direction.NORTH : None,
                        Direction.SOUTH : None,
                        Direction.EAST : None,
                        Direction.WEST : None }

        self._name = name
        self._description = description
        #TODO: Need to add items passed into method; items is currently ignored.
        #      Will need to check if items refers to single object or to an ItemSet.
        #      If it points to an ItemSet, you can just set self._items to that ItemSet. 
        #      (self._items = items)
        self._items = ItemSet()
        self._city = city
        self._uniquePlaces = uniquePlaces

    def getName(self):
        """
        Returns the name of the room.

        @return:    Name of the room.
        """
        return self._name

    def getDescription(self):
        """
        Returns description of the room.

        @return:    Description of room.
        """
        return self._description
        
    def getItems(self):
        """
        Returns a string of times.

        @return:    Items in Space (as ItemSet).
        """
        return self._items
        
    def addItem(self, item):
        """
        Adds an item to the room.

        @param item:    Item to add.
        """
        self._items.addItem(item)

    def removeItem(self, item):
        """
        Removes an item from the room.

        @param item:    Item to remove.
        """
        self._items.removeItem(item)

    def containsItem(self, item):
        """
        Determines if room contains an item.

        @param item:    Item object to search for.

        @return:    True if item is contained in Space, False otherwise.
        """
        return self._items.containsItem(item)

    def containsItemString(self, string):
        """
        Determines if room contains an item.

        @param item:     The string associated with the name of the item that we are looking for.

        @return:    True if item is contained in Space, False otherwise.
        """
        #TODO: Use ItemSet's containsItemWithName() instead here. 

        for item in self._items:
            if item.getName() == string:
                return True
            
        return False
    
    def getCity(self):
        """
        Returns city object.

        @return:    Reference to cit(ies).
                    May be reference to single city or list of cities.
        """
        return self._city

    def getUniquePlace(self):
        """
        Returns uniquePlace object(s).

        @return:    Reference to unique place(s).
                    May be reference to single unique place or list of unique places.
        """
        return self._uniquePlaces

    def createExit(self, direction, space, outgoingOnly = False):
        """
        Create an exit to another space. By default,
        the method creates the appropriate exit
        in the second space. (This can be suppressed, however,
        using I{outgoingOnly}).

        @param direction:       Direction of exit.
        @param space:           Adjacent space.
        @keyword outgoingOnly:  By default, this method creates the appropriate
                                exit in the second space. Set I{outgoingOnly}
                                to False to supress this behavior.
        """
        #Make sure a valid direction has been specified
        if not self._isExit(direction):
            errorMsg = "Direction not valid: %s" % direction 
            raise AssertionError(errorMsg)

        #Set exit to other space
        self._exits[direction] = space

        #Create exit from other space to this space
        if not outgoingOnly:
            oppositeDirection = self._oppositeDirection(direction)
            space._exits[oppositeDirection] = self

    def clearExit(self, direction, outgoingOnly):
        """
        Removes an exit to another space. By default,
        the method removes the appropriate exit from
        the second space. (This can be suppressed, however,
        using I{outgoingOnly}).

        @param direction:       Direction of exit.
        @keyword outgoingOnly:  By default, this method removes the appropriate
                                exit from the second space. Set I{outgoingOnly}
                                to False to suppress this behavior.
        """
        #Make sure a valid direction has been specified
        if not self._isExit(direction):
            errorMsg = "Direction not valid: %s" % direction 
            raise AssertionError(errorMsg)

        #If exit has not been set, there is nothing to do
        if self._exits[direction] == None:
            return

        #Create a temporary copy of adjacent space
        adjSpace = self._exits[direction]

        #Clear exit from this space
        self._exits[direction] = None

        #Clear exit from other space to this space
        if not outgoingOnly:
            oppositeDirection = self._oppositeDirection(direction)
            adjSpace._exits[oppositeDirection] = None

    def getExit(self, direction):
        """
        Returns a reference to an adjacent space.
        Returns None if no space exists in given direction.

        @param direction:   Direction of adjacent space.
                            Must be one of the directions defined in
                            constants.Direction.
        
        @return:            Reference to space in given direction.
                            (Returns None if no exit is defined
                            for given direction).
        """
        space = self._exits[direction]
        return space

    def _isExit(self, exit):
        """
        Makes sure that a string represents a valid exit.

        @param direction:   Name of exit.

        @return:            True if valid exit, False otherwise.
        """
        availableExits = self._exits.keys()
        if exit not in availableExits:
            return False
        return True

    def _oppositeDirection(self, direction):
        """
        Returns the opposite direction. (e.g. North is opposite of South)

        @param direction:   A direction (from constants.Direction)
        
        @return:            Opposite direction (from constants.Direction)
        """
        if direction == Direction.NORTH:
            return Direction.SOUTH
        elif direction == Direction.SOUTH:
            return Direction.NORTH
        elif direction == Direction.EAST:
            return Direction.WEST
        elif direciton == Direction.WEST:
            return Direction.EAST
        else:
            raise AssertionError("Not a valid direction: %s" % direction)
Example #3
0
class Space(object):
    """
    A given location on the map. Connects with other spaces
    to form larger geographic areas.
    """
    def __init__(self, name, description, region, battleProbability = 0, 
    battleBonusDifficulty = 0, items = None, city = None, uniquePlace = None):
        """
        Initialize a Space object.

        @param name:                   Name of space.
        @param description:            Description of space.
        @param battleProbability:      Probability between [0, 1] that a 
                                       random battle will occur between 
                                       successive game command executions.
        @param battleBonusDifficulty:  Probability between [0, 1] that is used 
                                       to determine battle bonus difficulty. 
                                       This stat results in a percentage 
                                       increase over default monster stats and 
                                       number for any given space.
                                       
                                       For instance, if bonus difficulty is 
                                       set to .5, space will spawn 50% more 
                                       monsters with 150% base stats.
                                       
        @keyword items:                (Optional) Items found in the space.
                                       May be a reference to a single item or 
                                       an ItemSet.
        @keyword city:                 (Optional) City objects in space. May 
                                       be a reference to an individual object 
                                       or a list.
        @keyword uniquePlace:          (Optional) Reference to unique places 
                                       in space. May be a reference to an 
                                       individual object or a list.
        """
        self._exits = {Direction.NORTH : None,
                       Direction.SOUTH : None,
                       Direction.EAST : None,
                       Direction.WEST : None}

        self._name = name
        self._description = description
        self._region = region
        self._battleProbability = battleProbability
        self._battleBonusDifficulty = battleBonusDifficulty
        self._items = ItemSet()
        self._city = city
        self._uniquePlace = uniquePlace

    def getName(self):
        """
        Returns the name of the space.

        @return:    Name of the space.
        """
        return self._name

    def getDescription(self):
        """
        Returns description of space.

        @return:    Description of space.
        """
        return self._description
        
    def getRegion(self):
        """
        Returns the region of the space.
        
        @return:    The region of space.
        """
        return self._region
        
    def getItems(self):
        """
        Returns a string of times.

        @return:    Items in Space (as ItemSet).
        """
        return self._items
        
    def addItem(self, item):
        """
        Adds an item to the space.

        @param item:    Item to add.
        """
        #Special prompt for theOneRing
        if item == theOneRing and self._name != "Orodruin":
            print "\nYou see some strange men walk by."
            return
            
        if isinstance(item, Item):
            self._items.addItem(item)
        elif isinstance(item, list):
            self._items.addItems(item)
        else:
            errorMsg = "space.AddItem() was given invalid item type."
            raise AssertionError(errorMsg)

    def removeItem(self, item):
        """
        Removes an item from the space.

        @param item:    Item to remove.
        """
        self._items.removeItem(item)

    def containsItem(self, item):
        """
        Determines if space contains an item.

        @param item:    Item object to search for.

        @return:    True if item is contained in 
                    Space, False otherwise.
        """
        return self._items.containsItem(item)

    def containsItemString(self, string):
        """
        Determines if space contains an item.

        @param string:   The name-string of 
                         the target item.

        @return:    True if item is contained 
                    in space, False otherwise.
        """ 
        return        self._items.containsItemWithName(string)
    
    def getCity(self):
        """
        Returns city object/objects.

        @return:    Reference to cit(ies).
                    May refer to a single city or list of cities.
        """
        return self._city

    def getUniquePlace(self):
        """
        Returns uniquePlace object(s).

        @return:    Reference to unique place(s).
                    May be reference to a single unique
                    place or a list of unique places.
        """
        return self._uniquePlace

    def getBattleProbability(self):
        """
        Returns probability of a random battle.

        @return:    The probability that a random
                    battle occurs.
        """
        return self._battleProbability

    def getBattleBonusDifficulty(self):
        """
        Returns bonus difficulty attribute of space.

        @return:    The difficulty parameter of space.
        """
        return self._battleBonusDifficulty

    def createExit(self, direction, space, outgoingOnly = False):
        """
        Create an exit to another space. By default, the method creates the 
        appropriate exit in the second space. (This can be suppressed, however, 
        using I{outgoingOnly}).
        
        Spaces can have multiple spaces per direction.

        @param direction:       Direction of exit.
        @param space:           Adjacent space.
        @keyword outgoingOnly:  By default, this method creates the appropriate
                                exit in the second space. Set I{outgoingOnly}
                                to False to suppress this behaviour.
        """
        #Make sure a valid direction has been specified
        if not self._isExit(direction):
            errorMsg = "Direction not valid: %s" % direction
            raise AssertionError(errorMsg)
        
        #Set exit to other space - if a space already exists
        if self._exits[direction]:
            currentSpace = self._exits[direction]
            #If multiple spaces already exist in that direction
            if isinstance(self._exits[direction], list):
                currentSpace.append(space)
            #If a single space exists in that direction
            else:
                self._exits[direction] = [currentSpace, space]
        #If no space already exists
        else:
            self._exits[direction] = space

        #Create exit from other space to this space
        if not outgoingOnly:
            oppositeDirection = self._oppositeDirection(direction)
            #outgoingOnly = True as to not create an infinite loop
            space.createExit(oppositeDirection, self, outgoingOnly = True)

    def clearExit(self, direction, outgoingOnly, space = None):
        """
        Removes an exit to another space. By default, the method removes the 
        appropriate exit from the second space. (This can be suppressed, 
        however, using I{outgoingOnly}).

        @param direction:       Direction of exit.
        @keyword outgoingOnly:  By default, this method removes the appropriate
                                exit from the second space. Set I{outgoingOnly}
                                to False to suppress this behavior.
        """
        #Make sure a valid direction has been specified
        if not self._isExit(direction):
            errorMsg = "Direction not valid: %s" % direction
            raise AssertionError(errorMsg)

        #If exit has not been set, there is nothing to do
        if self._exits[direction] == None:
            return
    
        #Create a temporary copy of adjacent space
        adjSpace = self._exits[direction]
        
        if isinstance(self._exits[direction], list):
            self._exits[direction].remove(space)
        else:
            self._exits[direction] = None
            
        if not outgoingOnly:
            oppositeDirection = self._oppositeDirection(direction)
            adjSpace.clearExit(oppositeDirection, True, space = self)

    def getExit(self, direction):
        """
        Returns a reference to an adjacent space.
        Returns None if no space exists in given direction.

        @param direction:   Direction of adjacent space.
                            Must be one of the directions defined in
                            constants.Direction.
        
        @return:            Reference to space in given direction.
                            (Returns None if no exit is defined
                            for given direction).
        """
        space = self._exits[direction]
        return space

    def getExits(self):
        """
        Returns dictionary of direction-space pairs.

        @return:            Dictionary of direction-space pairs.
        """
        return self._exits

    def _isExit(self, exit):
        """
        Makes sure that a string represents a valid exit.

        @param direction:   Name of exit.

        @return:            True if valid exit, False otherwise.
        """
        availableExits = self._exits.keys()
        if exit not in availableExits:
            return False
            
        return True

    def _oppositeDirection(self, direction):
        """
        Returns the opposite direction. (e.g. North is opposite of South)

        @param direction:   A direction (from constants.Direction)
        
        @return:            Opposite direction (from constants.Direction)
        """
        if direction == Direction.NORTH:
            return Direction.SOUTH
        elif direction == Direction.SOUTH:
            return Direction.NORTH
        elif direction == Direction.EAST:
            return Direction.WEST
        elif direction == Direction.WEST:
            return Direction.EAST
        else:
            raise AssertionError("Not a valid direction: %s" % direction)
Example #4
0
class ItemSetTest(unittest.TestCase):
    """
    Tests ItemSet class.
    """
    INITIAL_COUNT = 3
    INITIAL_WEIGHT = 4

    def setUp(self):
        from items.item import Item
        from items.item_set import ItemSet

        sword = Item("sword", "made by elves", 2)
        helmet = Item("helmet", "made by men", 1)
        potion = Item("potion", "restores health", 1)

        self._itemList = [sword, helmet, potion]
        self._items = ItemSet([sword, helmet, potion])

    def tearDown(self):
        self._itemList = self._items = None

    def testInitItemSet(self):
        errorMsg = "ItemSet object has more objects than it was given " \
                    "during initialization."
        self.assertEqual(len(self._items._items), ItemSetTest.INITIAL_COUNT, errorMsg)

        errorMsg = "ItemSet object does not include all objects given " \
                    "during initialization."
        for item in self._itemList:
            self.assertTrue(item in self._items._items, errorMsg)

    def testCountItems(self):
        expectedCount = ItemSetTest.INITIAL_COUNT
        actualCount = self._items.count()
        
        errorMsg = "Actual count and expected count different for ItemSet object."
        self.assertEqual(expectedCount, actualCount, errorMsg)

    def testAddRemoveContainsItems(self):
        from items.item import Item
        antidote = Item("antidote", "cures poison", 1)

        #Verify item not included in collection
        errorMsg = "ItemSet.containsItem() claimed to contain item not present."
        self.assertFalse(self._items.containsItem(antidote), errorMsg)

        #Add item
        self._items.addItem(antidote)

        errorMsg = "ItemSet.containsItem() failed to identify existing item." 
        self.assertTrue(self._items.containsItem(antidote), errorMsg)

        #Remove item
        self._items.removeItem(antidote)

        errorMsg = "ItemSet.containsItem() claimed to contain item not present."
        self.assertFalse(self._items.containsItem(antidote), errorMsg)

    def testItemsWeight(self):
        from items.item import Item 

        errorMsg = "Initial weight of ItemSet object incorrect."
        expectedWeight = ItemSetTest.INITIAL_WEIGHT
        actualWeight = self._items.weight()
        self.assertEqual(expectedWeight, actualWeight, errorMsg)

        heavyRock = Item("heavy rock", "weighs a ton", 2000)

        #Add item
        self._items.addItem(heavyRock)

        errorMsg = "ItemSet.weight() reported incorrect weight." 
        expectedWeight += 2000
        actualWeight = self._items.weight()
        self.assertEqual(expectedWeight, actualWeight, errorMsg)

        #Remove item
        self._items.removeItem(heavyRock)

        expectedWeight -= 2000
        actualWeight = self._items.weight()
        self.assertEqual(expectedWeight, actualWeight, errorMsg)

    def testItemSetIter(self):
        #Verify iterator returns by ItemSet object visits the exact
        #collection of objects added to ItemSet

        #(Implicitly) use iterator in for loop
        for item in self._items:
            #Verify item returned is recognized
            errorMsg = "ItemSet iterator returned unrecognized object."
            self.assertTrue(item in self._itemList, errorMsg)

            #Remove item from original list of items
            self._itemList.remove(item)

        #Assert all items are accounted for
        errorMsg = "ItemSet object contained Item not added during initialization."
        self.assertEqual(len(self._itemList), 0, errorMsg)