IronFlame
IronFlame

Reputation: 29

Item class in Text Adventure Game (Python)

I am making a text adventure game in python. I have most of the basic items setup such as linking locations and a save feature. (I had a little bit of difficulty setting up the save features, so if there is a better way please tell me).

Now I want to make items. Specifically I want the item to be in a location (maybe linked to it the same way other locations are linked to each other), and when the player interacts with them, (e.g. picks it up) they location that had the item is updated. I want the user to have to type in the command and recognize that they need the item, and not have the item picked up passively once they enter an area. (The shop is also non-functional, and it would be good if you could give me pointers on how best to do it + maintain the player's inventory)

I know this would include a lot of stuff, such as a new class, and some new functions that dictate specifically what commands will work. I have taken a shot at it, but quickly ran into a wall. If any of you could help me, that would be awesome. (Also, it there is a better/faster way to do something, point it out and I'll consider adding it).

Here is the code:

import pickle
import time

# Constants/Valid Commands
# This is a mess, ignore it unless it causes a problem.

invalidChars = '\"\'()*&^%$#@!~`-=_+{}[]\|:;<,>.?/'
validLogin = 'log in', 'log', 'saved', 'in', 'load', 'logging in', 'load game', 'load'
validNewGame = 'new', 'new game', 'new save'
directions = ['north', 'south', 'east', 'west'] 
possibleGenders = ['boy', 'girl']
examineCommands = ['examine yourself', 'look at yourself', 'my stats', 'my statistics', 'stats', 'statistics', 'examine statistics', 'examine stats']
invalidExamine = ['examine', 'look at' ]
stop = ['stop', 'exit', 'cancel']



# FUNCTIONS

def start():


  print("Welcome to XXXXX, created by Ironflame007") #XXXX is the name placeholder. I haven't decided what it will be yet
  while True:
    command = input("Are you making a new game, or logging in?\n> ")
    if command in validNewGame:
      clear()
      newGame()
      break
    elif command in validLogin:
      clear()
      login()
      break
    else:
      clear()
      print("Thats not a valid command. If you wish to exit, type exit\n")



def newGame():
  while True:
    username = input('Type in your username. If you wish to exit, type exit\n> ')
    if username[0] in invalidChars:
      clear()
      print('Your username can\'t start with a space or any other type of misc. character. Just letters please')
    elif username in stop:
      clear()
      start()
    else:
      break

  password = input('Type in your password\n> ')
  playerName = input("What is your character's name?\n> ")

  while True:
    playerGender = input("Is your character a boy or a girl?\n> ".lower())
    if playerGender not in possibleGenders:
      print("That's not a valid gender...")
    else:
      clear()
      break

  inventory = []
  health = 100
  player = Player(playerName, playerGender, 0, 1, inventory, health, password)

  file = username + '.pickle'
  pickle_out = open(file, 'wb')
  pickle.dump(player.player_stats, pickle_out)
  pickle_out.close()


  print("You wake up. You get off of the ground... dirt. You didn't fall asleep on dirt. You look around an observe your surroundings\n(If you need help, use the command help)") # hasn't been made yet

  game('default', username, player.player_stats)





def examine(string, dictionary):
  if string in examineCommands:
    print(dictionary)
  elif string in invalidExamine:
    print('There is nothing to {0}'.format(string))
  else:
    print('Thats an invalid command')



def clear():
  print('\n' * 50)

def game(startLoc, username, dictionary):
  if startLoc == 'default':
    currentLoc = locations['woods']
  else:
    currentLoc = dictionary['location']

  while True:
    print(currentLoc.description)
    for linkDirection,linkedLocation in currentLoc.linkedLocations.items():
      print(linkDirection + ': ' + locations[linkedLocation].name)
    command = input("> ").lower()
    if command in directions:
      if command not in currentLoc.linkedLocations:
        clear()
        print("You cannot go this way")
      else:
        newLocID = currentLoc.linkedLocations[command]
        currentLoc = locations[newLocID]
        clear()
    else:
      clear()
      if command in examineCommands:
        examine(command, dictionary)
      elif command in invalidExamine:
        examine(command, dictionary)
      elif command == 'log out':
        logout(username, dictionary, currentLoc)
        break
      else:
        print('That\'s an invalid command.')
        print("Try one of these directions: {0}\n If you are trying to log out, use the command log out.".format(directions))


def login():
  while True:
    while True:
      print('If you wish to exit, type exit or cancel')
      username = input("What is your username\n> ")
      if username in stop:
        clear()
        start()
        break
      else:
        break
    inputPass = input("What is your password\n> ")
    try:
      filename = username + '.pickle'
      pickle_in = open(filename, 'rb') 
      loaded_stats = pickle.load(pickle_in, )
      if loaded_stats['password'] == inputPass:
        clear()
        print("Your game was succesfully loaded")
        game('location', username, loaded_stats)
        break
      else:
        clear()
        print("That's an invalid username or password.")
    except:
      clear()
      print("Thats an invalid username or password.")



def logout(username, dictionary, currentLoc):
  print("Please don't close the window, the programming is saving.")
  dictionary.update({'location': currentLoc})
  file = username + '.pickle'
  pickle_out = open(file, 'wb')
  pickle.dump(dictionary, pickle_out)
  pickle_out.close()
  time.sleep(3)
  print("Your game has been saved. You may close the window now")


class Location:
  def __init__(self, name, description):
    self.name = name
    self.description = description
    self.linkedLocations = {} # stores linked locations in this dictionary

  def addLink(self, direction, destination):
    # adds link to the linked locations dictionary (assuming the direction and destination are valid)
    if direction not in directions:
      raise ValueError("Invalid Direction")
    elif destination not in locations:
      raise ValueError("Invalid Destination")
    else:
      self.linkedLocations[direction] = destination


class Player:

  def __init__(self, name, gender, gold, lvl, inventory, health, password):
    self.name = name
    self.gender = gender
    self.gold = gold
    self.lvl = lvl
    self.inventory = inventory
    self.health = health
    self.player_stats = {'name': name, 'gender': gender, 'gold': gold, 'lvl': lvl, 'inventory': inventory, 'health': health, 'password': password, 'location': 'default'}

# ACTUALLY WHERE THE PROGRAM STARTS

locations = {'woods': Location("The Woods", "You are surrounded by trees. You realize you are in the woods."),
'lake': Location("The Lake", "You go north and are at the lake. It is very watery."),
'town': Location("The Town", "You go north, and find yourself in town."),
'shop': Location("The Shop", "You go east, and walk into the shop. The shop owner asks what you want")
} 



locations['woods'].addLink('north', 'lake')
locations['lake'].addLink('south', 'woods')
locations['lake'].addLink('north', 'town')
locations['town'].addLink('south', 'lake')
locations['town'].addLink('east', 'shop')
locations['shop'].addLink('west', 'town')




start()

Upvotes: 0

Views: 2379

Answers (1)

Balakrishnan Rajan
Balakrishnan Rajan

Reputation: 195

As for picking things up you can have a method in the player class that appends the item to the inventory list of the player. If you want the item to be in a particular location, you can have a list of items available at location that can be accessed via the examine function.

So, in Class Location: you can add Class Location:

def __init__(self, name, description):
    self.name = name
    self.description = description
    self.linkedLocations = {} # stores linked locations in this dictionary
    self.items = items        # List of items on location

In Class Player: you can add,

Class Player:

def PickUp(self, Location, item):
    Location.items.remove(item)
    self.inventory.append(item)

You dont have to implement items the way you implement Locations as items will not have any neighbors.

I want the user to have to type in the command and recognize that they need the item, and not have the item picked up passively once they enter an area.

This is something that should be in your examine function, I guess. Except the examine function called on a location should yield the list of items in that particular location. Maybe understanding how an adventure game (one of your favorites) works by making a smaller version of it may help you understand how the abstract interactions between them are. I guess adding a specific example of this can spark a discussion on the interactions. Best of luck with your game!!

Cheers

Upvotes: 1

Related Questions