A Simple Game

Introduction

From Wikipedia:

Rock-paper-scissors is a hand game played by two people. The objective is to select a gesture which defeats that of the opponent. Gestures are resolved as follows:

In the following sections we'll build a web application that allows us to play rock-paper-scissors against the computer.

Game Implementation

Let's first describe how to implement the game in a webless fashion.

To begin, we'll need a dictionary that contains the rules of which gesture defeats that of the opponent:

rules = {
    'rock'     : 'scissors', 
    'scissors' : 'paper', 
    'paper'    : 'rock'
}

Each dictionary key defeats its associated value. For example: 'rock' defeats 'scissors'.

We'll also need a list containing only the gestures, which happen to be the keys of our rules dictionary:

gestures = rules.keys()

We can use the random.choice() standard library function to have the computer randomly choose one of the three gestures:

computer_choice = choice(gestures)

Let's assume that the user's input is contained in a variable named user_choice (we'll see how to get that value later on). We just need to add the logic to determine who wins or if it's a tie:

if user_choice == computer_choice:
    message = "Both chose %s. It's a tie!" % (user_choice,)
    
elif computer_choice == rules[user_choice]:
    message = '%s beats %s. You win!' % (user_choice, computer_choice)

else:    
    message = '%s beats %s. You loose!' % (computer_choice, user_choice)

The only thing left is to display the contents of message. This, of course, is a web specific issue that will be explained in a moment.

We are now ready to make our game a web application.

Building the Web Application

  1. Create an application called game. In the command line window (inside the sigcse directory) type:

    python manage.py startapp game
  2. Create the view containing the game logic we described above. Open and edit the file game/views.py so that it contains the following:

    from django.shortcuts import render
    from random import choice
    
    rules = {
        'rock'     : 'scissors', 
        'scissors' : 'paper', 
        'paper'    : 'rock'
    }
    
    gestures = rules.keys()
    
    def play(request, user_choice):
        
        assert user_choice in gestures
    
        computer_choice = choice(gestures)
        
        if user_choice == computer_choice:
            message = "Both chose %s. It's a tie!" % (user_choice,)
            
        elif computer_choice == rules[user_choice]:
            message = '%s beats %s. You win!' % (user_choice, computer_choice)
        
        else:    
            message = '%s beats %s. You loose!' % (computer_choice, user_choice)
    
        return render(request, 'play.html', {'message': message})

    Note that the user_choice is a view function parameter. In the next step we'll specify what values can go in that parameter.

  3. Edit the urls.py file by adding the highlighted line in order to link the play view function with the /game/ URL pattern:

    from django.conf.urls.defaults import patterns, include, url
    
    # Uncomment the next two lines to enable the admin:
    # from django.contrib import admin
    # admin.autodiscover()
    
    urlpatterns = patterns('',
        # Examples:
        # url(r'^$', 'sigcse.views.home', name='home'),
        # url(r'^sigcse/', include('sigcse.foo.urls')),
        (r'^foo/', 'sigcse.examples.views.foo'),
        (r'^game/(rock|paper|scissors)/', 'sigcse.game.views.play'),
    
        # Uncomment the admin/doc line below to enable admin documentation:
        # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    
        # Uncomment the next line to enable the admin:
        # url(r'^admin/', include(admin.site.urls)),
    )

    URL patterns are actually regular expressions. The parenthesis specify that we are capturing a group that contains one of three possible values (rock, paper, or scissors). Any captured group is sent as a parameter to the view function (user_choice in the play function in our case).

  4. Create the play.html file in the templates folder. Basically we only need to display the contents of the message template variable using whatever format we like. Everything else has been taken care of by the base.html template:

    {% extends "base.html" %}
    
    {% block main %}
        <h1>{{ message|capfirst }}</h1>
    {% endblock %}
  5. Test the web application using any of the following URLs:

    Reload your browser's current page to see different results using the same gesture.