
While learning Golang, I wanted to challenge myself with a fun, beginner-friendly project. So I decided to build a simple Tic-Tac-Toe game that runs in the terminal.
This project helped me understand how to structure a small CLI game, handle user input, and implement basic game logic using Go. In this article, I’ll walk you through how I built it and what’s happening behind the scenes.
Why Tic-Tac-Toe?
I chose Tic-Tac-Toe because it’s a classic game that’s:
- Easy to understand
- Small in scope (perfect for a beginner)
- Focused more on logic than graphics
Plus, it forces you to think in terms of data structures and loops—great for learning Go.
The Structure
The whole project lives in a single file: main.go. No frameworks, no external dependencies—just plain Go.
Representing the Game Board
I used a 3×3 array to represent the board. Each cell is initialized with a number from 1 to 9 to make it easier for players to choose a position.
var board = [3][3]string{
{"_", "_", "_"},
{"_", "_", "_"},
{"_", "_", "_"},
}
This board gets updated as players make their moves. Each number is replaced with either "X" or "O".
The Game Loop
The game runs inside a loop that alternates between two players. On each turn, the program:
- Displays the board
- Asks the current player to choose a number (1-9)
- Checks if the move is valid
- Updates the board
- Checks for a winner or a draw
for {
displayBoard()
getPlayerInput()
updateBoard()
if checkWin() || checkDraw() {
break
}
switchPlayer()
}
Getting Player Input
I read the user’s move using fmt.Scanln() and then convert it into row/column coordinates to access the board.
fmt.Print("Enter your move (1-9): ")
fmt.Scanln(&move)
I also made sure to check if the chosen cell was already taken—if so, the player has to enter another number.
Win and Draw Conditions
After each move, I check if there’s a win. This part was fun to implement! I check all possible winning combinations (rows, columns, and diagonals).
if board[0][0] == board[0][1] && board[0][1] == board[0][2] {
// Player wins
}
If there’s no winner and the board is full, then it’s a draw.
Switching Players
After a move, I simply toggle between “X” and “O”:
if currentPlayer == "X" {
currentPlayer = "O"
} else {
currentPlayer = "X"
}
Simple and clean.
Output Example
X | O | X
-----------
_ | O | _
-----------
_ | 8 | _
Player X wins!
What I Learned
This project helped me understand:
- How to manage 2D arrays in Go
- How to structure simple loops and conditions
- How to build something playable with minimal code
It was a fun little project, and I’d recommend it to anyone starting out with Go.
You can try It Yourself
You can check out the source code on GitHub:
github.com/amburegul/golang-simple-tictoe
If you want to run it:
git clone https://github.com/amburegul/golang-simple-tictoe
cd golang-simple-tictoe
go run main.go
So, What’s Next?
I might expand this project in the future by:
- Adding a simple AI to play against
- Making it playable over the network
- Creating a web-based version using Go’s web packages
But for now, I’m just happy I built a working game from scratch!
Thanks for reading—hope this inspires you to build something cool with Go too!
And please comment if you have any question or any better idea so we can implement this game together.