The Professional Steve

Tutorials, developer resources and inspiration.

Making A Game In Python Part 1

Ok here we go!

This gonna be a little different than my python tutorials. My plan is simply to write from the seat of my pants, much as if you and I were talking, working on a game together. All the code will be freely available at github.com/NerdcoreSteve/python-adventure.

So, let’s decide what kind of game we’re going to make. I’m partial to text adventures as a first project. You know, it says something like “You’re in a room, there’s a door to your left, a penguin on your right…” etc.

So, we’re going to make a game that describes a room to you and gives you options. Talk to the penguin, open the door, pick up magical items, use weapons, wear armor, go on quests, etc.

So, the first thing I do when I start a project is create a “hello world” just like my first python tutorial. Well, it won’t say hello world.

print "You're darkly lit one-room house. Its raining outside. You can hear the drops hit the ceiling and can  see rain hit the window when lightning strikes in the distance, which it often does. The window is above a sink which is full of dirty dishes. On the oven beside the sink there is a pot full of boiling water. To your left there is a couch facing a television. The power's out so it's not on. Amazingly there's a penguin sitting on the couch, but they've turned to face you. Behind you is a pile of smelly blankets and an old set  of golf clubs."

(Scroll to the right to see the rest of the text.)

If you run that program, nothing happens except that you see text on the screen. Choices! I want choices!

print "You're darkly lit one-room house. Its raining outside. You can hear the drops hit the ceiling and can  see rain hit the window when lightning strikes in the distance, which it often does. The window is above a    sink which is full of dirty dishes. On the oven beside the sink there is a pot full of boiling water. To your left there is a couch facing a television. The power's out so it's not on. Amazingly there's a penguin        sitting on the couch, but they've turned to face you. Behind you is a pile of smelly blankets and an old set  of golf clubs."

print "\n1) talk to the penguin\n"

user_input = input("What will you do? ")

if int(user_input) == 1:
    print "\nYou say, \"Hello penguin.\n\n\"Hello Dave,\" replies the penguin."
else:
    print "\nI have no idea what you're talking about."

Ok, now we’re cooking with petrol! Here’s what we’ve got so far:

  1. We describe the scene
  2. We ask what the player wants to do and get the player’s input with the input function.
  3. We change user input to a number, specifically an int, and then we see if it matches one of our given choices.
  4. If it does match a choice, we tell the user what happens. If not we tell them we don’t know what they’re on about.

But this is still no good! If we hit the wrong choice the game is done! If we hit any choice the game is done! We need a loop, and a way to quit the loop:

print "You're darkly lit one-room house. Its raining outside. You can hear the drops hit the ceiling and can  see rain hit the window when lightning strikes in the distance, which it often does. The window is above a    sink which is full of dirty dishes. On the oven beside the sink there is a pot full of boiling water. To your left there is a couch facing a television. The power's out so it's not on. Amazingly there's a penguin        sitting on the couch, but they've turned to face you. Behind you is a pile of smelly blankets and an old set  of golf clubs."


user_input = ''
while user_input != 'q':
    print ""

    print "t) talk to the penguin"
    print "q) quit game"

    print ""

    user_input = raw_input("What will you do? ")

    print ""

    if user_input == 't':
        print "You say, \"Hello penguin.\"\n\n\"Hello Dave,\" replies the penguin."
    elif user_input == 'q':
        print "Hope you had fun!"
    else:
        print "I have no idea what you're talking about."

Ok, let’s break it down again:

  1. We print out the description like we’ve always done.
  2. We initialize the user_input variable to the empty string, a string with no characters in it.
  3. Then we loop until the user enters the letter q. (we get user input inside the loop)
  4. Remember, everything indented under the while statement is part of the while loop.

 

That’s probably enough for one post. Let’s do more in the next one.

Boolean Expressions in Python

Ok, one last thing before we get to game programming. Comparisons.

def comparisons(number):
    if number > 5:
        print str(number) + " is greater than 5"
    if number == 4:
        print str(number) + " is 4"
    if number < 3:
        print str(number) + " is less than 3"
    if number >= 25:
        print str(number) + " is greater than or equal to 25"
    if number <= 0:
        print str(number) + " is less than or equal to 0"

comparisons(6);
comparisons(4);
comparisons(2);
comparisons(101);
comparisons(-3);

I think that, if you’ve read all my previous tutorials, this should be relatively straightforward. We’ve got a function that takes a single argument. It expects numbers but won’t break if you give it strings.

In our function we have a bunch of if statements. Each if statement’s condition uses a different comparison operator. If the given condition is met, then the statement is printed.

I hope I’m not going too fast with this but I’m kinda excited to start on the game. :)

We still need to look at more complex expressions (they’re called boolean expressions because they either return a true or false value).

Check this out:

def more_complex_comparisons(number):
    if number < 5 and number > 0 and number != 2:
        print str(number) + " is less than 5, greater than 0, and not 2"
    if number == 50 or (number < 0 and number >= -50):
        print str(number) + " is 50 or less than 0 as well as being greater than or equal to -50"
    if (number < 5 and number > 0 and number != 2) or (number == 50 or (number < 0 and number >= -50)):
        print str(number) \
            + " is less than 5, greater than 0, and not 2 or" \
            + " is 50 or less than 0 as well as being greater than or equal to -50"

more_complex_comparisons(3)
more_complex_comparisons(-3)

And our output (scroll to the right to see it all):

3 is less than 5, greater than 0, and not 2
3 is less than 5, greater than 0, and not 2 or is 50 or less than 0 as well as being greater than or equal to -50
-3 is 50 or less than 0 as well as being greater than or equal to -50
-3 is less than 5, greater than 0, and not 2 or is 50 or less than 0 as well as being greater than or equal to -50

I’m going to leave it to you to work out how these evaluate. I think the parentheses make it clear.

Ok, next time is game time!!!

Python and JSON

JSON is a file format that’s used all over the web and lots of other places. It’s especially convenient for Python programmers as it looks and acts just like a nested dictionary of lists and dictionaries.

Here’s an example JSON object:

{player:{weapons:['hammer', 'wrench'],
         armor:['saucepan', 'heavy blanked used as cape', 'combat boots']},
 monsters: ['giant fluffy kitty', 'donkey', 'can of spam', 'stack of pancakes']}

See what I mean? It’s a dictionary with two top-level entries. The first one being another dictionary, and the second one being just a list.

Let’s make a python version of that:

game_data = {'player':{'weapons':['hammer', 'wrench'],
             'armor':['saucepan', 'heavy blanked used as cape', 'combat boots']},
              'monsters': ['giant fluffy kitty', 'donkey', 'can of spam', 'stack of pancakes']}

print game_data['player']['weapons'][0]

Our output should be:

hammer

Ok, do you remember this bit from the last post?

foo_file = open("foo_file.txt", "w")
foo_file.write("Writin' to the foo file.\n");
foo_file.close

foo_file = open("foo_file.txt", "r")
print foo_file.read()
foo_file.close

The output from this file reading/writing is:

Writin' to the foo file

It also creates a file called foo_file.txt with that same text in it.

By the way, that ‘\n’ character just means new line. If you didn’t have the ability to specify a new line, all your files would be one extremely long line.

Ok, check this out:

import json

game_data = {'player':{'weapons':['hammer', 'wrench'],
             'armor':['saucepan', 'heavy blanked used as cape', 'combat boots']},
             'monsters': ['giant fluffy kitty', 'donkey', 'can of spam', 'stack of pancakes']}

game_data_file = open("game_data.json", "w")
game_data_file.write(json.dumps(game_data, game_data_file))
game_data_file.close

game_data_file = open("game_data.json", "r")
loaded_game_data = json.loads(game_data_file.read())
game_data_file.close

print loaded_game_data['player']['weapons'][0]
print loaded_game_data['monsters'][2]

The output of this file is:

hammer
can of spam

Let’s break this program down

The first line imports the json module.

The second line makes our game_data data structure.

The next line opens (or create) the game_data.json file.

This next line is a little tricky, you have to read it from the inside out. First we call json.loads and give it game_data as a parameter. json.loads will return a string formatted as json. This return value is then given to game_data_file.write, which writes our game data to the file.

The text of that file looks like this (scroll to the right to see it all):

{"player": {"weapons": ["hammer", "wrench"], "armor": ["saucepan", "heavy blanked used as cape", "combat      boots"]}, "monsters": ["giant fluffy kitty", "donkey", "can of spam", "stack of pancakes"]}

The next line closes the file we’ve written to.

Ok, now we have three lines of code that open the file, read its contents into a variable, and then close the file. Again, just read it from the inside out. game_data_file.read() returns the contents of the file as a string. json.loads takes that string and turns it into the same data structure we had to begin with.

The last two lines just demonstrate it’s that same data structure.

Why go through all this? Well, we now have the ability to save data to the disk! We can write games that allow us to save the player’s progress!

Ok, I know I said I’d start our game next time but I just realized there are a few things I’ve not covered yet. They’re just a few things, I promise. :)

Reading and Writing to Files in Python

Ok, I was going to start us making a game, but…

There’s only a few things to cover and I think I’m done introducing you to Python!

Oh, sure, there’s more stuff. There’s tons of stuff. But I think I’ve covered everything you need to get started, except the reading and writing of files. I’d also like to show you how python reads and writes json (JavaScript Object Notation), a commonly used format that makes passing around data super easy. We’ll be using it to let players save in our game.

Anyway, here’s how you write to a file in python:

foo_file = open("foo_file.txt", "w")
foo_file.write("Writin' to the foo file.\n");
foo_file.close

The open function takes two arguments: the name of the file and what you intend to do with it. “w” is for writing to a file, “r” is for reading a file.

No output for this program, but if you run it you’ll find that it creates a file called foo_file.txt. If you open it up, you’ll see the following:

Writin' to the foo file.

By the way, the foo_file.close business doesn’t matter much with small programs like this, but if you start to make bigger programs, you’ll need to close those things up or your program could start to run slowly as you leave more and more files just hanging out, swinging in the wind, on a kite goin’ nowhere.

Anyway, here’s how you read a file:

foo_file = open("foo_file.txt", "r")
print foo_file.read()
foo_file.close

Naturally the output to this program is:

Writin' to the foo file.

Ok, next post is about reading and writing json files.

CRM Log 1

I admit it. I have a problem.

I’m definitely the sort of person who jump from project to project. Now I have a new one.

Customer Relationships

After thinking about it and talking with my wife, it seems like business with customers are a better target for a business. This will be an app that helps businesses easily keep track of customer interactions: sales, fulfillment, support issues, all that stuff.

Like projects before this, I’ll keep a log that shows my progress. My progress for this log is this: the site’s up, and you can log in and out. That’s it for now.

I’ve been reading The Lean Startup quite a bit, so I’ll be logging more than just my technical progress. I’m going for actual customers. My goal is to learn how to make money with this thing and I aim to keep at it until I succeed, or it’s clear I need to to make some other product.

Stay tuned.

Functions in Python

This post’ll be quick. I just want to let you know how functions work so we can get to the good stuff, making a game. Functions are bits of code you can set off to one side so they can be executed again and again in your program. Here’s an example:

def print_hello():
    print "Why hello there!"

print_hello()

Your output goeth thusly:

Why hello there!

Why bother, you may ask? What if I want to do that more than once?

def print_hello():
    print "Why hello there!"

print_hello()
print_hello()
print_hello()

Yon output:

Why hello there!
Why hello there!
Why hello there!

Functions allow you to reuse code. You can also customize each call by giving your function arguments, like so (scroll to the right to see all the code):

def mad_lib(person, verbing, thing, place):
    print person + " is " + verbing + " quite vigorously on the " + thing + " at the " + place + "."

mad_lib("Batman", "bathing", "porcupine", "Eiffel Tower")
mad_lib("Barak Obama", "Kung Fu Fighting", "impromptu stage setup", "local Starbucks")
mad_lib("That pink kitty cat", "peeing", "head of Russel Brand", "BBC")

Your output sir:

Batman is bathing quite vigorously on the porcupine at the Eiffel Tower.
Barak Obama is Kung Fu Fighting quite vigorously on the impromptu stage setup at the local Starbucks.
That pink kitty cat is peeing quite vigorously on the head of Russel Brand at the BBC.

Arguments can be anything: strings, numbers, lists, dictionaries, whatever. You can write any code in a function that you would write anywhere else. Just remember to indent your code properly or the python interpreter won’t know you intended it to be part of your function.

Arithmetic In Python

Ok, I’ve avoided this long enough. It’s time to get back to my Python tutorial series. Next up: simple arithmetic.

Let’s add two numbers:

print 1 + 1

Run that sucker and you’re bound to get the answer: 2.

Similarly, I bet you can guess what these lines of code will get you:

print 5 - 2
print 5 * 8
print 10 / 2

That’s right, 3, 40, and 5.

Here’s a bit of a gotcha:

print 10 / 3

That gives you 3! What the heck?

If you want a decimal answer you’re going to have to tell Python that by including at least one decimal:

print 10.0 / 3

The above will get you 3.33333333333.

The order of operations in Python is pretty much what you would expect in any math class, but I tend to make liberal use of parentheses just to make everything clear:

print 3 * (4 + 8) - (22 * 7)

The above gets you -118.

Of course, if you want to do more than just simple stuff like the above there’s always the math module:

import math

print math.sqrt(math.pow(5 - 1, 2) + math.pow(1 - -2, 2))

If you’re interested, got the above equation from a distance formula example at Purplemath.

Using RequireJS

I may have already made mention of this neat JavaScript library called RequireJS, it allows you to modularize your javascript code.

Let’s say I had a simple page that uses JavaScript to make a button behavior:

HTML:

<!DOCTYPE html>
<html>
    <head>
        <script src="jquery-1.11.2.js" defer></script>
        <script src="norequire.js" defer></script>
    </head>
    <body>
        <h1>No requirejs</h1>
        <p class="some_paragraph">This is a paragraph</p>
        <button class="some_button" type="button">click it</button>
    </body>
</html>

JavaScript:

$(".some_button").click(function() {
    $(".some_paragraph").html("You changed the text!"); });

This example is pretty simple, but it already has two script tags at the top. In a large project, keeping track of a large number of script tags, as well as the order they need to be placed (since the script referred to by one tag can often depend on the script in one of the other tags) can quickly become too much to manage.

All the code from the above and below examples are at
https://github.com/NerdcoreSteve/requrejs_examples
by the way :)

Here’s something a little better:

<!DOCTYPE html>
<html>
    <head>
        <script data-main="scripts/main" src="scripts/libraries/require.js"></script>
    </head>
    <body>
        <h1>No requirejs</h1>
        <p class="some_paragraph">This is a paragraph</p>
        <button class="some_button" type="button">click it</button>
    </body>
</html>

Now all we need is one script tag that tells us where require.js is and where our main.js is.

Have a look at the directory structure in the “require” folder of that github project. main.js is in our “scripts” folder:

require(["scripts/libraries/jquery-1.11.2.js"], function() {
    $(".some_button").click(function() { $(".some_paragraph").html("You changed the text!"); });
});

The previous code is now put into a function that itself is a parameter in a call of the require function. The first parameter of the require function is a string array detailing a list of dependencies for the code. In our case the only dependency is JQuery, which lives in a “libraries” folder in the project.

The upshot is that the code won’t run until the library or libraries it needs are loaded.

In the lazyload directory of this github project we see how we handle a library’s dependency on other libraries. In this case, the lazy-load JQuery plugin.

To handle this kind of dependency you need to call RequireJS’s config function:

requirejs.config({
    shim: {
        'jquery': [],
        'jquery.lazyload': ['jquery']
    },

    paths: {
        'jquery': 'libraries/jquery-1.11.2.min',
        'jquery.lazyload': 'libraries/jquery.lazyload.min'
    }
});

require(['jquery.lazyload'], function() {
    $(function() {
        $('img.lazy').lazyload();
    });
});

The object I’m passing to requirejs.config has path information for my libraries in the paths sub-object, and dependency information in the shim sub-object. That’s all there is too it!

MongoDB And Java

MongoDB is pretty great. It’s easy to use and has none of the complications of SQL. It has a nice and understandable Javascripty syntax. I prefer to use Node with Mongo, but if you have to, here’s how you include it in your java project (using maven):

If you’re using Maven just stick this in your dependency list:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>2.12.5</version>
</dependency>

And now you’re ready to interact with the MongoDB driver. Here’s the MongoDB project’s getting started page and here’s another tutorial I found helpful.

Cloud Log 3

Soooooo……

Well….

I just want to say that JAX-RS sucks.

Now that I’m using Node.js with Express, things are moving sooooo much faster.

I did finish the Twitter-like app using Tomcat and JAX-RS, but after a lot of headaches trying to adapt that application to my Dropbox-like app I finally made the switch to something more sensible.

Just this morning I figured out how to grab POST request data with the Express body-parser module.

Now I just need to finish up writing the api calls. They’re stupid simple to write:

app.post('/users/register', function (request, response) {
    response.send('Got a POST /users/register for username ' + request.body.username
             + ' with password ' + request.body.password);
})

Not exactly the most secure code, I know, but this is a school assignment after all.

Here’s the github for this final project:
https://github.com/NerdcoreSteve/CloudDrive

Follow

Get every new post delivered to your Inbox.

Join 210 other followers