Pick Red Door
When we submit "red" to pick the red door, we should
- Message that we encounter a dragon!
- Set the
current_room
to "red_room" and return that in the context.
lets_adventure()
function should now look like the following:
def lets_adventure(request):
context = {}
context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]
if request.method == "POST":
form = AdventureForm(request.POST)
if form.is_valid():
data = form.cleaned_data
print(data)
## New - start
# Get the data from form
current_player = data.get("current_player")
current_room = data.get("room")
answer = data.get("answer")
# Check if this room with red and blue doors
if current_room == "two_doors":
print("In room with two doors")
# Check which door was picked
if answer in ["red", "left"]:
print("Picked red door")
context["current_room"] = "red_room"
context["message"] = "A DRAGON!!! What do you do? <<flee>> or <<stay>>?"
return render(request, 'myfirstgame/adventure.html', context)
elif answer in ["blue", "right"]:
print("Picked blue door")
context["current_room"] = "blue_room"
else:
print("Don't understand which door you picked")
## New - end
return render(request, 'myfirstgame/index.html', context)
Let's start doing something with this data.
current_player = data.get("current_player")
current_room = data.get("room")
answer = data.get("answer")
Create current_player
, current_room
and answer
variables to save the various data from the form.
We will need this later.
Checking which doors is picked by the player, we first make sure that the current_room
is "two_doors"
which was submitted via the form.
if current_room == "two_doors":
print("In room with two doors")
# Check which door was picked
if answer in ["red", "left"]:
print("Picked red door")
context["current_room"] = "red_room"
context["message"] = "A DRAGON!!! What do you do? <<flee>> or <<stay>>?"
return render(request, 'myfirstgame/adventure.html', context)
elif answer in ["blue", "right"]:
print("Picked blue door")
context["current_room"] = "blue_room"
else:
print("Don't understand which door you picked")
If the red
or left
door was picked, we
- set the
current_room
for thecontext
variable to"red_room"
- set the
message
for thecontext
variable to"A DRAGON!!! What do you do? <<flee>> or <<stay>>?"
- render the
myfirstgame/adventure.html
and passing its context variable
If the blue
or right
door was picked, we set current_room
to "blue_room"
. It will default return to 'myfirstgame/index.html'
.
The else
statement, we haven't done anything besides printing to terminal, it will default return to 'myfirstgame/index.html'
.
Note: Will leave this part as an excercise at the end. :-)
Save the file, and your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
After you submit your name and "red"
in the next screen, you should see the following:
Switch to your terminal where you are running your Django server, you should also see the print output to the terminal when the player picks the red
door:
And if the player picks the blue
door:-
The options available is the player can choose to flee
or stay
.
- flee : Back to the room with two doors (red and blue)
- stay : Game Over; dragon has eaten you
Let's flee the red room!
We will modify the if block, if current_room == "two_doors":
, and add the following:
if current_room == "two_doors":
...
elif current_room == "red_room":
# In the room with the dragon
if answer in ["flee"]:
print("FLEE") # Debug
context['message'] = "You are back in the room with two doors, what do you do?"
context['current_room'] = "two_doors"
return render(request, 'myfirstgame/adventure.html', context)
We are checking if current_room
is "red_room"
, we set
- the message in the context to let player know they are back in the room with two doors
"current_room"
in context to return"two_doors"
We render the adventure HTML page to see what the user wants to do next.
lets_adventure()
function should now look like the following:
def lets_adventure(request):
context = {}
context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]
if request.method == "POST":
form = AdventureForm(request.POST)
if form.is_valid():
data = form.cleaned_data
print(data)
# Get the data from form
current_player = data.get("current_player")
current_room = data.get("room")
answer = data.get("answer")
# Check if this room with red and blue doors
if current_room == "two_doors":
print("In room with two doors")
# Check which door was picked
if answer in ["red", "left"]:
print("Picked red door")
context["current_room"] = "red_room"
context["message"] = "A DRAGON!!! What do you do? <<flee>> or <<stay>>?"
return render(request, 'myfirstgame/adventure.html', context)
elif answer in ["blue", "right"]:
print("Picked blue door")
context["current_room"] = "blue_room"
else:
print("Don't understand which door you picked")
# New
elif current_room == "red_room":
# In the room with the dragon
if answer in ["flee"]:
print("FLEE")
context['message'] = "You are back in the room with two doors, what do you do?"
context['current_room'] = "two_doors"
return render(request, 'myfirstgame/adventure.html', context)
return render(request, 'myfirstgame/index.html', context)
Save the file, and your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
red
- Submit
flee
- Back at room with two doors, select
red
- Submit
flee
- Back at room with two doors
Remember we haven't done anything with selecting blue
(door) or flee
(dragon in red room). We will look at staying in the red room with the dragon.
Let's stay in the red room
The following code will be added to lets_adventure()
function, it should look like the following:-
elif current_room == "red_room":
# In the room with the dragon
if answer in ["flee"]:
...
# NEW
elif answer in ["stay"]:
print("STAY")
context["message"] = "Dragon gave a huge roar and eats you. GAME OVER!"
context['form'] = PlayerForm()
return render(request, 'myfirstgame/index.html', context)
If we are staying in the red_room
- The
print
statement is just for us to see its output in the terminal when the Django server is running. - Pass back the GAME OVER message to context variable
- Create blank
PlayerForm()
and save to context variable - render the index page passing back the context variable
Remember to save the file.
We will need to edit the following template to display the message
passed back in the context object to myfirstgame/templates/myfirstgame/index.html
. We use {{ message }}
and template updated as follows:
% extends 'myfirstgame/base.html' %}
{% block content %}
<div class="content container">
<div class="row">
<div class="col-md-12">
<!--NEW-->
<p>{{ message }}</p>
...
{% endblock %}
Note: This is ok for now, but we will find problems using this way of passing message strings back to the index page later in the tutorial.
Remember to save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
red
- Submit
flee
- Back at room with two doors, select
red
- Submit
stay
- Game over, back at the start to begin the game again.
You should see the following:
Game over - let's log that
We created myfirstgame/models.py
and there's a Player
model which saves the player's name, the date they finished/died in the game. It keeps track of the score as well, but that's not implemented.
Let's go back to the file myfirstgame/views.py
and look at lets_adventure()
function.
Need to refactor the code a little by creating player_form
variable:-
elif current_room == "red_room":
# In the room with the dragon
if answer in ["flee"]:
...
elif answer in ["stay"]:
print("STAY")
context["message"] = "Dragon gave a huge roar and eats you. GAME OVER!"
# New
player_form = PlayerForm()
context['form'] = player_form
return render(request, 'myfirstgame/index.html', context)
Next step is saving the player's game information, in the same section of code, add the new code as follows:
current_player = data.get("current_player")
context['current_player'] = current_player
current_room = data.get("room")
answer = data.get("answer")
...
if current_room == "two_doors":
...
elif current_room == "red_room":
# In the room with the dragon
if answer in ["flee"]:
...
elif answer in ["stay"]:
print("STAY")
context["message"] = "Dragon gave a huge roar and eats you. GAME OVER!"
player_form = PlayerForm()
context['form'] = player_form
# New
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
return render(request, 'myfirstgame/index.html', context)
We created current_player
variable earlier, this will be used to save the name to the new player
to our database.
Next is saving the current date and time to when the game ended.
Finally player.save()
will save this data to the database.
NOTE: Read more about what Django does on save().
Remember to save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
red
- Submit
flee
- Back at room with two doors, select
red
- Submit
stay
- Game over, back at the start to begin the game again.
Missing players listings
Notice anything?
The latest player who ended the game is not listed on the page, this is because we added created players
object before we saved the player's details when player chose to stay in the red room:
context['players'] = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]
We will need to call this again to get the updated list of players
to return to context for the renderer.
elif current_room == "red_room":
# In the room with the dragon
if answer in ["flee"]:
...
elif answer in ["stay"]:
print("STAY")
context["message"] = "Dragon gave a huge roar and eats you. GAME OVER!"
player_form = PlayerForm()
context['form'] = player_form
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
# New
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]
context["players"] = players
return render(request, 'myfirstgame/index.html', context)
Remember to save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
red
- Submit
flee
- Back at room with two doors, select
red
- Submit
stay
- Game over, back at the start to begin the game again.
You should see the latest player's name listed similar to the following:
Go to http://127.0.0.1:8000/admin to open the admin dashboard. Click on Players
. Click on the latest player's name and you will find the name and date of when the game ended pulled from the database.
Re-ordering the list of players in your templates
At the moment, the list of players is in ascending order by default.
Change in following functions:
index()
lets_adventure()
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("game_end")[:5]
to
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("-game_end")[:5]
Remember to save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
red
- Submit
flee
- Back at room with two doors, select
red
- Submit
stay
- Game over, back at the start to begin the game again.
The names should be sorted in descending order now.
Using Messages - Django in-built messages framework
Did you notice that the Game Over message doesn't appear anymore?
We can fix that, since we are redirecting to load the index page, the context is not passed, we can use Django's messages framework.
Let's go back to the file myfirstgame/views.py
and look at lets_adventure()
function.
At the top of the file, add the following:
from django.contrib import messages
Then go to the if statement checking for "red_room"
and add the following changes.
elif current_room == "red_room":
...
elif answer in ["stay"]:
# Remove this line
# context["message"] = "Dragon gave a huge roar and eats you. GAME OVER!"
# Add this NEW line
messages.add_message(request, messages.INFO, "Dragon gave a huge roar and eats you. GAME OVER!")
Save the changes.
Let's now open and edit myfirstgame/templates/myfirstgame/index.html
and add the new code:
{% block content %}
<div class="content container">
<div class="row">
<div class="col-md-12">
<!-- New - start-->
{% if messages %}
<div class="messages">
{% for message in messages %}
<p{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</p>
{% endfor %}
</div>
{% endif %}
<!-- New - end -->
...
Let's break it down...
{% if messages %}
Check if there's messages from Django's message framework
{% for message in messages %}
If there's messages from the message framework, it will go through a for
loop
<p{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</p>
Each message is displayed, and if there's message tags, a class is created with the message tags.
Remember to save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
red
- Submit
flee
- Back at room with two doors, select
red
- Submit
stay
- Game over, back at the start to begin the game again.
You should see the Game Over message appearing.
We have now completed the section dealing with the room when you pick the red door.
Exercise: You can try and change the other message prompts using Django's Message Framework instead of returning message
in the context
when rendering the template.
Pick Blue Room
These are the things we want to do when we enter the blue room
- Display message that player is now in the blue room with a chest and a sleeping guard, and ask what they want to do
- If player picks the chest, list out the items in the chest and ask what they want to do next.
- If they ignore the item and go to sleeping guard, or take the items and then go to sleeping guard.
- Choose to
check
,sneak
,attack
the guard.
The Treasure Chest
- Choose to open treasure chest
- We want to display the items in the chest (using list)
- Ask player if they want to take or leave the items
- If they take the items, drop sword and pick up new one and let player know they also picked up the rest of the treasure
- Leave the items, the next screen will be checking out the guard
Let's choose the treasure chest
Let's go back to the file myfirstgame/views.py
and look at lets_adventure()
function.
elif current_room == "blue_room":
...
if answer in ["treasure", "chest", "left"]:
msg = "Oooh, treasure! Do you [open] or [ignore]?"
messages.add_message(request, messages.INFO, msg)
return render(request, 'myfirstgame/adventure.html', context)
If current_room
is "blue_room"
, then
- Player chooses either
"treasure"
,"chest"
or"left"
messages.add_message(request, messages.INFO, msg)
- Add the message,
msg
, to Django's message framework
- Add the message,
- Render the
adventure
HTML page
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
- Submit your name
- Submit
blue
- Submit
treasure
You should see the following:
Let's open the treasure chest...
Go to the file myfirstgame/views.py
and look at lets_adventure()
function.
elif current_room == "blue_room":
...
if answer in ["treasure", "chest", "left"]:
...
elif answer == "open":
msg = "Let's see what's in here... /grins. The chest creaks open, and the guard is \
still sleeping. That's one heavy sleeper! You found some"
# Awesome string function to join a list of items separating them with a comma
treasure_contents = ", ".join(treasure_chest)
msg = "{} {}! Do you [take] the [treasure] or check out the [guard]?".format(msg, treasure_contents)
messages.add_message(request, messages.INFO, msg)
return render(request, 'myfirstgame/adventure.html', context)
Note: We will start using []
instead of <<>>
in our messages to denote actions for players to choose from. Keep this in mind as we go through the code later.
Back to stepping through the code...
When the player submits "open"
, we create msg
to start off the next storyline.
treasure_contents = ", ".join(treasure_chest)
Using string's join
function to create treasure_contents
list by joining its contents separated with a comma. You can try this yourself in the Python interpretor.
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
- Submit your name
- Submit
blue
- Submit
treasure
- Submit
open
You should see the following:
Now let's take the treasure!
Go to the file myfirstgame/views.py
and look at lets_adventure()
function.
elif current_room == "blue_room":
...
if answer in ["treasure", "chest", "left"]:
...
elif answer == "open":
...
elif answer in ["take", "treasure"]:
# Remove the sword
treasure_chest.remove("sword")
msg = "<p>You take the shinier sword from the treasure chest. It does looks exceedingly shiney.</p><p>Woohoo! Bounty and a shiney new sword. /drops your crappy sword in the empty treasure chest.</p>"
# Make a copy of the list and remove list items
temp_treasure_list = treasure_chest[:]
treasure_contents = ", ".join(treasure_chest)
msg = "{}<p>You also receive {}</p>".format(msg, treasure_contents)
for treasure in temp_treasure_list:
treasure_chest.remove(treasure)
if len(treasure_chest) == 0:
msg = "{} <p>Yay, you looted all the items in the chest. Now let's have fun with the guard.</p>".format(msg)
messages.add_message(request, messages.INFO, msg)
return render(request, 'myfirstgame/adventure.html', context)
Here we are making a copy of the treasure_chest
list:
temp_treasure_list = treasure_chest[:]
Then we create treasure_contents
string variable using the Python's inbuilt string function called join
. This will create a string with all the items in the list separated by a comma. A very handy functions.
treasure_contents = ", ".join(treasure_chest)
We use string formatting to build us the message to send back to the adventure.html
.
msg = "{}<p>You also receive {}</p>".format(msg, treasure_contents)
In the for
loop, we will remove the items in the temp_treasure_list
for treasure in temp_treasure_list:
treasure_chest.remove(treasure)
Then if the treasure_chest
is empty, we append another part onto the msg
string variable with string formatting again.
if len(treasure_chest) == 0:
msg = "{} <p>Yay, you looted all the items in the chest. Now let's have fun with the guard.</p>".format(msg)
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
blue
- Submit
treasure
- Submit
open
- Submit
take
You should see the following:
Note: The HTML <p>
tags are not appearing in the message. This is because the HTML needs to be escaped when the page is rendered. We use safe
filter to say that the text is safe, and we can now escape
it to render the HTML tag as expected.
Go to file myfirstgame/templates/myfirstgame/adventure.html
, and update with the following:
{ message|safe|escape }}
The code should look like the following:
{% extends 'myfirstgame/base.html' %}
{% block content %}
<div class="content container">
<div class="row">
<div class="col-md-12">
{% if messages %}
<div class="messages">
{% for message in messages %}
<p{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|safe|escape }}</p>
...
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
blue
- Submit
treasure
- Submit
open
- Submit
take
You should see the following, the <p>
tags are now rendered:
The guard
Now that we have taken the treasure, the player's next challenge is the guard.
check
the surround area and the guard - nothing happens, ask player these options againsneak
up on the sleeping guard - GAME OVER, player diesattack
the guard - GAME OVER, player wins
Go to file myfirstgame/templates/myfirstgame/adventure.html
, and update with the following:
elif current_room == "blue_room":
...
if answer in ["treasure", "chest", "left"]:
...
elif answer in ["check", "sneak", "attack"]: # New - Start
msg = guard(answer)
messages.add_message(request, messages.INFO, msg)
if answer in ["sneak", "attack"]:
player_form = PlayerForm()
context['form'] = player_form
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("-game_end")[:5]
return redirect('index')
return render(request, 'myfirstgame/adventure.html', context)
# New - End
return redirect('index')
...
Let's break this down:
elif answer in ["check", "sneak", "attack"]:
msg = guard(answer)
messages.add_message(request, messages.INFO, msg)
If the player submits "check"
, "sneak"
or "attack"
, then it calles a function called guard()
passing in answer
. This returns a message (string variable) depending on what the answer
was submitted.
It adds the message to the Django message framework, and this will be displayed when the HTML page is rendered.
if answer in ["sneak", "attack"]:
player_form = PlayerForm()
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("-game_end")[:5]
return redirect('index')
If it's "sneak"
or "attack"
only then as before, save the player's name and when the game ended to the database. Update the players
listings and redirect to the index
page.
guard()
def guard(choice):
actions_dict = {"check":"<p>You see the guard is still sleeping, you need to get to that door \
on the right of him. What are you waiting for?</p>",
"sneak":"<p>You approach the guard, he's still sleeping. Reaching for the door,\
you open it slowly and slip out. YOU WON THE GAME, CONGRATS!</p>",
"attack":"<p>You swiftly run towards the sleeping guard and knock him out with \
the hilt of your shiney sword. Unfortunately it wasn't hard enough. GAME OVER!<p>"}
if choice in actions_dict.keys():
if choice == "check":
msg = "{} <p>Do you [check] out area around the guard, [sneak] up on the guard, or [attack] the guard?</p>".format(actions_dict[choice])
else:
msg = actions_dict[choice]
return msg
guard()
function requires an argument to be passed in, which is the choice (string) made by the player.
The actions_dict
contains 3 entries and if the choice
made matches
"check"
- Append the string after the text from"check"
inactions_dict
, so we can let the player know what the options are to choose from again.- Otherwise (
"sneak"
or"attack"
) - Just return the text from"sneack"
or"attack"
inactions_dict
.
Example string returned from guard()
function:
"check"
<p>You see the guard is still sleeping, you need to get to that door on the right of him. What are you waiting for?</p> <p>Do you [check] out area around the guard, [sneak] up on the guard, or [attack] the guard?</p>
"sneak"
<p>You approach the guard, he's still sleeping. Reaching for the door, you open it slowly and slip out. YOU WON THE GAME, CONGRATS!</p>
"attack"
<p>You swiftly run towards the sleeping guard and knock him out with the hilt of your shiney sword. Unfortunately it wasn't hard enough. GAME OVER!<p>
Ignore Treasure Chest and Check out Guard
Player is in the blue_rooom
(picking the blue door), player chooses to check out guard, ignoring the treasure chest altogether.
We haven't handled this part yet, so let's edit myfirstgame/views.py
in lets_adventure()
section.
This is pretty straight forward
- User submits
"guard"
inblue_room
with chest and sleeping guard. - Renders
adventure.html
template and display the messages corresponding to"check"
(loops around to ask these options again),"sneak"
(Wins, game ends, and onindex.html
again) or"attack"
(lose, game ends, and onindex.html
).
Add the following code:
elif current_room == "blue_room":
...
elif answer in ["guard"]:
msg = "<p>Let's have fun with the guard.</p>\
<p>Do you [check] out area around the guard, [sneak] up on the guard, \
or [attack] the guard?</p>"
messages.add_message(request, messages.INFO, msg)
return render(request, 'myfirstgame/adventure.html', context)
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
blue
- Submit
guard
- Submit
sneak
- Game ends, and you win
Opens Treasure Chest, not take any treasure and checks guard instead
Player is in the blue_room
with chest and sleeping guard. Player decides to open the treasure chest, and after seeing the treasure, the player decides to "ignore"
it. This will bring the player to check out the guard again. We can edit the code we have above to include a check for "ignore"
.
We haven't handled this part yet, so let's edit myfirstgame/views.py
.
elif current_room == "blue_room":
...
elif answer in ["guard", "ignore"]: # Update: Added ignore to the list
msg = "<p>Let's have fun with the guard.</p>\
<p>Do you [check] out area around the guard, [sneak] up on the guard, \
or [attack] the guard?</p>"
messages.add_message(request, messages.INFO, msg)
return render(request, 'myfirstgame/adventure.html', context)
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
blue
- Submit
left
- Submit
ignore
- Submit
check
- Submit
attack
- Game ends, and you lose.
Entering something not recognised
After player submit their name, the user should be entering a blue or red door, provided they enter the right text. What if they enter the wrong text and it's not recognised? It should let the user know that what they entered could not be understood, and ask to enter again.
Curently the code doesn't handle this yet, and just renders the default template if it doesn't match any of the if
statements.
We haven't handled this part yet, so let's edit myfirstgame/views.py
in lets_adventure()
section.
Entering wrong answer in Room with Red and Blue Door
if current_room == "two_doors":
if answer in ["red", "left"]:
...
else: # New code starts here
print("Don't understand which door you picked")
context["current_room"] = current_room
msg = "Don't understand which door you picked. Try again. Hint: [red] or [blue]"
messages.add_message(request, messages.INFO, msg)
return render(request, 'myfirstgame/adventure.html', context)
# New code ends
Again the print
is used to print out to the terminal when we are running the Django server. Feel free to remove this.
Set the context["current_room"]
to current_room
variable as we haven't changed it since we obtained it from the form submission.
Create a new message to display on the HTML page when it's rendered so the player gets a hint on what to do next.
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
rubbish
You should see the following:
Entering wrong answer in the Red Room (with the Dragon)
We haven't handled this part yet, so let's edit myfirstgame/views.py
in lets_adventure()
section.
if current_room == "two_doors":
...
elif current_room == "red_room":
if answer in ["flee"]:
...
#elif answer in ["stay"]:
else:
if answer in ["stay"]:
msg = "Dragon gave a huge roar and eats you. GAME OVER!"
else:
msg = "It eats you. Well, that was tasty! GAME OVER!"
messages.add_message(request, messages.INFO, msg)
player_form = PlayerForm()
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("-game_end")[:5]
return redirect('index')
We are replacing
elif answer in ["stay"]:
with
else:
This means anything entered that is not "flee"
will end up in the code after else:
, this includes if the player enters "stay"
.
If "stay"
, create the message to be passed back by Django's message framework letting the player know that they game ended, otherwise create another message to be passed back to the message framework. They both doe the same thing, but the message to be displayed is different for this example.
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this with entering stay
:
- Submit your name
- Submit
red
- Submit
stay
- Game ends and
Dragon gave a huge roar and eats you. GAME OVER!
is displayed.
You should see the following:
Let's test this with entering aah
:
- Submit your name
- Submit
red
- Submit
aah
- Game ends and
It eats you. Well, that was tasty! GAME OVER!
is displayed.
You should see the following:
Let's tidy up the code a bit
There's some repetition, we can tidy it by replacing it with a function.
Let's create a new function, place it after guard()
function.
def save_player(current_player):
player_form = PlayerForm()
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
return
It takes in the current_player
name and saves it to the database.
Saving player when it's Game Over
Let's edit myfirstgame/views.py
in lets_adventure()
section.
In the red door room
Replace the following:
player_form = PlayerForm()
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
with
save_player(current_player)
Code should look like the following:
if current_room == "two_doors":
...
if answer in ["red", "left"]:
...
elif current_room == "red_room":
if answer in ["flee"]:
...
else:
if answer in ["stay"]:
...
else:
...
messages.add_message(request, messages.INFO, msg)
# New Code - Start
player_form = save_player(current_player)
# New Code - End
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("-game_end")[:5]
...
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this with entering stay
:
- Submit your name
- Submit
red
- Submit
stay
- Game ends and
Dragon gave a huge roar and eats you. GAME OVER!
is displayed. - The player name is in the listings.
In the blue door room
Let's edit myfirstgame/views.py
in lets_adventure()
section.
Replace the following:
player_form = PlayerForm()
player = player_form.save(commit=False)
player.name = current_player
player.game_end = timezone.now()
player.save()
with
player_form = save_player(current_player)
Code should look like the following:
elif current_room == "blue_room":
...
if answer in ["treasure", "chest", "left"]:
...
elif answer in ["check", "sneak", "attack"]:
msg = guard(answer)
messages.add_message(request, messages.INFO, msg)
if answer in ["sneak", "attack"]:
# New Code - start
player_form = save_player(current_player)
# New Code - end
players = Player.objects.filter(game_end__lte=timezone.now()).order_by("-game_end")[:5]
return redirect('index')
...
Save the file.
Your Django server should be still running in your terminal. If not, python manage.py runserver
to run it again, and go to http://127.0.0.1:8000.
Let's test this:
- Submit your name
- Submit
blue
- Submit
left
- Submit
ignore
- Submit
check
- Submit
attack
- Game ends, and you lose.
- The player name is in the listings.
That's a wrap!
Congrats! You've created a basic text-based adventure game.
What can you do to improve it? There's lots of refactoring you can do, keep track how many times you checked on the guard and display that after you win/lose the game.
Or add images at each screen?
If you have any questions, email us at [email protected].