The Professional Steve

Tutorials, developer resources and inspiration.

Regular Expressions In Python Part 1

Ok, first thing you need to know about regular expressions (or regex) is that they are an arcane magic you can use to do a lot with a little code. Second thing you need to know is that regular expressions are all about doing stuff with strings.

You get Python’s regex by importing the re module at the top of your python file, like so:

import re

Ok, let’s start with searching for patterns

import re

if re.search('a', 'a'):
    print "found it!"
else:
    print "didn't find it :("

If you run this code, you’ll print out “found it!”

Now replace

if re.search('a', 'a'):

with

if re.search('a', 'batman'):

You’ll still get a “found it!”

As you may have guessed, re.search takes the thing you give it in the first argument, and then searches for that thing in the second. We call that first thing a pattern.

Here are some more examples:

pattern string found it?
aa Banana didn’t find it :(
pie I like pie! found it!
hop Linus torvald is terrible at hopscotch found it!
a* cucumber found it!

Wait a minute, what’s up with that last one? How does ‘cucumber’ match the pattern ‘a*’? In regex patterns, the ‘*’ character has a special meaning. Are there more special regex characters? You bet your ass there are.

I’ll tell you more in part 2.

Making A Game In Python Part 5

I’m making a text-adventure in Python!

Here are the previous posts about this:
Making A Game In Python Part 1
Making A Game In Python Part 2
Making A Game In Python Part 3
Making A Game In Python Part 4

Here is the link to the code on github.

And here is the trello board I’m using to track my progress.

Ok, let’s get back to it!

Last time I said I wanted to have the game remember the name you give the penguin. I think I’ll create a separate data structure for this called “saved_data”. Later I’ll write some code to handle naming the penguin, but for now I’ll just add the player name to this structure:

player_name = raw_input("What's your name? ")

saved_data = {"player name" : player_name}

Next I’m going to change all instances where I typed something like this:

"Hello " + player_name + ", said the penguin"

To this:

"Hello {{player name}}, said the penguin"

Then I’ll write a function that takes “Hello {{player name}}, said the penguin”, looks at the saved data, and replaces “{{player name}}” with whatever’s in saved_data. If nothing is there, then it will use “player name” or whatever’s inside the double curly braces as the default. I’ll call the function add_saved_data.

So, if the player’s name is Reggie, then this code:

print add_saved_data("Hello {{player name}}, said the penguin")

should print out:
“Hello Reggie, said the penguin.”

The two places I want to call this function are when I print out a room’s description, and when I print out the player’s choices:

    print "\n" + add_saved_data(current_room["description"]) + "\n"

    for choice in current_room["choices"]:
        print choice["input"] + ") " + add_saved_data(choice["description"])
    print "q) quit game\n"

Ok, here’s the source code for add_saved_data:

def add_saved_data(string):
    matches = re.search("\{\{(.*?)\}\}", string)
    if(matches):
        default = matches.group(1)
        return add_saved_data(
                re.sub(
                    matches.group(0),
                    saved_data[default] if default in saved_data else default,
                    string))
    else:
        return string

Since this function is kind of complicated, I’m going to take a few posts to explain what it does.

In order to do that, I’ll first need to talk about regular expressions, function composition, and recursion.

Making A Game In Python Part 4

So, I’m making this game in python. Here are the previous posts about it:

Part 1
Part 2
Part 3

As always, the latest code for the game is available here on github.

Now, on with our adventure in making adventure…

In the last post we had developed a “real” game. Now I think it’s time to see how far we can get with what we’ve got. Before we add more code, let’s try and add some game content first: (again, you’ll have to scroll to the right to see it all)

game_data = {"one-room house" : {"description" : "You're name is " + player_name + ". You're in a 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 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. It's turned to a channel that only gets static. Amazingly there's a penguin sitting on the couch. The penguin turns to face you when you look at it. Behind you is a pile of smelly blankets and an old set of  golf clubs.",
                                  "choices" : [{"input" : "t",
                                               "description" : "Talk to the penguin",
                                               "destination" : "penguin conversation"},
                                               {"input" : "l",
                                                "description" : "Look around the room again",
                                                "destination" : "one-room house"}]},
"penguin conversation" : {"description" : "You say, \"Hello penguin.\"\n\n\"Hello " + player_name + ",\"      replies the penguin.",
                          "choices" : [{"input" : "l",
                                        "description" : "look around the room again",
                                        "destination" : "one-room house"},
                                       {"input" : "a",
                                        "description" : "Ask the penguin what's going on.",
                                        "destination" : "penguin says what's up"},
                                       {"input" : "n",
                                        "description" : "Ask the penguin their name.",
                                        "destination" : "name the penguin"}]},
"penguin says what's up" : {"description" : "You say, \"What's going on?\"\n\n\"I heard a loud bang outside.  I think someone's out there.\" replies the penguin.\n\nJust then, you hear a loud noise. Some thing or some   one just hit the wall with a loud thud.",
                          "choices" : [{"input" : "l",
                                        "description" : "look around the room again",
                                        "destination" : "one-room house"},
                                       {"input" : "n",
                                        "description" : "Ask the penguin their name.",
                                        "destination" : "name the penguin"}]},
"name the penguin" : {"description" : "You say, \"What's your name?\"\n\nThe penguin says, \"You remember     it's...\"",
                          "choices" : [{"input" : "l",
                                        "description" : "look around the room again",
                                        "destination" : "one-room house"}]}}

I never did say in my tutorials what this \n or \” business is did I? \n means the program will output a new line. \” makes the program print the double quote character.

Already I can make a lot of game content with my little game program, but I can already see parts of the game that need expanding and improving.

I want to be able to name the penguin and have the game remember that name. If I name them, for example, Sparky, then I don’t want the game to call them “The Penguin” I want the game to call him Sparky.

Also, I don’t want to keep having to copy and paste the same choices over and over again. I pasted the “look around the room” choice a few times already. I should put them in another dictionary and then reference them in each scene.

I also think it’s high time I implemented the saving and loading of games. While I’m at it, I’d like the game to look for game files and ask if I want to make a new game with them.

There are a few other things I want to add, pretty much immediately.

I want an inventory, and I want to be able to have new choices when I have stuff in that inventory. For example, once I pick up a key, I should be able to open a lockbox I wasn’t able to open before. I should put a lockbox and key in that opening scene description to test this out.

I want to have some way to fight monsters, a battle engine.

And I should just build into the game that looking around is always a choice I can make. I don’t want to have to paste that choice into each scene. The game should remember my location and tell me what I should see when I look around.

Maybe I should tie certain choices to people, like the penguin, and locations? That might be getting ahead of myself.

Anyway, I’ll tackle the ‘name the penguin task’ next time. Also, I think it might be time to make a trello board. I’ll do that next post as well.

Making A Game In Python Part 3

So, the code’s gotten too big to keep copy and pasting so I’ll just need to give you links to the story so far:

Making A Game In Python Part 1

Making A Game In Python Part 2

I will show you this data structure (you’ll need to scroll to the right to see the whole thing):

game_data = {"one-room house" : {"description" : "You're name is " + player_name + ". 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.",
                                  "choices" : [{"input" : "t",
                                               "description" : "talk to the penguin"}]},
"penguin conversation" : {"description" : "You say, \"Hello penguin.\"\n\n\"Hello " + player_name + ",\"      replies the penguin."}}

This represents the game data as it currently stands, but this is no good. I need to change this structure so that each entry is the same. Each one should have it’s own set of choices and each choice should lead us to another entry in the dictionary.

Let’s fix that now:

game_data = {"one-room house" : {"description" : "You're name is " + player_name + ". 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.",
                                  "choices" : [{"input" : "t",
                                               "description" : "talk to the penguin",
                                               "destination" : "penguin conversation"},
                                               {"input" : "l",
                                                "description" : "look around the room again",
                                                "destination" : "one-room house"}]},
"penguin conversation" : {"description" : "You say, \"Hello penguin.\"\n\n\"Hello " + player_name + ",\"      replies the penguin.",
                          "choices" : [{"input" : "t",
                                        "description" : "talk to the penguin",
                                        "destination" : "penguin conversation"},
                                       {"input" : "l",
                                        "description" : "look around the room again",
                                        "destination" : "one-room house"}]}}

Now each “room” has it’s own description and set of choices. Each set of choices has an input (the character or string that the player types) a description (“look around the room again” or “talk to the penguin”) and a destination for that choice (one of the “rooms” in game data).

Now we need to rewrite the game loop to account for this new structure:

current_room = game_data["one-room house"]

player_input = ""
while player_input != "q":
    print "\n" + current_room["description"] + "\n"

    for choice in current_room["choices"]:
        print choice["input"] + ") " + choice["description"]
    print "q) quit game\n"

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

    if player_input == "q":
        print "Hope you had fun!"
    else:
        valid_choice = False

        for choice in current_room["choices"]:
            if player_input == choice["input"]:
                current_room = game_data[choice["destination"]]
                valid_choice = True

        if not valid_choice:
            print "I have no idea what you're talking about."

If you’ve gone through my python tutorials, there shouldn’t be anything new here. Basically we set the initial room, print its description, it’s choices and then check the player’s input against those available choices. If there’s a match, we go to that new destination.

Ok, that’s it for now! Again, you can see the latest version of the code at https://github.com/NerdcoreSteve/python-adventure

Learn You A Haskell

Learn You A Haskell is a great, free, online book for learning the purely-functional programming language, Haskell. In case you’ve been living under a rock, programming only in Java 7 and COBOL, you know functional programming is what all the cool kids are doing.

Personally, I’ve found Learn You A Haskell┬áto go just the right pace (not dumbed down and slow, but not terse) for learning this style of programming.

Making A Game In Python Part 2

Here’s the game so far (scroll to the right to see the rest of the text.):

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."

You can also see the game at github.com/NerdcoreSteve/python-adventure.

Ok, let’s get back to work. One problem is that we never asked the user for their name! Let’s fix that right now.

player_name = ''

player_name = raw_input("What's your name? ")

print ""

print "You're name is " + player_name + ". 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."

And here’s the other change I made:

        print "You say, \"Hello penguin.\"\n\n\"Hello " + player_name + ",\" replies the penguin."

All we do is ask for the player name just the same way we ask for other input.

Well this is all fun and good, but I want new things to happen and new choices to come up when I do stuff. For that I’m gonna need to do some pre-work. I want the description and choices to be part of a data structure. Then when I make choices I can load a new part of the data structure with new descriptions and choices.

player_name = ''

player_name = raw_input("What's your name? ")

game_data = {"one-room house" : {"description" : "You're name is " + player_name + ". 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.",
                                  "choices" : [{"input" : "t",
                                               "description" : "talk to the penguin"}]},
"penguin conversation" : {"description" : "You say, \"Hello penguin.\"\n\n\"Hello " + player_name + ",\"      replies the penguin."}}

print ""

current_room = game_data['one-room house']
choices = current_room['choices']

print current_room['description']

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

    choice = choices[0]['input']
    description = choices[0]['description']

    print choice + ") " + description
    print "q) quit game"

    print ""

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

    print ""

    if player_input == 't':
        print game_data['penguin conversation']['description']
    elif player_input == 'q':
        print "Hope you had fun!"
    else:
        print "I have no idea what you're talking about."

Ok, the content of the game is now in a data structure, we have two parts: one part describes the room, the other describes what happens when you talk to the penguin. But the data structure is incomplete! What are the choices you get after talking with the penguin?

Also, the while loop needs work. It should just be able to take the game data and use it without knowing about penguins or rooms or whatever. It should just read the data, output the room description and give you your choices. When you make a choice, the game should load up another part of the data structure and start again. It should do that until the end of the game.

But… um… it took me a bit to get to this point. I think we need to stop here…. At this ugly, ugly place in the code.

Write at you later! :)

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.

Follow

Get every new post delivered to your Inbox.

Join 209 other followers