This tutorial was originally written when I was first learning Java. I’ve kept the original code below as a time capsule of my learning journey. If you want to see how I would write this today, with proper input validation and error handling, check out the retrospective at the bottom.
- Arrays and 2D array manipulation
- Boolean logic and conditionals
- Functions and method design
- Loop structures and game flow
- User input validation
- Game state management
| Difficulty | Beginner |
| Language | Java |
| Read time | 11 min |
| Originally published | Medium, May 6, 2021 |
Prerequisites
- Java JDK 11 or higher — Download from Oracle or use OpenJDK
- A text editor or IDE — VS Code with Java Extension Pack or IntelliJ IDEA Community Edition
- Basic Java knowledge — comfortable with variables, data types, and how to compile and run a Java program
Building the game
Build the board
The first step is to create the board. We’ll use a 2D character array filled with dashes, vertical bars, and spaces to create the visual layout.The game positions map to array indices as follows:
TicTacToe.java
| Position | Array index |
|---|---|
| Top row (1, 2, 3) | [0][0], [0][2], [0][4] |
| Middle row (4, 5, 6) | [1][0], [1][2], [1][4] |
| Bottom row (7, 8, 9) | [2][0], [2][2], [2][4] |
The vertical bars exist for visual formatting only. They occupy even-indexed columns (
[*][1] and [*][3]) but are never used in game logic.Place pieces
Next, add a method to update the board when a player makes a move.Test it by calling
- Player is represented by the character
Xand the number1 - Computer is represented by the character
Oand the number2
TicTacToe.java
updateBoard directly from main:Get player input
Add a
Scanner to read input from the keyboard, then call it from a playerMove method.TicTacToe.java
We create a
static Scanner because player input is needed across multiple methods. One shared instance prevents memory issues and simplifies the code structure.Validate moves
Before placing a piece, check that the chosen position is within range and not already occupied.Valid moves must:
- Be between 1 and 9
- Target a position containing
_or' '(empty squares only)
TicTacToe.java
The bottom row checks for
' ' (space) rather than '_' because the bottom row uses spaces as its empty-cell character.Simulate the computer
The computer picks a random position between 1 and 9, re-rolling until it finds an empty square.
TicTacToe.java
rand.nextInt(9) returns a number from 0 to 8. Adding 1 shifts the range to 1–9, which maps to our board positions.Detect a winner
There are 8 possible winning combinations: 3 horizontal, 3 vertical, and 2 diagonal. Check all of them after every move.
TicTacToe.java
Retrospective
This tutorial reached 75,000+ developers. That’s the success. What follows is how I’d write the same code today. Good documentation meets people where they are. A tutorial for beginners should prioritize clarity over cleverness. The original code isn’t wrong — it’s calibrated to its audience. These are three things I’d do differently now that I have more experience.1. Separation of concerns
1. Separation of concerns
The original code mixes game data (
X and O) with visual formatting (pipes | and underscores _) in the same array. This makes the win-detection logic harder to read and reason about.Today, I’d keep the data model clean and handle visuals separately:2. Input robustness
2. Input robustness
The original
input.nextInt() crashes with an uncaught exception if a user types a letter. Today, I’d wrap all input in a loop that handles NumberFormatException and supports basic help commands:3. Algorithmic efficiency
3. Algorithmic efficiency
The switch statements work, but each position maps to a row and column through a simple formula. You can replace 18 nearly-identical cases with two lines of math:A beginner can read
case 5: gameBoard[1][2] and immediately understand it. The compact version requires working backwards from the math. Both are correct. The original was the right choice for a beginner audience.Original article
Read the full tutorial as originally published on Medium.
On Good Tutorials
Why this tutorial was discussed in a broader study on tutorial quality.
