Question

I'm writing a Tic-Tac-Toe program and I'm trying to use the method "playOn" from this class in a driver and I'm not sure how I'm suppose to use the public variables (X and O) I've already defined to use that method. It's suppose to be in a "singleton-like" design. Any help is appreciated.

public class TTTPlayer {
    public TTTPlayer X = new TTTPlayer('X');
    public TTTPlayer O = new TTTPlayer('O');
    private char symbol;
    private Random gen;
    private boolean playerTurn; // true for 'X', false for 'O'

    private TTTPlayer(char ch) {
        this.symbol = ch;
    }
    public void playOn(TTTBoard board) {
        int row = gen.nextInt(2);
        int col = gen.nextInt(2);
    if (playerTurn) {
        board.place(X, row, col);
        playerTurn = false;
    } else {
        board.place(O, row, col);
        playerTurn = true;
   }
}
Was it helpful?

Solution

I think all you're missing here are static modifiers.

Static members belong to the class, they live a kind of global existence (though they are not necessarily accessible globally). You can access them with a reference to the class, like out is a static member of the class System so hence System.out.

When you create a new object with new, it's a unique instance and that holds instance members. out is actually an object instance of PrintStream so when you say out.println, println is an instance method.

Some other languages let you declare functions and things in some kind of global namespace but Java doesn't have that, everything has to go in a class. So we have static members.

Here, X and O are static members like System.out but they are also instances of the enclosing class.

public class TTTPlayer {
    private char symbol;

    private TTTPlayer(char ch) {
        this.symbol = ch;
    }

    public static TTTPlayer X = new TTTPlayer('X');
    public static TTTPlayer O = new TTTPlayer('O');
    private static Random gen;
    private static boolean playerTurn; // true for 'X', false for 'O'

    public static void playOn(TTTBoard board) {
        int row = gen.nextInt(2);
        int col = gen.nextInt(2);
        if (playerTurn) {
            board.place(X, row, col);
            playerTurn = false;
        } else {
            board.place(O, row, col);
            playerTurn = true;
        }
    }
}

To play the turns, you'd call TTTPlayer.playOn. Likewise, X and O are accessed using the name of the class like TTTPlayer.X and TTTPlayer.O.

If you aren't comfortable with the distinction between instance and static (some people aren't), consider separating these two in to different classes. One that's just for the tokens and another with the static members that makes the moves.

OTHER TIPS

First of all, I agree with @Radiodef that X and O should be made static. This will solve some of your access issues.

Also, it seems to me that you have two variables that serve the same purpose:

private char symbol;

This holds an X or an O to indicate the player.

private boolean playerTurn;

The comment explicitly states that this also represents either X or O.

I think the symbol variable is more useful because it holds the exact letter to use when taking a turn. If you use this variable, you can simplify the playOn() method considerably by keeping in mind that you will have two TTTPlayer objects which each store their own symbol value.

Finally, you need to also check that a player doesn't try to move in a square that is already taken.

To have a singleton. You could make the constructor(s) private and use it in a private static field:

private static MySingleton = new MySingleton();

Then provide an accessor getMySingleton()

Also make the players private instead of public if you can ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top