/*
Programmbeschreibung:
Die oberen vier Knöpe sind zum navigiern des Kursers und der untere Knopf zum Bestätigen der Position
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Initialisierung des LCD-Displays mit Adresse 0x27, 20 Zeichen und 4 Zeilen
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Spielfeld und Variablen
char board[3][3] = {
{' ', ' ', ' '},
{' ', ' ', ' '},
{' ', ' ', ' '}
};
int selectedRow = 0, selectedCol = 0; // Aktuelle Auswahl
char currentPlayer = 'X'; // Aktueller Spieler
bool gameWon = false; // Status: Hat jemand gewonnen?
bool gameDraw = false; // Status: Unentschieden?
// Taster-Pins
const int upButton = 6;
const int downButton = 7;
const int leftButton = 8;
const int rightButton = 9;
const int confirmButton = 10;
void setup() {
// Initialisierung des LCD-Displays
lcd.begin(20, 4); // LCD mit 20 Zeichen und 4 Zeilen initialisieren
lcd.backlight(); // Hintergrundbeleuchtung einschalten
// Setze Taster-Pins
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(leftButton, INPUT_PULLUP);
pinMode(rightButton, INPUT_PULLUP);
pinMode(confirmButton, INPUT_PULLUP);
drawBoard(); // Zeige das Start-Spielfeld an
}
// Hauptprogramm
void loop() {
if (!gameWon && !gameDraw) { // Nur wenn das Spiel noch läuft
handleInput();
}
}
// Eingaben verarbeiten
void handleInput() {
if (digitalRead(upButton) == LOW) {
selectedRow = (selectedRow + 2) % 3; // Nach oben (zyklisch)
delay(200); // Entprellen
drawBoard();
}
if (digitalRead(downButton) == LOW) {
selectedRow = (selectedRow + 1) % 3; // Nach unten (zyklisch)
delay(200);
drawBoard();
}
if (digitalRead(leftButton) == LOW) {
selectedCol = (selectedCol + 2) % 3; // Nach links (zyklisch)
delay(200);
drawBoard();
}
if (digitalRead(rightButton) == LOW) {
selectedCol = (selectedCol + 1) % 3; // Nach rechts (zyklisch)
delay(200);
drawBoard();
}
if (digitalRead(confirmButton) == LOW) {
if (board[selectedRow][selectedCol] == ' ') {
board[selectedRow][selectedCol] = currentPlayer;
if (checkWinner(currentPlayer)) {
gameWon = true;
displayWinner(currentPlayer);
} else if (checkDraw()) {
gameDraw = true;
displayDraw();
} else {
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X'; // Spielerwechsel
drawBoard();
}
}
delay(200);
}
}
// Spielfeld zeichnen
void drawBoard() {
lcd.clear(); // LCD Bildschirm löschen
// Zeile 1 (erste drei Felder)
lcd.setCursor(0, 0);
lcdPrintCell(0, 0);
lcd.print("|");
lcdPrintCell(0, 1);
lcd.print("|");
lcdPrintCell(0, 2);
// Zeile 2 (zweite drei Felder)
lcd.setCursor(0, 1);
lcdPrintCell(1, 0);
lcd.print("|");
lcdPrintCell(1, 1);
lcd.print("|");
lcdPrintCell(1, 2);
// Zeile 3 (dritte drei Felder)
lcd.setCursor(0, 2);
lcdPrintCell(2, 0);
lcd.print("|");
lcdPrintCell(2, 1);
lcd.print("|");
lcdPrintCell(2, 2);
// Zeile 4 für Statusanzeige
lcd.setCursor(0, 3);
if (!gameWon && !gameDraw) {
lcd.print("Player: ");
lcd.print(currentPlayer); // Zeigt den aktuellen Spieler
}
}
// Funktion zum Zeichnen der Zellen auf dem Display
void lcdPrintCell(int row, int col) {
if (selectedRow == row && selectedCol == col) {
lcd.print("[");
lcd.print(board[row][col]);
lcd.print("]");
} else {
lcd.print(" ");
lcd.print(board[row][col]);
lcd.print(" ");
}
}
// Überprüft, ob ein Spieler gewonnen hat
bool checkWinner(char player) {
// Überprüfen von Zeilen
for (int row = 0; row < 3; row++) {
if (board[row][0] == player && board[row][1] == player && board[row][2] == player) {
return true;
}
}
// Überprüfen von Spalten
for (int col = 0; col < 3; col++) {
if (board[0][col] == player && board[1][col] == player && board[2][col] == player) {
return true;
}
}
// Überprüfen von Diagonalen
if (board[0][0] == player && board[1][1] == player && board[2][2] == player) {
return true;
}
if (board[0][2] == player && board[1][1] == player && board[2][0] == player) {
return true;
}
return false; // Kein Gewinn gefunden
}
// Überprüft, ob das Spiel unentschieden endet
bool checkDraw() {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
if (board[row][col] == ' ') {
return false; // Noch mindestens ein leeres Feld
}
}
}
return true; // Alle Felder sind gefüllt, ohne Gewinner
}
// Gewinner auf dem Display anzeigen
void displayWinner(char winner) {
lcd.clear(); // Display löschen
lcd.setCursor(0, 1); // Gewinner-Nachricht zentriert in Zeile 2
lcd.print("Player ");
lcd.print(winner);
lcd.print(" wins!");
}
// Unentschieden auf dem Display anzeigen
void displayDraw() {
lcd.clear(); // Display löschen
lcd.setCursor(0, 1); // Nachricht zentriert in Zeile 2
lcd.print("It's a Draw!");
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
btn5:1.l
btn5:2.l
btn5:1.r
btn5:2.r
btn7:1.l
btn7:2.l
btn7:1.r
btn7:2.r
btn10:1.l
btn10:2.l
btn10:1.r
btn10:2.r
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL