2009 April 3 / jjddaavviiss@@ccaarrlleettoonn..eedduu

Tic Tac Toe

Carleton College CS 201, Spring 2009, Prof. Joshua R. Davis

The goal of this assignment is to practice writing Python code — in particular, writing classes and subclasses and using a graphics library. By the end, you will have a functioning two-player Tic Tac Toe game. If you dislike Tic Tac Toe, then you are welcome to implement another, comparable board game, such as Connect Four or Reversi. Clear your idea with me or Eric before starting on it, though.

You are expected to complete this assignment with one partner. It is due Monday at 5:00 PM.

0. Get Ready

Open a Terminal window and navigate to your working folder (where you stored the files above). You might find these Unix commands helpful: Open the TextWrangler text editor, too.

1. Try A Little Bopa

Read the "Getting Started" section of the Bopa manual. Definitely try out the starter code for yourself. Also skim the next two sections of the manual, to get an idea of which shapes are available and what you can do with them.

By default, you can drag any Bopa shape around with your mouse, as if it were a physical object. How does this work? The Bopa window waits for the user to use the mouse (or keyboard). When the user drags the mouse pointer on a shape, the window tells the shape to translate() in whatever direction the mouse moved.

This is the basic idea of your board game program: Make a board and some pieces, and let the users drag the pieces around.

2. Design Your Window And Board

On paper, sketch what the window for your game will look like. Somewhere in that window is a board of some kind. Make your sketch as detailed as possible; for instance, figure out how many pixels long each part of your board is. You'll need to know this when you write code to draw the board.

In a new file called game.py, write a new class called Board. It should be a subclass of Overlay or of one of Overlay's subclasses. Your code for Board should accomplish two things:

After you write your board code, test it out. How? At the bottom of game.py, write a little code that makes a window, creates a Board, and starts the window running. Then run game.py to make sure everything works so far. Checking your program periodically as you write it, rather than once after you've written everything, can save you a lot of time! (And I don't use exclamation points often.)

Now is a good time to document your Board class. Make sure there are comments for any large or non-obvious chunks of code. Also make sure that your name(s) are typed in comments at the top of the file, along with the date.

3. Design Your Pieces

Now that you have a board, you need some pieces. For Tic Tac Toe these are Xs and Os. Draw them on paper, in as much detail as possible, including the length of each part of each piece, in pixels.

Write classes for your pieces. For my version of Tic Tac Toe I used an XPiece class and an OPiece class. In each, all I really did was override __init__() to set up my desired color and size and attach child shapes.

Test your piece class(es).

Write documentation for your piece class(es).

4. Write The Game Logic

Your program is required to post a message of some kind to the Bopa window when the game is finished. This means that you need to keep track of the state of the game somehow, test the state of the game after each move, and display a message if one player or the other has won (or if the game has ended in a draw). Depending on how you decide to do this, you may have to go back and alter your board and piece classes.

To help you out, let's talk about the logic of Tic Tac Toe. There is a 3 x 3 board. When a user moves a piece, your program must figure out which square of the board the piece was dropped on, record the fact that the piece now occupies that square, and check the board to see whether that player now occupies an entire row, column, or diagonal. If so, she wins; if not, then either all the squares are occupied (draw) or some are still unoccupied (play on).

Let's expand on that first step — figuring out which square the piece was dropped on. When you think about it, you don't really care how the user drags the piece around, or how long it takes; you just want to know the final resting place of the piece. This is exactly what Window's setEndOverlayDragHandler() method gives you. It's covered in the "User Interface" section of the Bopa manual. Here's a little example of how you might use it. Define this handler function somewhere in your program.

def myendhandler(xyStarting, xyPrevious, xyFinal, names):
    print 'piece dropped at', xyFinal[0], xyFinal[1]
Then, in the main body of your program (between creating the window and running the window's loop), attach the handler function to the window like this:
mywindow.setEndOverlayDragHandler(myhandler)
Now, whenever the user drags a piece, that piece's final resting place will be printed out. Of course, you don't want your Tic Tac Toe program to print out the final resting place; you want it to figure out the new state of the game, and whether the game is finished or not. That's your job.

5. Polish

This assignment is a little open-ended. You can design your program however you like, as long as it is a recognizable version of the game you were approved to make, that behaves correctly and displays a useful message in the Bopa window when the game is finished.

However, as you can see from the grading criteria in the next section, one quarter of the points are reserved for creativity and polish. How might you earn these points?

In a comment near the top of the file, explain what kind of creativity or polishing you've performed that deserves points. If you don't make this explanation/declaration, then you will not be considered for these points.

6. Hand In Your Work

Your file game.py will be graded using these criteria:

Each pair of students should submit one copy of game.py with both of their names on it. There are two ways to submit it.