#include #include #include #include #define BUTTON_MOVE 5 #define BUTTON_OK 4 // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET 7 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET); int gameStatus = 0; int currentPlayer = 0; // 0 = Player 1, 1 = Player 2 int winner = -1; // -1 = Playing, 0 = Draw, 1 = Player 1, 2 = Player 2 int board[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // 0 = blank, 1 = Player 1 (circle), 2 = Player 2 (cross) //-------------------------------------------------------------------------------------------------------- void playMove() { int playerMove = 0; bool stayInLoop = true; bool showDot = false; long timerPos = millis() - 1000; while (stayInLoop) { while (board[playerMove] != 0) { playerMove++; if (playerMove > 8) playerMove = 0; } // Flashing "?" at the current position if (timerPos + 200 < millis()) { timerPos = millis(); showDot = !showDot; playMove_showPos(playerMove, showDot); // Update display } if (digitalRead(BUTTON_MOVE) == LOW) { playMove_showPos(playerMove, false); // Hide "?" at the current position do { playerMove = (playerMove + 1) % 9; // Move to the next position and loop back if necessary } while (board[playerMove] != 0); // Skip over already filled positions showDot = true; // Ensure "?" will be shown at the new position timerPos = millis(); // Reset timer to flash "?" immediately at the new position } if (digitalRead(BUTTON_OK) == LOW) stayInLoop = false; delay(100); } playMove_showPos(playerMove, false); // Hide "?" before updating the board board[playerMove] = currentPlayer + 1; // Assign the chosen cell to the current player. } //-------------------------------------------------------------------------------------------------------- void playMove_showPos(int playerMove, bool showDot) { display.setTextSize(2); // Set cursor position based on playerMove int x = (playerMove % 3) * 20 + 5; int y = (playerMove / 3) * 20 + 5; display.setCursor(x, y); if (showDot) display.setTextColor(WHITE); else display.setTextColor(BLACK); display.print("?"); display.display(); } //-------------------------------------------------------------------------------------------------------- void checkWinner() { // Check horizontal, vertical, and diagonal lines for a win for (int i = 0; i < 3; i++) { if (board[i * 3] != 0 && board[i * 3] == board[i * 3 + 1] && board[i * 3 + 1] == board[i * 3 + 2]) { winner = board[i * 3]; } if (board[i] != 0 && board[i] == board[i + 3] && board[i + 3] == board[i + 6]) { winner = board[i]; } } if ((board[0] != 0 && board[0] == board[4] && board[4] == board[8]) || (board[2] != 0 && board[2] == board[4] && board[4] == board[6])) { winner = board[4]; } if (winner == -1) { bool isDraw = true; for (int i = 0; i < 9; i++) { if (board[i] == 0) { isDraw = false; break; } } if (isDraw) winner = 0; } } //-------------------------------------------------------------------------------------------------------- void resetGame() { for (int i = 0; i < 9; i++) board[i] = 0; winner = -1; gameStatus = 0; currentPlayer = 0; // Start with Player 1 } //-------------------------------------------------------------------------------------------------------- void boardDrawing() { display.clearDisplay(); display.setTextColor(WHITE); // Draw grid lines display.drawFastHLine(0, 21, 64, WHITE); display.drawFastHLine(0, 42, 64, WHITE); display.drawFastVLine(21, 0, 64, WHITE); display.drawFastVLine(42, 0, 64, WHITE); // Draw cell contents display.setTextSize(2); for (int i = 0; i < 9; i++) { int x = (i % 3) * 20 + 5; int y = (i / 3) * 20 + 5; display.setCursor(x, y); if (board[i] == 1) display.print("o"); else if (board[i] == 2) display.print("x"); else display.print(" "); } display.display(); delay(200); } //-------------------------------------------------------------------------------------------------------- void setup() { pinMode(BUTTON_MOVE, INPUT_PULLUP); pinMode(BUTTON_OK, INPUT_PULLUP); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); delay(500); display.clearDisplay(); display.setTextColor(WHITE); display.display(); } //-------------------------------------------------------------------------------------------------------- void loop() { if (gameStatus == 0) { resetGame(); boardDrawing(); gameStatus = 1; } if (gameStatus == 1) { while (winner == -1) { playMove(); boardDrawing(); checkWinner(); currentPlayer = (currentPlayer + 1) % 2; // Switch players } // Show winner or draw message display.setTextSize(2); display.setCursor(68, 25); if (winner == 0) { display.print("Draw"); } else { display.clearDisplay(); display.setCursor(20, 32); display.print("P"); display.print(winner); display.print(" Wins"); } display.display(); delay(2000); // Wait for both buttons to be released while (digitalRead(BUTTON_MOVE) == LOW || digitalRead(BUTTON_OK) == LOW); gameStatus = 0; // Reset for a new game } }