Monday, January 14, 2013

Python Training "Text Movies"

I have cobbled together a script that creates training "text movies" that use a instructions text file and some javascript.

The javascript creates a simlated video of an interactive interpreter session along with comments and instructions:

http://lightbird.net/larks/tmovies.html

Friday, January 11, 2013

Versi Tutorial

A new tutorial was added to Lark's Python Guide: Versi Tutorial -- a clone of the Reversi game.

Some of the highlights:

A rather neat approach is used to capture enemy pieces -- a 'ray' is cast from the starting location (ray creates the list of all pieces in line, horizontal, vertical or diagonal, to the end of board), then I use the itertools.groupby() function to group tiles into player's, enemy's and blanks; finally a custom nextgroup() function is used two times to get two next groups.

The nextgroup(groupby_iterator, default=None) returns a convenient wrapper object with key and group attributes; or a default value if there is no next group.

This makes it very easy to create the piece-capture logic: to be successful, first group needs to be enemy tiles and the second, player's; on success, first group returned to be captured.

Turns handling is a little tricky in this game, and, I think, nicely handled here: a player may have no turns available, then the enemy takes turns until the player can make a move, the game only ends when either player can make no turn (which may happen when some blank tiles are still left on the board).

The full list of tutorials is here:  Lark's Guide.

Thursday, January 10, 2013

Betelgeuse Tutorial

I've just uploaded a new tutorial: this time it's a simple space conquest strategy game -- Betelgeuse Tutorial.

One of the things this tutorial illustrates is the use of a base class to allow comparison between various objects that belong to players.

It also provides an example of how to implement a game with each player having arbitrary number of moves per turn (sometimes you have to skip a few turns to let your space army build up, other times you may want to send multiple fleets from different stars or even from the same star system.)

Stars and fleets have a neat, consistent interface which allows convenient handling of both.

As with most other games in the guide, you can configure it to have ai vs ai play, ai vs player, or player vs player.


Wednesday, January 9, 2013

Mines Tutorial

I've just added the Mines (clone of Minesweeper game) Tutorial: Mines

The main url with all tutorials is here: Lark's Tongue Guide to Python

It's a neat classic game and is quite fun to play, even though the interface is primitive.

The game contains a nice example of floodfill algorithm which is used to mark empty tiles (tiles with no neighbouring mines -- with a twist: tiles that border empty tiles also have to be revealed, but their neighbours stay hidden.

Tuesday, January 8, 2013

Python Lists Part II


This post continues where I left off in my Introduction to Python Lists. This time I'm going to
look at some examples of use of lists in the games I've written for my series of tutorials.

TicTacToe uses lists to store winning lines (which, in turn, contain lists of board locations). A
list is a good type of a collection to use in this case because when I use winlines, I iterate
over the entire list and check if a winline is completed by the player. That's what lists are
really good for: going over each item in a sequence.

TicTacToe Tutorial


RockPaperScissors uses a list to keep track of player scores: it's a list of two integers
(initially, both are 0), corresponding to players #1 and #2. That's a good example of the second
thing lists are really good at -- getting and modifying items by index.

RockPaperScissors Tutorial


Flashcards script uses lists to store a master copy of cards and a temporary randomized copy which
has the card removed from it after it's shown. This illustrates another useful property of lists:
they can be randomized using the built-in random.shuffle() function (I'm using the slightly
modified utils.shuffled() function in my example). Lists can also be "exhaused" using the pop()
method which returns a list item and removes it from the list at the same time (last item by
default, but you can also provide any other valid index as an argument).

Flashcards Tutorial


In the Words game, I'm using a list to store indexes of hidden letters for each word. This list is
used in a few different ways:

- when displaying a word, each letter's index is checked against the list using 'in' operator
- when revealing a random letter, it is picked using random.choice() function
- when revealing a letter, it's index is removed using remove() method
- when generating the list, indexes are added using the append() method, which is probably the
  first list method you learn when reading about lists in a Python tutorial

Words Tutorial

Thursday, January 3, 2013

I'm glad to announce the addition of a new chapter, covering the Tictactoe game, to my series of Python tutorials: Tictactoe Tutorial.

The main page with a listing of all tutorials is located here: http://lightbird.net/larks/.

Unlike the previous chapters, this one goes into much greater detail and (I hope) will be helpful to readers who are new to Python and Programming.

I plan to make an expanded version of a few other chapters in the near future.

I'm still working out the kinks out of the format of pseudo-code I use in this chapter; once I go through a few chapters I'm sure it will change, perhaps dramatically!

I'll need to look at more examples of pseudo-code people use in books and guides and pick & choose the best, most expressive bits and pieces.

Saturday, December 22, 2012

Python Lists part I

A list is one of the most important data structures in Python. In this (and subsequent) posts I will go over the methods, tips, and examples of using lists in your programs.

I will be using Python 3.3 but most of the examples should work with Python 2.7.

There are already some excellent tutorials that cover usage of lists:

http://docs.python.org/3.3/tutorial/datastructures.html#more-on-lists

and

http://effbot.org/zone/python-list.htm

In this series of posts my goal is to cover some helpful utility functions for list handling, go into more detail on list sorting and give some examples of list use in my game tutorials:

http://lightbird.net/larks/

Customizing lists

Lists are a kind of a default go-to container structure in Python: if you’re not sure what to use, it’s always a safe choice to start with and to change later as needed.

It’s very easy to make a list-like container to add custom functionality. If you only need to iterate over the list, you need to add the special __iter__() method:

# (star, brightness)
starlst = [["Deneb", 1.25], ["Aldebaran", 0.85], ["Betelgeuse", 0.42], ["Fomalhaut", 1.16]]

class Stars(object):
    def __init__(self, stars) : self.stars = stars
    def __iter__(self)        : return iter(self.stars)

stars = Stars(starlst)
for star in stars:
    print(star)

You can also use the ‘in’ test:

print(starlst[0] in stars)

Once you have your custom container, it’s easy to add convenience methods:

class Stars(object):
    def __init__(self, stars) : self.stars = stars
    def __iter__(self)        : return iter(self.stars)

    def names(self):
        return [s[0] for s in self.stars]

    def brightness(self):
        return [s[1] for s in self.stars]

    def bright_stars(self):
        return [s[0] for s in self.stars if s[1] < 1]

print(stars.names())
print(stars.bright_stars())

The way visual brightness is measured is that the lower the value.

Of course, you might also want to make a Star class to wrap each star with name and brightness attributes, but this is a good example of making a wrapper around a list of tuples which may be more than enough in many cases.

Now, if I need to access items by index, I’ll just need to add one more special method – __getitem__() (naturally, if I did not need to iterate but ONLY needed access-by-index, I could add this special method alone – my point is that it’s VERY easy to add these special methods as you experiment with your code as you go and worry about the rest later):

def __getitem__(self, i): return self.stars[i]

... letting me do print(stars[0]):

["Deneb", 1.25]

Often, you’ll want to accompany your __getitem__ with a __setitem__:

def __setitem__(self, i, val): self.stars[i] = val

Now I can change the star’s brightness (ok not the real star’s but the one in my program):

i, brightness = input("Enter star # and brightness: ").split()
i = int(i)
stars[i][1] = float(brightness)
print(stars[i])

If I enter ‘1 0.9’, I get the following:

['Aldebaran', 0.9]

In this manner, I can get little bits and pieces of the full list’s functionality as I need them. If I wanted to have a full set of list’s methods, I need to inherit from collections.MutableSequence and override the following special methods:

class Stars(collections.MutableSequence):
    def __init__(self, stars)     : self.stars = stars
    def __len__(self)             : return len(self.stars)
    def __getitem__(self, i)      : return self.stars[i]
    def __delitem__(self, i)      : del self.stars[i]
    def __setitem__(self, i, val) : self.stars[i] = val
    def __str__(self)             : return str(self.stars)

    def insert(self, i, val)      : self.stars.insert(i, val)

Now you’ll be able to use methods like append, count, extend, pop, reverse, sort, et cetera.

My guide to Python has many examples of usage of lists, built-in and customized, used in many simple games along with helpful explanations:

http://lightbird.net/larks/

In my next post I’ll go over some of the uses of lists in my guide’s games.