0

I have made a treasure hunt game, and I need it so that once a square containing a treasure chest has been visited 3 times it turns into a 'bandit'. In order to covunt the number of times a treasure chest has been visited, I added another lot of the same coordinates to the list of TreasureChestCoordinates. Then I plan to have an if statement so that if any of the coordinates are written 3 times, all 3 will be removed and put in the 'bandit' list. Here's my draft code for the section:

            # Treasure Chests Collecting Coins #
        if (x,y) in TreasureCoords[0:(TCNumber -1)]:
            print("You have landed on a treasure chest! You can visit it 2 more times before it becomes a bandit.")
            CoinCollection = CoinCollection + 10
            TreasureCoords.append(x,y)

        #if TreasureCoords.count(any item) > 3:
            #remove all copies of item from list
            #add item to bandit list

x,y means the coordinates the user is currently in. CoinCollection is a seperate variable that changes when the user lands on a treasure chest or bandit.By the way, the number of coordinates is unlimited because the user decides that earlier on in the game. So, how can I duplicate my list of coordinates, remove them once they are in the list 3 times and put them in a new list? I presume this is the easiest way to 'count' how many times the user has been on a square, and change the treasure chest to a bandit.

3
  • No, this sounds like an unnecessarily complicated way of doing it. It would be simpler to just keep a mapping from coordinate to number of visits. Commented Feb 7, 2017 at 18:43
  • Also, the number of coordinates you have in your list cannot be "unlimited" because you don't have unlimited memory... Commented Feb 7, 2017 at 18:44
  • Sorry was just trying to illustrate my point - as you can probably tell I'm not a particularly advanced coder... How would you solution work? Commented Feb 7, 2017 at 18:49

2 Answers 2

1

First... you don't need to search the list for any coordinate present three times. That's wasteful. If you remove them once that happens, then the only coordinate that can possibly be present three times is the one you just visited.

If you really want to do it as shown in your question, just do something like while (x,y) in TreasureCoords: TreasureCoords.remove((x,y)). However, it would probably be easier to use a dict. You can probably avoid having separate variables, even. Assuming that ItemCoords is initially filled with coordinates that represent unvisited treasure chests:

ItemCoords[(x,y)] = 0 # add a treasure

...then you can just look at how many times the treasure is visited:

visits = ItemCoords.get((x,y), None)
if visits is None:
    pass # nothing there
else if visits > 3:
    fightBandit() # ...or whatever
else:
    print("You have landed on a treasure chest! You can visit it %i more times before it becomes a bandit." % (2 - visits))
    CoinCollection += 10
    ItemCoords[(x,y)] += 1

This is still simplistic. You probably want a more object-oriented approach as hinted at by Christian:

class Treasure:
    def __init__(x,y):
        self.x = x
        self.y = y
        self.visits = 0

    def visit():
        print("You have landed on a treasure chest! You can visit it %i more times before it becomes a bandit." % (2 - visits))    
        CoinCollection += 10

        if visits == 3:
            world[(self.x, self.y)] = Bandit(self.x, self.y)

class Bandit:
    def __init__(x,y):
        self.x = x
        self.y = y

    def visit():
        # Replace this with whatever happens when the player meets a bandit
        print("You have been eaten by a grue.")
        sys.exit(0)

# Initialize the world
for n in range(NumberOfTreasure):
    # get x,y somehow, e.g. random
    world[(x,y)] = Treasure(x,y)

# ...code for player wandering around...
here = world.get((x,y), None)
if here is not None:
    here.visit()
Sign up to request clarification or add additional context in comments.

5 Comments

I implemented your 1st code, and changed itemCoords to TreasureCoords, which is the list name that stores all the treasure chest coordinates. However when I played the game, this error appeared "TreasureCoords[(x,y)] = 0 TypeError: list indices must be integers, not tuple" can you help/do you know what this means?
You probably initialized TreasureCoords like = [], which makes it a list. My modified code uses a dict instead, so you need to initialize it like = {} or = dict().
Ok. Does that mean I need to change all my other lists into dictionaries too? Will I need to change anything else, or does everything work the same with a dictionary?
It depends how you use them; a list is... well, a list. It has items, they are in some order, you can access them by index. A dict is a map. Maps in general may or may not present their items as being in any particular order, but each item has an associated key, and you look up items by key. The key in this case is the location of the item in the world.
Currently, my TreasureCoords and BanditCoords are lists, as they both have 'A' amount of values for the X coordinates and 'B' amount of values for the Y coordinates to determine their position. By changing them into dictionaries, I don't think this would be beneficial as I would have to then determine a key - and as the number of values in the (current) list is set by the user, this could be very complicated. What do you suggest? Your second code would be a lot harder to implement into my current code, so I'd rather not use that.
0

I think this is a case where an object would be beneficial - instead of tracking separate lists with facts about the same thing, use an list of objects which store all relevant information.

Could look like this:

class Monster(object):
    #define like you like it
    pass

class Treasure(object):
   def init(x, y):
      self.x = x
      self.y = y
      self.visits = 0

    def visit():
        self.visits += 1

        if self.visits >= 3:
            return Monster()
        else:
            return 10


calling code:
    treasure = Treasure(1,1)
    rv = treasure.visit()
    if isinstance(rv, Monster):
        # lets the monster rip him to shreds
    else:
        CoinCollection +=treasure.visit()

2 Comments

Can I still use that code without knowing how many treasure chests there are? The user sets the number of treasure chests elsewhere in the code.
Of course - you would have to create a list of Treasures of a similar length. Honestly, that's the critical skill your software course tries to teach you - how to structure a big program which consists of modular pieces which work in concert to achieve a goal.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.