Around 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!
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.
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 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.
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! 🙂