#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// LCD Settings
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Game Constants
const int BUTTON_ROWS = 3;
const int BUTTON_COLS = 3;
// Keypad constants
const byte ROWS = 4;
const byte COLS = 4;
// Array to represent keys on keypad
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'},
};
// Connections to the arduino
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
// Create keypad object
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
// Player Constants
const int PLAYER_NONE = 0;
const int PLAYER_1 = 1;
const int PLAYER_YOU = 2;
// Game Variables
int board[BUTTON_ROWS][BUTTON_COLS];
int currentPlayer;
bool gameOver;
void setup() {
// Initialize LCD Display
lcd.begin(20, 4);
lcd.backlight();
lcd.print("Welcome To My Game, ICT Online");
delay(2000);
lcd.clear();
// Initialize Game Variables
currentPlayer = PLAYER_1;
gameOver = false;
resetBoard();
updateDisplay();
}
void loop() {
// Check for Button Press
char keypress = customKeypad.getKey();
if (keypress == '0') {
setup();
}
if (!gameOver) {
if (keypress <= 57 && keypress >= 49) {
int number = keypress - 57 + 9;
int i = (number - 1) / 3;
int j = ((number - 1) % 3);
if (board[i][j] == PLAYER_NONE) {
board[i][j] = currentPlayer;
updateDisplay();
checkWinCondition();
switchPlayers();
}
delay(200); // Button Rebound
}
}
}
void resetBoard() {
for (int i = 0; i < BUTTON_ROWS; i++) {
for (int j = 0; j < BUTTON_COLS; j++) {
board[i][j] = PLAYER_NONE;
}
}
}
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Player ");
lcd.print(currentPlayer == PLAYER_1 ? "1" : "YOU");
lcd.setCursor(0, 1);
delay(1);
for (int i = 0; i < BUTTON_ROWS; i++) {
lcd.setCursor(0, i + 1);
for (int j = 0; j < BUTTON_COLS; j++) {
lcd.print("|");
lcd.print(symbolForPlayer(board[i][j]));
}
lcd.print("|");
}
// lcd.setCursor(0, 5);
// lcd.print("-------------");
}
char symbolForPlayer(int player) {
if (player == PLAYER_1) {
return 'X';
} else if (player == PLAYER_YOU) {
return 'O';
}
return ' ';
}
void switchPlayers() {
currentPlayer = (currentPlayer == PLAYER_1) ? PLAYER_YOU : PLAYER_1;
}
void checkWinCondition() {
// Check Rows
for (int i = 0; i < BUTTON_ROWS; i++) {
if (board[i][0] != PLAYER_NONE && board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
gameOver = true;
lcd.setCursor(0, 4);
lcd.print("Player ");
lcd.print(symbolForPlayer(board[i][0]));
lcd.print(" wins!");
return;
}
}
// Check Columns
for (int j = 0; j < BUTTON_COLS; j++) {
if (board[0][j] != PLAYER_NONE && board[0][j] == board[1][j] && board[1][j] == board[2][j]) {
gameOver = true;
lcd.setCursor(0, 4);
lcd.print("Player ");
lcd.print(symbolForPlayer(board[0][j]));
lcd.print(" wins!");
return;
}
}
// Check Diagonals
if (board[0][0] != PLAYER_NONE && board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
gameOver = true;
lcd.setCursor(0, 4);
lcd.print("Player ");
lcd.print(symbolForPlayer(board[0][0]));
lcd.print(" wins!");
return;
}
if (board[0][2] != PLAYER_NONE && board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
gameOver = true;
lcd.setCursor(0, 4);
lcd.print("Player ");
lcd.print(symbolForPlayer(board[0][2]));
lcd.print(" wins!");
return;
}
// Check Draw
bool draw = true;
for (int i = 0; i < BUTTON_ROWS; i++) {
for (int j = 0; j < BUTTON_COLS; j++) {
if (board[i][j] == PLAYER_NONE) {
draw = false;
break;
}
}
if (!draw) {
break;
}
}
if (draw) {
gameOver = true;
lcd.setCursor(0, 4);
lcd.print("It's a draw!");
}
}