patternpythonMinor
Simple text based game (LPTHW)
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.
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"
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
Now to the first room:
Add all the other rooms to
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
Of course, code as written is a pretty primitive prototype I've hacked together as an example, but hopefully it explains the idea.
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.