HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

A little text based adventure game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
textadventuregamelittlebased

Problem

I'm writing a little text based adventure game, and wanted to know if there's anything I can do better thus far. It is not completed to don't get mad when it ends. I'm just curious as to better ways to write the syntax, or different ways to do things.

```
from random import randint

BACKPACK = {} # What you will bring with you on your journey
SURVIVAL_TOOLS = {} # What you collect over the course of your journey

def create_player():
"""
Create your character name
"""
player_name = raw_input('Enter your characters name: ').capitalize()
return player_name

def formatter(width=50):
"""
Formatting for to keep everything all pretty
:type width: Integer
"""
return '' width

def die(why):
"""
Kill off the program becasue you did something stupid
:type why: String
"""
return "{}. You slowly fade into darkness. Game over.".format(why)

def gather_gear(player):
"""
Gather your gear from a set list of items you have available
:type player: String
"""
print formatter()
print "{}! Shouts Jack as he runs towards you." \
" Do you wanna go Hiking this weekend?" \
" You ponder this for a second." \
" What the hell, you think." \
" Can't be any worse then last time." \
" Sure, Jack! You say enthusiastically." \
" Just let me get some things prepared.".format(player)

options = { # All the items that are available to you before you leave
'fire starter': 1,
'matches': randint(1, 5), # Uses random integers as the value
'flash light': 1,
'sleeping bag': 1,
'canteen cup': 1,
'dried foods': randint(1, 6),
'shovel': 1,
'knife': 1
}

for key in options:
print "You have {} {}".format(options[key], key) # Print out all your items and make it look pretty
print "\n"

count = 3
num_in_pack = 0

while count != 0:
item = raw_input("What woul

Solution

The biggest issue I see is that you're mixing your logic (i.e. how things happen) with the gameplay (why things happen). In general, regardless of what sort of project you're working on, you want to separate the business logic (how things happen) from the user interface (what the user is doing, what is happening, etc).

To facilitate this I'd advise using OOP. The most obvious place to do this is with a Player class. I've also added a Backpack class, and some custom exceptions.

class AdventureGameException(Exception): pass

class BackpackFullException(AdventureGameException): pass

class Backpack(object):

    def __init__(self, items=None, max_size=3):
        self.stuff = {}
        if items:
            self.stuff.update(items)
        self._max_size = 3

    @property
    def full(self):
        return len(self.stuff) == self._max_size

    def add_item(self, name, value):
        if self.full:
            self.stuff[name] = value
        else:
            raise BackpackFullException()

    def __str__(self):
        return "A backpack with {} items.".format(len(self.stuff))

    def __repr__(self):
        return "Backpack(items={items}, max_size={max_size})".format(items=self.stuff, max_size=self._max_size)

class Player(object):

    def __init__(self, name, backpack=Backpack()):
        self.name = name
        self.backpack = backpack

    def take_item(self, item_name, item_value):
        self.backpack.add_item(item_name, item_value)

    def __str__(self):
        return self.name

    def __repr__(self):
        return "Player({name}, backpack={backpack})".format(name-self.name, backpack=repr(self.backpack))


All I've done is make some custom exceptions that we can use in our application, and a Backpack and Player object.

The backpack just keeps track of its own stuff, and whether or not it is full. The player keeps track of themselves, and in this case doesn't worry about error handling.

I've also given them both repr implementations. While it isn't necessary, it is nice when a repr is roundtrippable, i.e. eval(repr(some_item)) == some_item. Speaking of == I didn't implement any of the other operators; I didn't see a need for them, but if you want it then they're straightforward to implement.

The next thing I'd do is make a game driver class (and as the app gets bigger, probably classes. You might even want to do something like MVC eventually). This class should be responsible for actually taking the user through the game.

I made something like this

```
class GameDriver(object):

def __init__(self):
self.player = self.get_player()
self.in_progress = False
self.lost = False

def start_game(self):
print "\nWelcome to the survival game {}.\n".format(self.player)
print formatter()
print """The object of this game is fairly simple. Survive.
You will be given a set number of items to survive
with. Remember, small mistakes in the wilderness
can be the difference between life and death.
Are you ready to begin, {} [Y/N]?""".format(self.player)

begin = raw_input().lower()

while begin not in ['y', 'n']
if begin == 'y':
self.start_game()
elif begin == 'n':
print 'Exiting game..'
self.end_game('Quitter')
else:
print "{} is not an option. Please pick [Y/N]".format(begin)

def get_player(self):
return Player(raw_input('Enter your characters name: ').capitalize())

def end_game(self, reason):
self.in_progress = False
self.lost = True

print "{}. You slowly fade into darkness. Game over.".format(reason)

def gather_gear(self):
print self.formatter()
print "'{}! Shouts Jack as he runs towards you." \
" 'Do you wanna go Hiking this weekend?'" \
" You ponder this for a second." \
" What the hell, you think." \
" Can't be any worse then last time." \
" 'Sure, Jack!' You say enthusiastically." \
" 'Just let me get some things prepared.'".format(self.player)

options = {
'fire starter': 1,
'matches': randint(1, 5),
'flash light': 1,
'sleeping bag': 1,
'canteen cup': 1,
'dried foods': randint(1, 6),
'shovel': 1,
'knife': 1
}

self.take_items_until_full(options)

def print_options(self, items):
for option_name, option_value in items.iteritems():
print "\t{} {}.format(option_value, option_name)"
print

def take_items_until_full(self, items):
num_left = self.player.backpack.space
while num_left > 0:
print "You can take {} more items from:".format(num_left)
self.print_options(items)
choice = raw_input("What would you like to take with you?").strip().lower()

try:

Code Snippets

class AdventureGameException(Exception): pass

class BackpackFullException(AdventureGameException): pass

class Backpack(object):

    def __init__(self, items=None, max_size=3):
        self.stuff = {}
        if items:
            self.stuff.update(items)
        self._max_size = 3

    @property
    def full(self):
        return len(self.stuff) == self._max_size

    def add_item(self, name, value):
        if self.full:
            self.stuff[name] = value
        else:
            raise BackpackFullException()

    def __str__(self):
        return "A backpack with {} items.".format(len(self.stuff))

    def __repr__(self):
        return "Backpack(items={items}, max_size={max_size})".format(items=self.stuff, max_size=self._max_size)


class Player(object):

    def __init__(self, name, backpack=Backpack()):
        self.name = name
        self.backpack = backpack

    def take_item(self, item_name, item_value):
        self.backpack.add_item(item_name, item_value)

    def __str__(self):
        return self.name

    def __repr__(self):
        return "Player({name}, backpack={backpack})".format(name-self.name, backpack=repr(self.backpack))
class GameDriver(object):

    def __init__(self):
        self.player = self.get_player()
        self.in_progress = False
        self.lost = False

    def start_game(self):
        print "\nWelcome to the survival game {}.\n".format(self.player)    
        print formatter()
        print """The object of this game is fairly simple. Survive.
You will be given a set number of items to survive
with. Remember, small mistakes in the wilderness
can be the difference between life and death.
Are you ready to begin, {} [Y/N]?""".format(self.player)

        begin = raw_input().lower()

        while begin not in ['y', 'n']
            if begin == 'y':
                self.start_game()
            elif begin == 'n':
                print 'Exiting game..'
                self.end_game('Quitter')
            else:
                print "{} is not an option. Please pick [Y/N]".format(begin)

    def get_player(self):
        return Player(raw_input('Enter your characters name: ').capitalize())

    def end_game(self, reason):
        self.in_progress = False
        self.lost = True

        print "{}. You slowly fade into darkness. Game over.".format(reason)

    def gather_gear(self):
        print self.formatter()
        print "'{}! Shouts Jack as he runs towards you." \
              " 'Do you wanna go Hiking this weekend?'" \
              " You ponder this for a second." \
              " What the hell, you think." \
              " Can't be any worse then last time." \
              " 'Sure, Jack!' You say enthusiastically." \
              " 'Just let me get some things prepared.'".format(self.player)

        options = {
            'fire starter': 1,
            'matches': randint(1, 5),
            'flash light': 1,
            'sleeping bag': 1,
            'canteen cup': 1,
            'dried foods': randint(1, 6),
            'shovel': 1,
            'knife': 1
        }

        self.take_items_until_full(options)

    def print_options(self, items):    
        for option_name, option_value in items.iteritems():
            print "\t{} {}.format(option_value, option_name)"
        print

    def take_items_until_full(self, items):
        num_left = self.player.backpack.space
        while num_left > 0:
            print "You can take {} more items from:".format(num_left)
            self.print_options(items)
            choice = raw_input("What would you like to take with you?").strip().lower()

            try:
                item = items.pop(choice)
            except KeyError:
                print "You can't take that item"
                continue

            try:
                num_left = self.player.take_item(choice, item)
            except BackpackFullException:
                print "You can't carry anything else!"
                break

            print "You throw a {} in your backpack".format(item)
            num_left -= 1

        print "Your backpack is now full"

    def formatter(self, width=50):
        """
       
class GameText(object):

    def __init__(self, player):
        self.player_name = player.name

    @property
    def welcome_text(self):
        return "\nWelcome to the survival game {}.\n".format(self.player_name)

    @property
    def separator(self):
        return "*" * 50

    @property
    def objective(self):
        return """The object of this game is fairly simple. Survive.
You will be given a set number of items to survive
with. Remember, small mistakes in the wilderness
can be the difference between life and death.
Are you ready to begin, {} [Y/N]?""".format(self.player_name)

    @property
    def exit_message(self):
        return 'Exiting game..'

    def get_invalid_choice_message(self, options, selection):
        return "{} is not an option. Please pick [{}]".format(selection, options)

Context

StackExchange Code Review Q#136784, answer score: 4

Revisions (0)

No revisions yet.