const uint8_t MODE_SW = 50;
const uint8_t NUM_BTNS = 9;
const uint8_t BTN_PINS[] = {41, 47, 53, 23, 29, 35, 10, 7, 4};
const uint8_t GRN_LED_PINS[] = {39, 45, 51, 2, 27, 33, 11, 8, 5};
const uint8_t RED_LED_PINS[] = {37, 43, 49, 3, 25, 31, 12, 9, 6};
const uint32_t DEBOUNCE_TIME = 20;
bool isGrnTurn = false;
char boardArray[3][3];
uint8_t moves = 0;
uint8_t oldMode = -1; // always different on boot
uint8_t btnState[NUM_BTNS];
uint8_t oldBtnState[NUM_BTNS];
// function returns which button was pressed, or 0 if none
uint8_t checkButtons() {
uint8_t btnPressed = 0;
for (uint8_t i = 0; i < NUM_BTNS; i++) {
btnState[i] = digitalRead(BTN_PINS[i]); // check each button
if (btnState[i] != oldBtnState[i]) { // if it changed
oldBtnState[i] = btnState[i]; // remember state for next time
if (btnState[i] == 0) { // was just pressed
btnPressed = i + 1;
}
delay(20); // debounce
}
}
return btnPressed;
}
bool checkWin() {
// rows / cols
for (int i = 0; i < 3; i++) {
if (boardArray[i][0] == boardArray[i][1] && boardArray[i][0] == boardArray[i][2]) {
//Serial.println("Row");
return true;
}
if (boardArray[0][i] == boardArray[1][i] && boardArray[0][i] == boardArray[2][i]) {
//Serial.println("Col");
return true;
}
}
// diagonals
if (boardArray[0][0] == boardArray[1][1] && boardArray[1][1] == boardArray[2][2]) {
//Serial.println("Diag");
return true;
}
if (boardArray[0][2] == boardArray[1][1] && boardArray[1][1] == boardArray[2][0]) {
//Serial.println("Diag");
return true;
}
return false;
}
void reset() {
moves = 0;
if (isGrnTurn) {
Serial.println("Green goes first\n");
} else {
Serial.println("Red goes first\n");
}
for (uint8_t i = 0; i < NUM_BTNS; i++) {
digitalWrite(GRN_LED_PINS[i], LOW);
digitalWrite(RED_LED_PINS[i], LOW);
}
int count = 49; // 49 = ASCII '1'
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
boardArray[i][j] = count;
count++;
}
}
}
void setup() {
Serial.begin(115200);
pinMode(MODE_SW, INPUT_PULLUP);
for (uint8_t i = 0; i < NUM_BTNS; i++) {
pinMode(GRN_LED_PINS[i], OUTPUT);
pinMode(RED_LED_PINS[i], OUTPUT);
pinMode(BTN_PINS[i], INPUT_PULLUP);
}
}
void loop() {
uint8_t cellNum = 0;
if (digitalRead(MODE_SW) != oldMode) {
oldMode = digitalRead(MODE_SW);
delay(250); // debounce
if (digitalRead(MODE_SW) == 0) {
isGrnTurn = true;
} else {
isGrnTurn = false;
}
reset();
}
uint8_t btnNumber = checkButtons();
if (btnNumber) {
moves++;
//Serial.println(btnNumber);
cellNum = btnNumber - 1;
if (isGrnTurn) {
digitalWrite(GRN_LED_PINS[cellNum], HIGH);
boardArray[cellNum / 3][cellNum % 3] = 'X';
} else {
digitalWrite(RED_LED_PINS[cellNum], HIGH);
boardArray[cellNum / 3][cellNum % 3] = 'O';
}
for (uint8_t i = 0; i < 3; i++) {
for (uint8_t j = 0; j < 3; j++) {
Serial.print(boardArray[i][j]);
}
Serial.println();
}
Serial.println();
bool isWin = checkWin();
if (isWin) {
Serial.println(isGrnTurn ? "Green wins!" : "Red wins!");
Serial.println();
delay(5000);
reset();
return;
}
if (moves == 9) {
Serial.println("It's a draw!\n");
delay(2000);
reset();
return;
}
isGrnTurn = !isGrnTurn;
}
}First
Green is X
Red is O
X < > O