A Beginner Tic-Tac-Toe Class for Java

Tic Tac ToeAround this time each year we mentors on Dream.In.Code see a bunch of students and beginners, attempting to do there final programming projects, come on the boards asking for help with coding problems. Some even come on asking for ideas to help them out and a large majority want help with simple games they can do like connect four, “the snake game” or even Tic-Tac-Toe. Then each year we throw out some code to help them out and hope they come back to thank us later after the semester ends. So to help out this year I thought I would address a few students who were asking about the game of Tic-Tac-Toe and some code to get them started. Enjoy!

A Java Class for Tic-Tac-Toe

Each beginner who comes in and asks about this game tends to have a slight variation on the theme. Some need just a console app, some need to add a Graphical User Interface (GUI) and some need to add additional functionality (different characters, play online, more squares etc). To address all these variations I thought the best approach would be a simple Java Class where the programmer can take the class, tack on a GUI interface that calls the class’ methods or integrate it directly into a console app. Heck perhaps to even part it out for the various functions… I don’t mind.

The class code below is divided into three sections.

  • The first part is the board functions. These include initializing the board (which can be called to also reset the board state), printing a representation of the board state (so you can see what the game looks like at that point in time) and a check to see if the board is full (for detecting a draw scenario).
  • The second part is the win conditions. Here we have a simple function which will tell us if there is a win or not on the board. This function will call other functions to check the rows, the columns and the diagonals for a win condition. Each of these functions call a key function called “checkRowCol()” which is given the three values of a row/col and yes even a diagonal to see if they are a match.
  • The last part is the player functions. These control which player mark is active and where a user can place their mark on the board.

The Java Code

Below is the code, in its entirety, for you do do what you wish with it. It is in the public domain and can be used or modified as you see fit. But a reminder to students, do keep in mind that plagiarism can be frowned upon at school so learn what you can from this and try and make your own version. I would hate to see you guys get kicked out of class and blame me.

public class TicTacToe {

    private char[][] board; 
    private char currentPlayerMark;
			
    public TicTacToe() {
        board = new char[3][3];
        currentPlayerMark = 'x';
        initializeBoard();
    }
	
	
    // Set/Reset the board back to all empty values.
    public void initializeBoard() {
		
        // Loop through rows
        for (int i = 0; i < 3; i++) {
			
            // Loop through columns
            for (int j = 0; j < 3; j++) {
                board[i][j] = '-';
            }
        }
    }
	
	
    // Print the current board (may be replaced by GUI implementation later)
    public void printBoard() {
        System.out.println("-------------");
		
        for (int i = 0; i < 3; i++) {
            System.out.print("| ");
            for (int j = 0; j < 3; j++) {
                System.out.print(board[i][j] + " | ");
            }
            System.out.println();
            System.out.println("-------------");
        }
    }
	
	
    // Loop through all cells of the board and if one is found to be empty (contains char '-') then return false.
    // Otherwise the board is full.
    public boolean isBoardFull() {
        boolean isFull = true;
		
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == '-') {
                    isFull = false;
                }
            }
        }
		
        return isFull;
    }
	
	
    // Returns true if there is a win, false otherwise.
    // This calls our other win check functions to check the entire board.
    public boolean checkForWin() {
        return (checkRowsForWin() || checkColumnsForWin() || checkDiagonalsForWin());
    }
	
	
    // Loop through rows and see if any are winners.
    private boolean checkRowsForWin() {
        for (int i = 0; i < 3; i++) {
            if (checkRowCol(board[i][0], board[i][1], board[i][2]) == true) {
                return true;
            }
        }
        return false;
    }
	
	
    // Loop through columns and see if any are winners.
    private boolean checkColumnsForWin() {
        for (int i = 0; i < 3; i++) {
            if (checkRowCol(board[0][i], board[1][i], board[2][i]) == true) {
                return true;
            }
        }
        return false;
    }
	
	
    // Check the two diagonals to see if either is a win. Return true if either wins.
    private boolean checkDiagonalsForWin() {
        return ((checkRowCol(board[0][0], board[1][1], board[2][2]) == true) || (checkRowCol(board[0][2], board[1][1], board[2][0]) == true));
    }
	
	
    // Check to see if all three values are the same (and not empty) indicating a win.
    private boolean checkRowCol(char c1, char c2, char c3) {
        return ((c1 != '-') && (c1 == c2) && (c2 == c3));
    }
	
	
    // Change player marks back and forth.
    public void changePlayer() {
        if (currentPlayerMark == 'x') {
            currentPlayerMark = 'o';
        }
        else {
            currentPlayerMark = 'x';
        }
    }
	
	
    // Places a mark at the cell specified by row and col with the mark of the current player.
    public boolean placeMark(int row, int col) {
		
        // Make sure that row and column are in bounds of the board.
        if ((row >= 0) && (row < 3)) {
            if ((col >= 0) && (col < 3)) {
                if (board[row][col] == '-') {
                    board[row][col] = currentPlayerMark;
                    return true;
                }
            }
        }
		
        return false;
    }
}

What I love about this style of game, and this class shown above, is that it has very defined and easily written tasks. For example, check a row, check a column, change the player’s mark, is the board full etc. Because of this the code can be seen as being very modular and each method is short and easy to read. If you have trouble figuring out all the parts to it, just focus in on one method at a time and dissect it line by line.

Using The Class

Using this class is straight forward and very versatile. As you can see, many of the methods are declared as public and by calling them from a GUI or a console app you can control the game. Just creating an instance of the class will create the board and initialize it. Any time you want to restart the board, you can call the initialize method again. Below is an example of how you might create a pattern for the game mechanics…

// Create game and initialize it.
// First player will be 'x'
TicTacToe game = new TicTacToe();

// Player 'x' places a mark in the top right corner row 0, column 2
// These values are based on a zero index array, so you may need to simply take in a row 1 and subtract 1 from it if you want that.
game.placeMark(0,2);

// Lets print the board
game.printBoard();

// Did we have a winner?
if (game.checkForWin()) {
   System.out.println("We have a winner! Congrats!");
   System.exit(0);
}
else if (game.isBoardFull()) {
   System.out.println("Appears we have a draw!");
   System.exit(0);
}

// No winner or draw, switch players to 'o'
game.changePlayer();

// Repeat steps again for placing mark and checking game status...

As you can see from the code above, we can do many things with this class and implement any step in any order. We created a game, placed a mark for the player, checked win conditions, checked for a draw and changed player. If I have done my job right, you should be able to look at this class and say to yourself “Oh I could just tweak this and get another effect.” You should be able to take this code straight into a GUI setup where starting your JFrame constructor would create and initialize this class and clicking a square would trigger the placeMark() method. A reset button might trigger the initalizeBoard() method and you could either use the printBoard() function or write your own to display the board in your GUI.

Conclusion

I hope that this code has helped all those students out there looking to build a simple game program. Or if you are just a hobbyist or beginner to Java and want to see how things fit together in a simple game scenario, a little class like this should do the trick. If you are looking for more fun little projects like this and want to expand your mind, your skills in Java, or any other programming language, I encourage you to check out our ebook titled “The Programmers Idea Book – 200 Software Project Ideas And Tips To Developing Them” which is available on this site.

Thanks for reading and keep on coding! 🙂

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 18 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.
  • Mark Wilhelm

    Thanks for the article. Just two notes. In your example usage, you call “game.isWinner()” which is not declared. Also, you call “game.changePlayer()” which you declared as private. Two simple fixes, but thought I’d point them out.

    Thanks again for the article.

    • Thanks, you were right. I must have changed the name at the last minute. Not sure how the private/public thing got through, but I have since made the corrections. 🙂

  • Derri Leahy

    Thanks for the code but one minor mistake on row 69 in the class.

    if (checkRowCol(board[i][0], board[i][1], board[i][1]) == true)

    The second 1 should be a 2. Thanks again though

  • pari007

    Liked the clarity and simplification of the code.

    you use the same data-structure if the game board is 2^31 by 2^31? Or is there a better data structure to be able to check the player wins? Thanks

  • Vikrant Gupta

    How will i run this class?
    I got an error saying “main method not found” or javaFx must extend javaFx.application. What should i do?

    • Saket Khandelwal

      You would first need to create a class and put the main function in it, then put in the code. “do the public static void main(String[] args)”

  • gerald

    hey thanks. so which platform do i write the code and the see it become a game

  • gerald

    which android platform is best use.

  • Anri Delon

    I don’t get the “checkRowCol” thingy, its not initialized anywhere but the article does say that “Below is the code, in its entirety” so I am really confused, I tried copy pasting the code and well same thing happened “checkRowCol” needs initialization. Can someone please help me understand this part ?