18. Adventure Game with Structural Pattern Matching
By Bernd Klein. Last modified: 10 Nov 2023.
Introduction
In this section of our Python tutorial, we introduce structural pattern matching through an intriguing scenario—a hypothetical text-based adventure game.
Text adventure games, often referred to as interactive fiction, are a type of computer game that relies primarily on text-based descriptions and typed language commands for user input, rather than graphics and sound. Typical user input for most of these games look like:
- 'help'
- 'show inventory'
- 'go north'
- 'go south'
- 'drop shield'
- 'drop all weapons'
A notable example of such a game is "Hack," a text-based role-playing game developed in the 1980s at the Massachusetts Institute of Technology (MIT) and more commonly recognized as "NetHack."
We will showcase Python code snippets that simulate scenarios within a text adventure game, while also elucidating significant aspects and features of structural pattern matching.
command = input("What are you doing next? ")
action, object = command.split()
print(f"{action=}, {object=}")
OUTPUT:
action='take', object='sword'
What if the user types less or more than 2 words?
command = input("What are you doing next? ")
words = command.split()
no_of_words = len(words)
if no_of_words == 1:
print(f"action without object: {action=}")
elif no_of_words == 2:
print(f"{action=}, {object=}")
else:
print(words)
OUTPUT:
action='take', object='sword'
Now with structural pattern recognition. Matching multiple patterns:
command = input("What are you doing next? ")
match command.split():
case [action]:
print(f"action without object: {action=}")
case [action, obj]:
print(f"{action=}, {obj=}")
OUTPUT:
action without object: action='look'
Live Python training
Matching specific patterns:
command = input("What are you doing next? ")
match command.split():
case ["quit"]:
print("Goodbye!")
quit_game()
case ["look"]:
print("You are in cold and dark room ....")
case ["get", obj]:
print(f"You grab the {obj}")
case ["go", direction]:
print(f"You will go {direction} if possible")
case _:
print("Sorry, I do not understand!")
OUTPUT:
You grab the apple
Matching Multiple Values:
command = "drop apple armour shield"
match command.split():
case ["drop", *objects]:
for obj in objects:
print(f"You drop a{'n' if obj[0] in 'aeiou' else ''} {obj}")
OUTPUT:
You drop an apple You drop an armour You drop a shield
Live Python training
Upcoming online Courses
24 Feb 2025 to 28 Feb 2025
31 Mar 2025 to 04 Apr 2025
07 Apr 2025 to 11 Apr 2025
19 May 2025 to 23 May 2025
02 Jun 2025 to 06 Jun 2025
30 Jun 2025 to 04 Jul 2025
11 Aug 2025 to 15 Aug 2025
10 Mar 2025 to 14 Mar 2025
07 Apr 2025 to 11 Apr 2025
23 Jun 2025 to 27 Jun 2025
28 Jul 2025 to 01 Aug 2025
Efficient Data Analysis with Pandas
10 Mar 2025 to 11 Mar 2025
07 Apr 2025 to 08 Apr 2025
02 Jun 2025 to 03 Jun 2025
23 Jun 2025 to 24 Jun 2025
28 Jul 2025 to 29 Jul 2025
Machine Learning from Data Preparation to Deep Learning
10 Mar 2025 to 14 Mar 2025
07 Apr 2025 to 11 Apr 2025
02 Jun 2025 to 06 Jun 2025
28 Jul 2025 to 01 Aug 2025
Adding a wildcard
In the following code, if you use an input that doesn't match any of the defined patterns, Python doesn't raise an exception. Instead, the code will simply continue without entering any of the case blocks like in the following Python example:
command = 'fight monster'
match command.split():
case ["help"]:
print("""You can use the following commands:
""")
case ["go", direction]:
print('going', direction)
case ["drop", "all", "weapons"]:
for weapon in weapons:
inventory.remove(weapon)
case ["drop", item]:
print('dropping', item)
To handle unexpected or unmatched input gracefully, you can add a wildcard case using an underscore _
as a wildcard to catch any input that doesn't match the specific patterns.
commands = ['go north','go west', 'drop potion', 'drop all weapons', 'drop shield', 'fight monster']
weapons = ['axe','sword','dagger']
shield = True
inventory = ['apple','wood','potion'] + weapons + ['shield']
for command in commands:
match command.split():
case ["help"]:
print("""You can use the following commands:
""")
case ["go", direction]:
print('going', direction)
case ["drop", "all", "weapons"]:
for weapon in weapons:
inventory.remove(weapon)
case ["drop", item]:
print('dropping', item)
inventory.remove(item)
case ["drop shield"]:
shield = False
case _:
print(f"Sorry, I couldn't understand {command!r}")
OUTPUT:
going north going west dropping potion dropping shield Sorry, I couldn't understand 'fight monster'
Several Patterns Resulting in the Same Outcome
command = input("What are you doing next? ")
match command.split():
# Other cases
# .....
case ["north"] | ["go", "north"]:
print("Let's go north")
case ["look"] | ["look", "around"]:
print("You are in a cold and dark room ....")
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
print(f"Picking up {obj}")
OUTPUT:
You are in a cold and dark room ....
Live Python training
Capturing Matched Subpatterns
command = input("What are you doing next? ")
match command.split():
case ["go", ("north" | "south" | "east" | "west") as direction]:
print(f"You go {direction}")
OUTPUT:
You go north
Patterns mit Conditions
We can also add conditions to a branch of a structural pattern matching. So like checking if an exit exists in a certain direction of a room.
command = input("What are you doing next? ")
possible_direction = ['north', 'south']
match command.split():
case ["go", direction] if direction in possible_direction:
print(f"So, let's go {direction}!")
OUTPUT:
So, let's go south!
Live Python training
Upcoming online Courses
24 Feb 2025 to 28 Feb 2025
31 Mar 2025 to 04 Apr 2025
07 Apr 2025 to 11 Apr 2025
19 May 2025 to 23 May 2025
02 Jun 2025 to 06 Jun 2025
30 Jun 2025 to 04 Jul 2025
11 Aug 2025 to 15 Aug 2025
10 Mar 2025 to 14 Mar 2025
07 Apr 2025 to 11 Apr 2025
23 Jun 2025 to 27 Jun 2025
28 Jul 2025 to 01 Aug 2025
Efficient Data Analysis with Pandas
10 Mar 2025 to 11 Mar 2025
07 Apr 2025 to 08 Apr 2025
02 Jun 2025 to 03 Jun 2025
23 Jun 2025 to 24 Jun 2025
28 Jul 2025 to 29 Jul 2025
Machine Learning from Data Preparation to Deep Learning
10 Mar 2025 to 14 Mar 2025
07 Apr 2025 to 11 Apr 2025
02 Jun 2025 to 06 Jun 2025
28 Jul 2025 to 01 Aug 2025