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

Simple Python maze game

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

Problem

The program is running fine but I was just wondering whether there was anything I could do to make it more user friendly or efficient.

```
from random import randint
import time
word = "a"
shield = 5
#The main function
def main():
#This will trigger the introduction
intro()
while True:
shield, word, finished = TakeTurn(word,shield)
if finished:
break
if shield == 1:
word1 = "shield"
else:
word1 = "shields"
print ("You have",shield,word1)
if shield < 1:
print ("Sorry! You ran out of shields! You lose!")
else:
print ("You win")

#This function is the introduction to the program
def intro():
time = [1,2.5, 2, 1.5, 1, 2, 1]
text = ["You are lost in a maze, it is dark and you are lost",
"Im afraid there are monsters here...", "BOO!",
"You have five shields to protect you...","Use them well!",
"Okay, let's go!"]
print_on_a_timer(time, text)

#This function is the actual 'game' and will deterine what happens to the character
def TakeTurn(word1,shield1):
time.sleep(1.5)
#This means that when the user reaches 0 shields, they lose.
if shield1 < 1:
return True
#Whatever the user inputs will not actually affect the outcome
print ("You have reached", word1 ,"junction.\nDo you want to turn left (L), turn right (R) or go straight ahead(S)?")
turning = input().lower()
#This is a simple instruction that means that the first time you come to a junction, it will say 'a junction' but the second time it will say 'another junction'
word1 = "another"
#This 'if' statement means that the program will only continue if the user has inputed the letters 'L', 'R' or 'S'
while turning not in ["l","r","s"] :
time.sleep (0.7)
print ("Sorry, I didn't understand that")
turning = input().lower()
choice = randint (1,10)
#This is just going to display a random message whi

Solution

Time to learn about objects. Below is a rewrite that should move you down the learning path. I did not change everything about the code I just shuffled the logic into events.

Note the use of game_sleep. This allows sleep to be disabled during testing. Moving all of the bits of logic and choices out of the core function enables tests to be written for each specific choice, event, etc.

I needed game_input because I am using 2.7 and so my input is not the same as the one in 3.x.

Enjoy and feel free to ask any questions.

```
import random
import time

def game_input():
return raw_input()

def game_sleep(value):
# time.sleep(value)
pass

def pluralize(word, number):
# you can find libraries containing a function like this
known_words = {
'shield': lambda x: "shield" if x == 1 else "shields",
}

if word in known_words:
return known_wordsword
else:
return word

def print_on_a_timer(times, lines):
for times, lines in zip(times, lines):
game_sleep(times)
print(lines)

#This function is the introduction to the program
def intro():
time = [1,2.5, 2, 1.5, 1, 2, 1]
text = ["You are lost in a maze, it is dark and you are lost",
"I'm afraid there are monsters here...", "BOO!",
"You have five shields to protect you...","Use them well!",
"Okay, let's go!"]
print_on_a_timer(time, text)

def get_valid_input(prompt, choices):
choice = None

# This means that the program will only continue if the user's choice is in valid_choices
while True:
print (prompt)
choice = game_input().lower()

if choice in choices:
break

print ("Sorry, I didn't understand that")
game_sleep(0.7)

return choice

class Event(object):
_result = 0

def __init__(self):
pass

def endGame(self):
return False

def interact(self):
return None

def message(self):
yield self._message

def result(self):
return self._result

class NegativeEvent(Event):
def __init__(self, msg, value):
super(NegativeEvent, self).__init__()

self._message = msg
self._result = value

class FoundExit(Event):
_message = "You have found the exit!"

def endGame(self):
return True

class FoundShield(Event):
_message = "You have found {} {}!"

def __init__(self, count):
super(FoundShield, self).__init__()

self._count = count

def message(self):
yield self._message.format(self._count, pluralize("shield", self._count))

def result(self):
return self._count

class FoundFairy(Event):
_message = "A fairy has jumped into your pants!"
_result = -2

class FoundTreasureChest(Event):
_message = "You have found a treasure chest!"

def __init__(self):
super(FoundTreasureChest, self).__init__()

def interact(self):
choice = get_valid_input(prompt="Do you want to open it? Y or N?",
choices=["y", "n"])
if choice is not "y":
print ("Okay Bye")
return None

print_on_a_timer([1, 1, 1], ["Opening...", "Opening...", "Opening..."])

random_events = [(FoundShield, [1,]),
(FoundShield, [2, ]),
(NegativeEvent, ["A dwarf jumps out and steals one of your shields!", -1]),
(NegativeEvent, ["An evil fairy steals two of your shields!", -2]),
(JustMessage, ["Sorry, the chest is empty"]),
(Encounter, ["A goblin is in the chest.", Goblin])
]
event, options = random.choice(random_events)
return event(*options)

class JustMessage(Event):
def __init__(self, msg):
super(JustMessage, self).__init__()
self._message = msg

class TrippedOverALog(Event):
_message = "You have tripped over a log!"
_result = -1

class Encounter(Event):
def __init__(self, msg, event, *options):
self._message = msg
self._next_event = event
self._options = options

def interact(self):
return self._next_event(*self._options)

class AngryTeenager(Event):
_result = -3

def message(self):
game_sleep(2.5)
yield "He uses laziness..."
game_sleep(1.5)
yield "It's super effective!"
game_sleep(1)
return

class Ogre(Event):
_result = -2

def message(self):
game_sleep(1.5)
yield ("He bashes you over the head with a steel bar")
game_sleep(2)
return

class Goblin(Event):
_message = "He says the following:"

def interact(self):
timings = [1, 2.5, 1, 1, 1]
text = ["""'Do you want to play my magical roulette?
There are three different outcomes:'""",
"You lose a shield",
"You gain a shield",
"Nothing

Code Snippets

import random
import time


def game_input():
    return raw_input()


def game_sleep(value):
    # time.sleep(value)
    pass


def pluralize(word, number):
    # you can find libraries containing a function like this
    known_words = {
        'shield': lambda x: "shield" if x == 1 else "shields",
    }

    if word in known_words:
        return known_words[word](number)
    else:
        return word


def print_on_a_timer(times, lines):
    for times, lines in zip(times, lines):
        game_sleep(times)
        print(lines)


#This function is the introduction to the program
def intro():
    time = [1,2.5, 2, 1.5, 1, 2, 1]
    text = ["You are lost in a maze, it is dark and you are lost",
            "I'm afraid there are monsters here...", "BOO!",
            "You have five shields to protect you...","Use them well!",
            "Okay, let's go!"]
    print_on_a_timer(time, text)


def get_valid_input(prompt, choices):
    choice = None

    # This means that the program will only continue if the user's choice is in valid_choices
    while True:
        print (prompt)
        choice = game_input().lower()

        if choice in choices:
            break

        print ("Sorry, I didn't understand that")
        game_sleep(0.7)

    return choice


class Event(object):
    _result = 0

    def __init__(self):
        pass

    def endGame(self):
        return False

    def interact(self):
        return None

    def message(self):
        yield self._message

    def result(self):
        return self._result


class NegativeEvent(Event):
    def __init__(self, msg, value):
        super(NegativeEvent, self).__init__()

        self._message = msg
        self._result = value


class FoundExit(Event):
    _message = "You have found the exit!"

    def endGame(self):
        return True


class FoundShield(Event):
    _message = "You have found {} {}!"

    def __init__(self, count):
        super(FoundShield, self).__init__()

        self._count = count

    def message(self):
        yield self._message.format(self._count, pluralize("shield", self._count))

    def result(self):
        return self._count


class FoundFairy(Event):
    _message = "A fairy has jumped into your pants!"
    _result = -2


class FoundTreasureChest(Event):
    _message = "You have found a treasure chest!"

    def __init__(self):
        super(FoundTreasureChest, self).__init__()

    def interact(self):
        choice = get_valid_input(prompt="Do you want to open it? Y or N?",
                                 choices=["y", "n"])
        if choice is not "y":
            print ("Okay Bye")
            return None

        print_on_a_timer([1, 1, 1], ["Opening...", "Opening...", "Opening..."])

        random_events = [(FoundShield, [1,]),
                         (FoundShield, [2, ]),
                         (NegativeEvent, ["A dwarf jumps out and steals one of your shields!", -1]),
                         (NegativeEvent, ["An evil fairy steals two of you

Context

StackExchange Code Review Q#52208, answer score: 5

Revisions (0)

No revisions yet.