Program 5

Home Windows C++ 241 C++ 242 Contact Info Contents

Program 5 - February 5

Up

Designing with Functions: Tic-Tac-Toe

This assignment is the first of several that will deal with that weighty issue of software design: how best to organize a tic-tac-toe program. This first iteration of the program is very simple. You are only to create a program that allows two people to play tic-tac-toe. There are no computer-generated moves involved. Later we will add use of arrays, structures and other language features and even allow the computer to play.

Rules of the Game

Just so we are all get started on the right foot, here is how to play the game. A playing board is drawn that consists of nine squares organized in three rows and three columns. The board shown below has numbers added so we can easily talk about (and enter) the moves. The first player always uses X as a marker and the second player uses O. Each player can mark any empty square. In the illustration, the first player has marked two squares and the second has marked one square. 

The first player to get three of his own marks in a row - horizontally, vertically or diagonally - wins the game. If nobody wins, and there are no empty squares, the game is a draw. (It's also possible to call a draw if you can see that nobody can possibly win.)

Your assignment...

Design a program to let two people play tic-tac-toe. The program should get the names of the player who will go first and of the one who goes second and ask each of them to move in turn. Moves should be input as numbers from 1 to 9. You should draw the board at the start and after each move. Your board should show the moves made so far and the numbering of the squares. Since we are writing console apps, you will have to use characters to show the board.

You must check each move to make sure the square is empty, and allow the user to make a different move if it is not. After each move, you should check to see if the player has just won and, if so, announce the winner. You should also check to see if the game is a draw and announce that if it is the case. Allow the players to play multiple games if they like.

What you cannot use...

Usually, it's good to use advanced features before they are covered... but not this time. You must program this assignment using only the features covered in the first four chapters. That means no structures, arrays or classes. Even if you know a better way to do the assignment, please suffer with the rest of us. Subsequent assignments will allow you to expand this program using more advanced features.

What you must use...

Functions! After all, that's what the chapter is about. You should begin designing your program by thinking about all the components needed. Think about how to decompose the problem into a set of functions - both void and value-returning - that allow you to carry it out. You may (and should) use global variables to keep track of the status of the game.

One possible approach...

You can do this in any way you like - within the constraints I've given. Here's one way to do it that will get you started thinking about the problem.

Since you aren't allowed to use arrays or structures, set up nine integer variables to keep track of things. You can call them something like s1, s2, etc.

Because the user enters numbers, but you have to translate those numbers to variable names, you will have to use functions with switch or if statements to do it. At a minimum you'll need something for WhatsOnSquare(int num) and MoveToSquare(int num). Example:

    int WhatsOnSquare(int num)
    {
        if (num == 1) return s1;
        else if (num == 2) return s2;
        // and on and on.... until
        else return -1; // User typed a bad number
    }

    void MoveToSquare(int num, int mark)
    {
        // You figure it out
    }

One trick is to set the variables to zero for an empty square, 1 for an X and 10 for an O. That way, if all the squares in a row add up to 3, X wins. If they all add up to 30, O wins.

Use lots of if statements to see if the player has just won. For example

    bool DidXWin()
    {
        if ( s1 + s2 + s3 == 3)
            return true;
        // seven more if statements go here

        // Must not have
        return false;
    }

You'll have to do the same for DidOWin(). As you can see, not being able to use arrays or structures makes us type a lot but the code itself is very simple.

This organization of this program, on the other hand, is fairly complex. You should design and develop it in a logical order rather than trying to do it all at once. Here is a suggested order you might consider using:

  1. Design the main program which gets the users' names and calls your PlayGame program.

  2. Design and perfect your output routine so that you can see the board.

  3. Perfect your move input without worrying about who won. For testing, you can just stop when zero is entered.

  4. Add winner-detection and draw-detection.

In all of this, look for opportunities to encapsulate some little bit of functionality in a function. It will make it easier for you to understand what's happening in your own program. Even trivial functions help in this way.

Think about this program during the week. On Wednesday, January 31 I'll give a few more hints and allow class time to start working on it.

Up

Home Windows C++ 241 C++ 242 Contact Info Contents

Copyright © 2000  Charlie Poole. All rights reserved.
Revised: July 15, 2002 - cpoole@ctc.edu