Tic-Tac-Toe Game with Atmega 256 MicroController
In this blog, I’ll walk you through how I built a Tic-Tac-Toe game using an AVR microcontroller, a 4x3 keypad, and a grid of LEDs. This project combines the basics of embedded programming, game logic, and user interaction to create a fun and interactive game.
1. Overview of the Project
The goal of this project was to create a Tic-Tac-Toe game where players could input their moves using a keypad and see the results displayed on an LED grid. Each move lights up an LED in red or green, depending on the player's turn. The game identifies the winner and celebrates with an animation.
2. Hardware Setup
For this project, I used:
- ATmega microcontroller (running at 8 MHz)
- 4x3 Keypad for player input
- 3x3 LED grid to display the game
- A few resistors and wires for connections
3. Software Workflow
Step 1: Setting Up the Keypad
The keypad is the primary input device. Each button corresponds to a grid cell (1-9). I used the PORTK
and PINK
registers to scan the keypad rows and columns.
void initKeypad() {
DDRK = 0x0F; // Lower nibble output, upper nibble input
PORTK |= 0x70; // Enable pull-ups for inputs
}
The keypad()
function polls for key presses and debounces inputs to ensure accurate readings.
Step 2: Initializing the LED Grid
The grid is controlled using multiple ports: PORTA
, PORTC
, PORTD
, and PORTG
. Each LED represents a cell in the grid, and I assigned specific bits to control them.
void initGrid() {
DDRA = 0xFF; // Set PORTA as output
// Similar setup for other ports
}
Step 3: Game Logic
The core of the game is managing the players' turns and checking for a winner. The grid is represented as a 3x3
array, and each player alternates their turn by pressing a key to light up the respective cell.
void play(int index) {
int row = (index - 1) / 3;
int col = (index - 1) % 3;
if (grid[row][col] == 0) { // If cell is empty
grid[row][col] = turn; // Mark the cell
controlLed(row, col, turn, ON);
turn = (turn == RED) ? GREEN : RED;
}
}
Step 4: Checking for a Winner
Once a move is made, the checkWinner()
function evaluates rows, columns, and diagonals for three matching symbols.
int checkWinner() {
for (int i = 0; i < 3; i++) {
if (grid[i][0] == grid[i][1] && grid[i][1] == grid[i][2])
return grid[i][0];
}
// Similar checks for columns and diagonals
return 0;
}
Step 5: Winning Animation
If a player wins, a simple animation flashes the winning LEDs.
void animation(int winner) {
for (int i = 0; i < 3; i++) {
controlLed(0, i, winner, ON);
_delay_ms(300);
}
}
Explorer the world of cyber security. Read some cool articles on System exploitation, Web application hacking, exploit development, malwara analysis, Cryptography etc.