• No results found

Writing New Classes - Tic Tac Toe

In document Java (Page 140-146)

This section shows how new classes can be designed and written. This will be done using the example of the game Noughts and Crosses, also known as Tic Tac Toe. We will write this as a character-based game, then in the next section adapt it to a GUI.

Designing new classes

We first have to identify what classes would be involved in the game. That is, we must identify the things in the game. One way to do this is to look for the nouns in a description of the context. This is how wiki describes it:

Tic-tac-toe, also rendered wick wack woe (in some Asian countries), or noughts and

crosses/Xs and Os as it is known in the UK, Australia and New Zealand, is a pencil-and-paper game for two players, X and O, who take turns marking the spaces in a 3×3 grid. The X player usually goes first. The player who succeeds in placing three respective marks in a horizontal, vertical, or diagonal row wins the game.

In our version, one player will be the user, and the computer will be the other player. Here is a set of classes:

Game. There would only be one instance of this class - just one game object. This is an example of a singleton class. The Game class would need to let the two players alternate turns, check if someone had won after each go, and end the game if they had. This class could contain the main method, since we start by starting the game.

Board. This would need to have a 3X3 grid, and be able to show it. Again a singleton.

Human player. This singleton would represent the human player. It would have to provide for a human turn, where the board was shown and the user allowed to chose where to go.

Computer player. This singleton represents the human's opponent. The key method would be to decide where to go.

Projects and packages

An application like this, containing several classes, is a project. The source code (the class definitions) is organised into one or more packages.

In this case our project could be called ttt, for tic tac toe, and it needs just one package, also called ttt. We might have done this differently - say one package for the visual content, and another for the game logic. But this is a pretty simple project so we do not.

The class definitions are now listed. Note they were not written like this and then tested. They were written small sections at a time, and tested after each small step. This is the end result:

package ttt;

public class Game { // data fields

Then the board. It needs to be able to tell if someone has won, and it does this by brute force. There are only 8 winning configurations - three rows, three columns and two diagonals - and it simply tests them all.

package ttt;

// return true if someone's won, otherwise return false boolean checkWin(char c) {

The human player:

package ttt;

import java.util.Scanner;

class Human {

private Scanner scanner=new Scanner(System.in);

private Board board;

The computer is not too bright. It chooses cells at random until it finds one which is empty, and goes there.

Objects in the application

This shows the four main objects which exist when this application is running. Execution starts at main, and this constructs the game object. That also constructs the human, computer and board objects.

The arrows show which objects contain references to others. The game has references to the human and computer objects, so that it can tell them to do their go methods. It also has a reference to the board object, so that it can tell it to do its display and checkwin methods.

The human and computer objects also have references to the board. This is possible because that reference was passed to them in their constructors. They need it so that their go methods can use its get method to find out what is on the board.

Access levels - encapsulation

Recall that encapsulation means sealing objects as much as possible to prevent their corruption by bugs. This application uses 3 access modifiers

public - can be accessed from anywhere.

no keyword - access restricted to the package.

private - accessible only from that class.

These can be applied to classes or class members. Access levels are chosen here as follows

Game - the class is public. This is because it contains main, which is itself public. The runtime system must have access to this to start everything off. All other members of game, data fields and

methods, are private. This is the 'best' - members should be private unless there is a reason why they cannot be.

Board - the class has no access keyword, so access is restricted to the package. There is no reason why wider access is needed. The same is true of the methods - they are needed to be accessed from other classes in the package. But the data member, the two D array, is private. But we have get and set methods which prvide access through them. The set method checks that the row and columns are possible, and that the character being set if either X or O.

Human - the class, constructor and go method have no keyword, so are visible to the package, as needed. The data fields, the scanner and the reference to the board, are private, since that is enough. The computer object is similar.

Exercise

Try this application out.

Make sure you can understand every line of it.

The computer is dumb - it always loses unless you try hard to let it win. Devise and implement a better 'go' algorithm for the computer. This is not easy.

In document Java (Page 140-146)