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

Simple text based game (LPTHW)

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

Problem

For Learn Python The Hard Way exercise 45 I made a small text game, that took a few hours. Since classes were used and classes were a recently brought up concept in the book, I was wondering how this piece of code could be made better. It should be able to work in terminal as far as I know.

from sys import exit
from random import randint

from Scene import *

class Main(object):

    def __init__(self):
        self.stage = DoorScene()
        self.stage_2 = FightScene()
        self.stage_3 = EndingScene()

    def play(self):
        boss_door = self.stage.enter_boss_room()
        if boss_door == True:
            defeated_boss = self.stage_2.the_fight()
            if defeated_boss == True:
                self.stage_3.ending()
        else:
            exit(0)

game_try = Main()
game_try.play()


second file

```
from random import randint

class DoorScene(object):

def enter_boss_room(self):
print "You walk and come across a door. It requires you to guess the"
print "right number to enter the room to fight the final boss. You only"
print "have 5 guesses so make good use of your guesses."

code = randint(1, 10)
choice = raw_input("> ")
attempts = 0

while int(choice) != code:
attempts += 1
if attempts == 5:
break
else:
pass
print "Wrong number, try again."
choice = raw_input("> ")

if int(choice) == code:
print "That's the correct number! You pass through the door and see"
print "a huge beast laying in the room. Prepare yourself to fight the beast!\n"
return True
else:
print "You failed more than 5 times. Game Over."
return False

class FightScene(object):

def the_fight(self):
print "Your character will now fight the boss. If your health drops"
print "below 100, you can use a health potion to restore your"

Solution

You should generalize your room code. Instead of having self.stage.enter_boss_room(), self.stage2.the_fight() and so on in separate classes, it'd be better to have a single Scene() class with methods such as eg entrance_text and main_interaction. Assuming the gameplay is gonna be strictly linear and each room consists of a block of text and a single puzzle, code might look like this:

def Scene():
    def __init__(self, entrance_text, test):
        self.entrance = entrance_text
        self.test = test

    def print_entrance(self):
        print(self.entrance)

    def run_test():
        #1st class functions magic!
        return self.test()


Now to the first room:

def test1():
            code = randint(1, 10)
        choice = raw_input("> ")
        attempts = 0

        while int(choice) != code:
            attempts += 1
            if attempts == 5:
                break
            else:
                pass
            print "Wrong number, try again."
            choice = raw_input("> ")
s = []
s.append(Scene('You walk across the room. It requires you to guess the\nright number', test1))


Add all the other rooms to s, as well. Now your Main() will be way more simple:

for a in s:
    a.print_entrance()
    if not a.run_test():
        print('Game Over')
        quit()


The main advantage here is not the brevity of the code; it's the scalability. In your version, every time you add a scene, you have to manually add some method calls in Main(). This is annoying and leads to barely maintainable code. Imagine all the fun of remembering whether self.bash_goblin() needs to be before or after self.unlock_door_45() when you have a couple hundreds of scenes. Now you have a unified scene API, so your engine doesn't really care how many scenes there are or where. You can add features such as jumping to any random scene, savegames (which are basically a single integer) or rollback at pretty much no cost.
Of course, code as written is a pretty primitive prototype I've hacked together as an example, but hopefully it explains the idea.

Code Snippets

def Scene():
    def __init__(self, entrance_text, test):
        self.entrance = entrance_text
        self.test = test

    def print_entrance(self):
        print(self.entrance)

    def run_test():
        #1st class functions magic!
        return self.test()
def test1():
            code = randint(1, 10)
        choice = raw_input("> ")
        attempts = 0

        while int(choice) != code:
            attempts += 1
            if attempts == 5:
                break
            else:
                pass
            print "Wrong number, try again."
            choice = raw_input("> ")
s = []
s.append(Scene('You walk across the room. It requires you to guess the\nright number', test1))
for a in s:
    a.print_entrance()
    if not a.run_test():
        print('Game Over')
        quit()

Context

StackExchange Code Review Q#139076, answer score: 2

Revisions (0)

No revisions yet.