Explore the future of Web Scraping. Request a free invite to ScrapeCon 2024

Building An Old School Text-Based Game With Python

They're not dead yet!

image While cleaning up a few old Jump Drives, I found old projects from my early college days. Being a little curious, I decided to take a trip down memory lane. One project was a Python text-based game. A small mystery game that involved random numbers and user input. Although not a very difficult dive into Python, it was a fun project at the time and I thought it would make a good post for those looking to start a simple first game. It also teaches small skills that would be helpful for any other text-based games you may want to write.

Writing the Introduction

The first thing to note is that because it's a text-based game, there will be a lot of hard-coded print statements. That being said, although I am sharing my text, you can use it any way you would like. Your story can be completely different than mine. That's the joy of learning a few basic Python commands. To keep code at least a little clean in the main module, we can split up the code into separate files. The first file will contain only the introduction information.

For my game, I started with a standard “you woke up to an unfamiliar place” scene, where I was looking for basic user input. First, this was the beginning of the function as well as the initial descriptors and a short menu:

def intro():
     print("Last night, you went to sleep in your own home.")
     print("Now, you wake up to an unfamiliar environment.")
     print("As your eyes flutter open, darkness greets you. Your surroundings are blind to you.")
     print("You are sat on a bed, and a wall hugs your back. Beside you is a table, whose outline you can vaguely determine.") print("1 - to check under the bed")
     print("2 - to check the table")

Next, we will read in the input. However, because users don't necessarily follow the rules of enter digits, we need to test the input. We need to ensure that the digits are whole numbers, that they are the numbers are one and two, and that the value is in fact an integer.

To do this, we will test in a loop. We will “try” to parse the input to an integer, and if that does not work we will prompt the user to enter a whole number value. On the other hand, if it is an integer other than one or two, it encourages the user to select one of those digits:

while True:

bedOrWall = input()

try:

if int(bedOrWall) == 1:

print("Under the bed, you feel a note. But you cannot see to examine it.")

print("You check the table and find a lamp. With a loud click, your surroundings are illuminated.")

break

elif int(bedOrWall) == 2:

print("You check the table and find a lamp. With a loud click, your surroundings are illuminated.")

print("You also check under the bed and find a note.")

break

else:

print("Enter either 1 or 2:")

except:

print("Value must be whole number 1 or 2:")

Now that we had the output, in my personal game I had one more list of story setup.

print("")
print("The note reads:")
print("My dearest participant,")
print(" If you notice, the door contains a padlock with a three digit code.")
print(" You will find this code hidden within the room, and must solve it. You shall find three numbers, and must order them correctly.")
print(" I wish you the best of luck.")
print("Sincerely, your gracious host.")print("")
print("You examine the room and see:")

That was the last code for the introduction file. Next, we will need to set up the menu.

Writing the Menu

For this menu file, we will need to pass a list of items to choose from. We will also send the user prompt. Within a “for” loop, we will print each item in that list. Once we have those, we will use “while” loop to check the input, just like we did in the introduction file. Again, we will prompt the user to correct their input to the expected list of results.

def menu(list, question):

for item in list:

print(list.index(item), item)

while True:

result = input(question)

try:

result = int(result)

break

except:

print("Selection must be whole number between 0-9:")

return result

Now that we have the menu file finished, we can write our next file, which will contain the items inside the menu.

Writing the searchItem File

For this file, we should include all remaining elements that will be involved in the menu. The objective to the game will be to find hidden numbers of a padlock code, so the menu will include every item that has the ability to be searched, as well as the door containing the padlock. First we will declare the Door, where we will need to pass the code to test if the player guesses correctly. The code inserted will need each digit tested, just like in the last two files. Because the game will be in a loop, we will also need to break the loop by sending a positive confirmation if the code is correct, and something a code to continue the loop if it is incorrect.

def Door(code):

print("You walk to the door. The rotary padlock contains three digits. You enter a code")

while True:

try:

option1 = int(input("Digit one: "))

break

except:

print("Digit one must be a whole number between 0-9:")

while True:

try:

option2 = int(input("Digit two: "))

break

except:

print("Digit two must be a whole number between 0-9:")

while True:

try:

option3 = int(input("Digit three: "))

break

except:

print("Digit three must be a whole number between 0-9:")

chosenCode = int(str(option1) + str(option2) + str(option3))

print("")

if chosenCode == code:

print("You hear a click, and the padlock shifts. As you press open the door a rush of fresh, warm air caresses your face. At last, you are free.")

return (1)

else:

print("You jiggle the padlock, but to no avail. The code is incorrect.")

return(0)

Next, we create our first search item. We need to send the menu number selection for that item, then the first code location to test against, and also the first code segment if that is the correct location.

def Window(choice, codeLocation, codeValue):

print("")

print("You look at the window. It's dark, and damp. Mold grows along the edges and you cannot see through its musty panes.")

if choice == codeLocation:

print("Carved into the edging, you see the number " + str(codeValue) + ".")

print("")

else:

print("You find no code.")

print("")

The window was the first selection. As you can see, most of the code is text-based, and so it can be changed to whatever you would like. The next code will handle a backpack selection.

def Backpack(choice, codeLocation, codeValue):

print("")

print("The backpack is your personal bag. Strange. You thought you lost it weeks ago.")

if choice == codeLocation:

print("Within the front pocket, you see the number " + str(codeValue) + " written on a crumpled note.")

print("")

else:

print("You find no code.")

print("")

The text can be as straightforward or descriptive as you want. Now, we will work on the vase section.

def Vase(choice, codeLocation, codeValue):

print("")

print("A dark blue vase holds roses that seem to have died long ago.")

if choice == codeLocation:

print("On the base, you see the number " + str(codeValue) + ".")

print("")

else:

print("You find no code.")

print("")

As you can see, the code is very standard across these functions. But again, they can be any length you personally want for your game.

def Bucket(choice, codeLocation, codeValue):

print("")

print("The bucket sits in the middle of the floor. It catches a gentle leak from the dank ceiling.")

if choice == codeLocation:

print("Within, you see exactly " + str(codeValue) + " stones.")

print("")

else:

print("You find no code.")

print("")

We're now about halfway through my selection of items. I decided to do nine of them, but you can do less if you would prefer.

def Painting(choice, codeLocation, codeValue):

print("")

print("Has Mona Lisa always been this creepy? Her eyes peer into you, her smile gleams as if she knows the fate that awaits you unless you find the code.")

if choice == codeLocation:

print("Painted in the corner, you see the number " + str(codeValue) + ".")

print("")

else:

print("You find no code.")

print("")

Some options were definitely more descriptive than others, but that's the joy of having fun with the creativity.

def JewelryBox(choice, codeLocation, codeValue):

print("")

print("The oak Jewelry Box creeks open and gentle music fills the room. The music may have once been soothing, but years of age has ruined this once peaceful melody.")

if choice == codeLocation:

print("Etched inside the lid, you see the number " + str(codeValue) + ".")

print("")

else:

print("You find no code.")

print("")

Something to note, to keep multiple codes from using the same location, there is a predetermined list of what location each code segment can be found in.

ef Rug(choice, codeLocation, codeValue):

print("")

print("A dusty woven rug adorns the otherwise ragged wooden floor, adding a hint of color to the eery room.")

if choice == codeLocation:

print("Carved onto the floor beneath, you see the number " + str(codeValue) + ".")

print("")

else:

print("You find no code.")

print("")

Nearly there, only two more items. This has the possibility to contain the third code segment, but not the second or first as previously explained.

def Mirror(choice, codeLocation, codeValue):

print("")

print("The mirror is grimey and unpleseant. The unnatural reflection leers back at you. The circles under your eyes are dark and full. It offers little comfort.")

if choice == codeLocation:

print("As you study your reflection, you notice the number " + str(codeValue) + " painted onto your shirt.")

print("")

else:

print("You find no code.")

print("")

This will be our last item:

def Bookshelf(choice, codeLocation, codeValue):

print("")

print("A bookshelf filled with old, unkempt books. It is sad to see them so run down.")

if choice == codeLocation:

print("You notice the books are all the same volume. The volume number is " + str(codeValue) + ".")

print("")

else:

print("You find no code.")

print("")

Now, we will be ready to create the last file, which would be the main file.

Writing the Main File

In this file, we will import all the others, as well as make a random code and declare the game. The very first thing we need to do is import the random module:

import random

With that imported, we can now import all the functions in each file we wrote:

from introduction import intro
from menu import menu
from searchItem import Door, Window, Backpack, Vase, Bucket, Painting, JewelryBox, Rug, Mirror, Bookshelf

To create the code, we will declare three segments of codes generated by random integers between zero and nine. We will also need to add those together for the code. Next, we need to create our items list. After that, we will declare the locations that the code segments could possibly be in. Recall that to keep them from overlapping, we keep the potential locations in a separate potential set.

codeSegment1 = random.randint(0,9)

codeSegment2 = random.randint(0,9)

codeSegment3 = random.randint(0,9)

code = int(str(codeSegment1) + str(codeSegment2) + str(codeSegment3))

items = ["Door","Window","Backpack","Vase","Bucket","Painting","Jewelry Box","Rug","Mirror","Bookshelf"]

code1Location = random.randint(1,3)

code2Location = random.randint(4,6)

code3Location = random.randint(7,9)

Now, we are ready to initiate the game:

intro()

Finally, we initiate the game loop. It will continue to run until the user finds the correct code, or guesses correctly. To see the player's selection, call the menu and place it within a variable. Then than selection is within a larger if/elif/else section where we can send the right details to the menu item. We will also need to send the choice number and the code location so they may be tested if that item is the right location. We also need to send the code segment in case it is correct. Anything not item-related will be sent to the door to test the padlock. If the correct return code was returned, stating the player entered the right padlock code, then we will break the loop. Otherwise, the game continues.

while True:

choice = menu(items, "What do you want to inspect? ")

if choice == 1:

Window(choice, code1Location, codeSegment1)

elif choice == 2:

Backpack(choice, code1Location, codeSegment1)

elif choice == 3:

Vase(choice, code1Location, codeSegment1)

elif choice == 4:

Bucket(choice, code2Location, codeSegment2)

elif choice == 5:

Painting(choice, code2Location, codeSegment2)

elif choice == 6:

JewelryBox(choice, code2Location, codeSegment2)

elif choice == 7:

Rug(choice, code3Location, codeSegment3)

elif choice == 8:

Mirror(choice, code3Location, codeSegment3)

elif choice == 9:

Bookshelf(choice, code3Location, codeSegment3)

else:

result = Door(code)

if result == 1:

break

And that's the last of our custom text-based game code.

Time To Play The Game

image

Introduction

image

Opening to the first menu.

image

Inspecting first locations.

image

Inspecting next locations.

image

Inspecting next locations.

image

Inspecting next locations.

image

Inspecting final location and door.

image

Unsuccessful padlock code.

image

Testing user entry.

image

Successful padlock code.

Conclusion

Not the most intricate code, and more hard-coded values, but a good blast from the past for me. The best part about it is with these few simple skills, we can create a wide range of text-based games. Because a lot of description is hard-coded, the storyline could be a mix of any genre. I hope you enjoyed this game writing experience, as well as my trip down memory lane. Until next time, cheers!




Continue Learning