#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include <cstdio>
#include <cstdlib>
#include <thread>
#include <chrono>
// Define GPIO pins for buttons and LEDs
#define BUTTON_T 16 // blue button
#define BUTTON_S 17 //green button
#define BUTTON_R 19 //red button
#define LED_X 9 //red led
#define LED_O 13 //green led
// Function to print the Tic-Tac-Toe board
void printBoard(char board[3][3], int row, int col) {
printf("\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == row && j == col) {
printf("[%c]", board[i][j]);
} else {
printf(" %c ", board[i][j]);
}
if (j < 2) printf("|");
}
printf("\n");
if (i < 2) {
printf("---+---+---\n");
}
}
printf("\n");
printf(" 1 2 3\n\n");
}
// Function to check if the current player has won
bool checkWin(char board[3][3], char currentPlayer) {
// Check rows, columns, and diagonals
for (int i = 0; i < 3; i++) {
if (board[i][0] == currentPlayer && board[i][1] == currentPlayer && board[i][2] == currentPlayer) {
return true; // Row
}
if (board[0][i] == currentPlayer && board[1][i] == currentPlayer && board[2][i] == currentPlayer) {
return true; // Column
}
}
if (board[0][0] == currentPlayer && board[1][1] == currentPlayer && board[2][2] == currentPlayer) {
return true; // Diagonal (top-left to bottom-right)
}
if (board[0][2] == currentPlayer && board[1][1] == currentPlayer && board[2][0] == currentPlayer) {
return true; // Diagonal (top-right to bottom-left)
}
return false;
}
// Function to check for a tie
bool checkTie(char board[3][3]) {
// Check if all cells are filled
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == ' ') {
return false; // Board is not full
}
}
}
return true; // Board is full (tie)
}
// Function to reset the game
void resetGame(char board[3][3], char ¤tPlayer, int &row, int &col, bool &gameEnded) {
// Clear the board
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = ' ';
}
}
// Reset game state
currentPlayer = 'X'; //red will denote X
row = 0;
col = 0;
gameEnded = false;
printf("Game reset, Player X starts.\n");
}
int main() {
stdio_init_all();
// Initialize GPIO pins for buttons
gpio_init(BUTTON_T);
gpio_set_dir(BUTTON_T, GPIO_IN);
gpio_pull_up(BUTTON_T);
gpio_init(BUTTON_S);
gpio_set_dir(BUTTON_S, GPIO_IN);
gpio_pull_up(BUTTON_S);
gpio_init(BUTTON_R);
gpio_set_dir(BUTTON_R, GPIO_IN);
gpio_pull_up(BUTTON_R);
// Initialize GPIO pins for LEDs
gpio_init(LED_X);
gpio_set_dir(LED_X, GPIO_OUT);
gpio_init(LED_O);
gpio_set_dir(LED_O, GPIO_OUT);
char board[3][3] = { {' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '} };
char currentPlayer = 'X'; // Player X starts the game
int row = 0, col = 0;
bool gameEnded = false;
while (1) {
// Print the current state of the board
//printBoard(board, row, col);
// Check for game reset button
if (gpio_get(BUTTON_R) == 0) {
resetGame(board, currentPlayer, row, col, gameEnded);
gpio_put(LED_X, false); // Turn off LED_X
gpio_put(LED_O, false); // Turn off LED_O
sleep_ms(500); // Debounce delay
printBoard(board, row, col);
continue;
}
// Check for button presses
if (gpio_get(BUTTON_T) == 0) {
// Toggle mode, move the cursor
col = (col + 1) % 3;
if (col == 0) {
row = (row + 1) % 3;
}
printBoard(board, row, col);
sleep_ms(200); // Delay for smoother cursor movement
} else if (gpio_get(BUTTON_S) == 0 && !gameEnded) {
// Select mode, mark the cell
if (board[row][col] == ' ') {
board[row][col] = currentPlayer;
// Check if the current player has won
if (checkWin(board, currentPlayer)) {
printBoard(board, row, col);
printf("Player wins! Congratulations!\n", currentPlayer);
gameEnded = true;
gpio_put(currentPlayer == 'X' ? LED_X : LED_O, true); // Turn on the corresponding LED
sleep_ms(2000); // Delay for 2 seconds before exiting
exit(0); // Stop the code execution
} else { %c
// Check if the board is full (tie)
if (checkTie(board)) {
printBoard(board, row, col);
printf("Game tied!\n");
gameEnded = true;
sleep_ms(2000); // Delay for 2 seconds before exiting
exit(0); // Stop the code execution
} else {
if (currentPlayer == 'X') {
currentPlayer = 'O';
} else {
currentPlayer = 'X';
}
// Reset the cursor position
row = 0;
col = 0;
sleep_ms(500); // Delay before switching players for a smoother experience
gpio_put(LED_X, currentPlayer == 'X'); // Turn on LED_X if currentPlayer is 'X'
gpio_put(LED_O, currentPlayer == 'O'); // Turn on LED_O if currentPlayer is 'O'
}
}
} else {
printf("Cell already occupied. Try again.\n");
sleep_ms(500); // Delay for smoother experience after an invalid move
}
printBoard(board, row, col);
}
sleep_ms(100); // Debounce delay
}
return 0;
}