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.