Pick Red Door

When we submit "red" to pick the red door, we should

  1. Message that we encounter a dragon!
  2. 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 the context variable to "red_room"
  • set the message for the context 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:

  1. Submit your name
  2. Submit red
  3. Submit flee
  4. Back at room with two doors, select red
  5. Submit flee
  6. 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:

  1. Submit your name
  2. Submit red
  3. Submit flee
  4. Back at room with two doors, select red
  5. Submit stay
  6. 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:

  1. Submit your name
  2. Submit red
  3. Submit flee
  4. Back at room with two doors, select red
  5. Submit stay
  6. 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:

  1. Submit your name
  2. Submit red
  3. Submit flee
  4. Back at room with two doors, select red
  5. Submit stay
  6. 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:

  1. Submit your name
  2. Submit red
  3. Submit flee
  4. Back at room with two doors, select red
  5. Submit stay
  6. 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:

  1. Submit your name
  2. Submit red
  3. Submit flee
  4. Back at room with two doors, select red
  5. Submit stay
  6. 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
  • 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.

  1. Submit your name
  2. Submit blue
  3. 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.

  1. Submit your name
  2. Submit blue
  3. Submit treasure
  4. 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:

  1. Submit your name
  2. Submit blue
  3. Submit treasure
  4. Submit open
  5. 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:

  1. Submit your name
  2. Submit blue
  3. Submit treasure
  4. Submit open
  5. 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 again
  • sneak up on the sleeping guard - GAME OVER, player dies
  • attack 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" in actions_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" in actions_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" in blue_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 on index.html again) or "attack" (lose, game ends, and on index.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:

  1. Submit your name
  2. Submit blue
  3. Submit guard
  4. Submit sneak
  5. 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:

  1. Submit your name
  2. Submit blue
  3. Submit left
  4. Submit ignore
  5. Submit check
  6. Submit attack
  7. 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:

  1. Submit your name
  2. 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:

  1. Submit your name
  2. Submit red
  3. Submit stay
  4. 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:

  1. Submit your name
  2. Submit red
  3. Submit aah
  4. 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:

  1. Submit your name
  2. Submit red
  3. Submit stay
  4. Game ends and Dragon gave a huge roar and eats you. GAME OVER! is displayed.
  5. 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:

  1. Submit your name
  2. Submit blue
  3. Submit left
  4. Submit ignore
  5. Submit check
  6. Submit attack
  7. Game ends, and you lose.
  8. 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].

results matching ""

    No results matching ""