// Projektname: TIC TAC TOE
// von Theodor Diehl, Nino Cataffo, Pascal Nikiema
// Zugehöriger Aufbau im Arduino-Emulator WOKWI: https://wokwi.com/projects/350384388994761298
// Stand: 29.12.2022 @alle: bitte immer ändern!
// --- LIBRARIES ---
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// LCD
#include <LiquidCrystal_I2C.h>
// Neo Pixels
#include <FastLED.h>
// Keypad
#include <Keypad.h>
// Headerdateien
#include "Classes.h";
#include "CustomChars.h";
// Joystick
#include <Joystick.h>
// --- INITALISIEREN ---
// LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Neo Pixels
#define LED_PIN 2
#define COLOR_ORDER GRB
#define CHIPSET WS2811
#define BRIGHTNESS 255
#define MATRIX_WIDTH 10
#define MATRIX_HEIGHT 10
#define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT)
#define Clear 5
const bool kMatrixSerpentineLayout = true;
CRGB leds[NUM_LEDS];
byte xy(byte x, byte y) {
return x + y * MATRIX_WIDTH;
}
// Keypad
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 8, 7, 6, 5 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 12, 11, 10, 9 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Joystick
#define VERT_PIN A0
#define HORZ_PIN A1
#define SEL_PIN 3
// Objekte
Field gameField(10, 10, 5, 5);
Player playerX("x", CRGB(255, 0, 0), 2); // Player-Farben erstmal provisorisch + LIFEPOINT nach auswahl neu setten mit setLifepoint() !!
Player playerO("o", CRGB(255, 255, 0), 2);
// Variablen
bool xTurn = true;
bool oTurn = false;
const long interval = 100;
bool ledOn = true;
unsigned long previousMillis = 0;
int selectedX = 0;
int selectedY = 0;
bool selected = false;
bool passedMathQuiz = false;
bool mathQuizStarted = false;
int userAnswer;
int downsel=0;
int downsel1=0;
byte pointer[] = {0x00, 0x00, 0x04, 0x02, 0x1D, 0X02, 0X04, 0X00};
byte Check[] = {
B00000,
B00001,
B00011,
B10110,
B11100,
B01000,
B00000,
B00000
};
int box[5][5] = { // 0 ist leer, 1 ist X, 2 ist O
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}
};
enum STATUS { // Status des Spiels
MENU, // 0 /
ROUND, // 1
EVALUATION // 2
};
STATUS gameStatus = 0;
enum eDIRECTIONS { // Richtungen für Joystick
LEFT, // 0
UP, // 1
RIGHT, // 2
DOWN, // 3
NONE // 4
};
eDIRECTIONS M1dir = NONE; // Merker
char *actuallyDisplayedOnLCD[4];
void setup() {
// Setup
Serial.begin(9600);
// Joystick
pinMode(VERT_PIN, INPUT);
pinMode(HORZ_PIN, INPUT);
pinMode(SEL_PIN, INPUT_PULLUP);
// LCD
lcd.init();
lcd.backlight();
lcd.createChar(0, bulletpoint);
//lcd.setCharset(CS12);
// Neo Pixels
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(UncorrectedColor);
FastLED.setBrightness(BRIGHTNESS);
FastLED.show();
//---DEBUG/DEVELOPING AREA
passedMathQuiz = true;
selected = false;
//------------------------
Serial.println("Setup beendet.");
//lcd.begin(20,4);
lcd.init(); // initialize the lcd
lcd.backlight();
// pinMode
pinMode(SEL_PIN,INPUT_PULLUP);
pinMode(Clear,INPUT_PULLUP);
// Startanzeige
lcd.setCursor(0,0);
lcd.print("TIC TAC TOD : ");
lcd.setCursor(0,2);
lcd.print("The Brain Edition ");
delay(1000);
lcd.clear();
lcd.createChar(5, pointer); // create a new character
lcd.createChar(6, Check);
}
void loop() {
switch (gameStatus) {
case MENU:
showMenu();
break;
case ROUND:
if (!selected) {
if (passedMathQuiz) {
chooseBox();
} else if (!mathQuizStarted) {
Serial.println("quiz");
mathQuiz();
}
} else evaluate();
break;
case EVALUATION:
evaluate();
break;
}
}
void showMenu() {
UPandDOWN();
}
void UPandDOWN(){
int horz = analogRead(HORZ_PIN);
int vert = analogRead(VERT_PIN);
lcd.clear();
switch(downsel){
case 0: lcd.setCursor(0,0);
lcd.write(5);
break;
case 1: lcd.setCursor(0,1);
lcd.write(5);
break;
case 2: lcd.setCursor(0,2);
lcd.write(5);
break;
case 3: lcd.setCursor(0,3);
lcd.write(5);
break;
}
lcd.setCursor(1,0);
lcd.print("START GAME");
lcd.setCursor(1,1);
lcd.print("MANUAL");
lcd.setCursor(1,2);
lcd.print("CHARACTERS & POWER");
lcd.setCursor(1,3);
lcd.print("CREDITS");
if (vert < 300){
downsel++;
delay(200);
}
if (vert > 700) {
downsel--;
delay(100);
}
if (downsel > 3 ) {
downsel = 0;
}
if (downsel < 0 ) {
downsel = 0;
}
if(digitalRead(SEL_PIN)== LOW){
while(1){
executeAction();
if(digitalRead(Clear)== LOW){
lcd.clear();
}
}
}
delay(100);
}
void executeAction() {
switch (downsel) {
case 0:
action0();
break;
case 1:
action1();
break;
case 2:
action2();
break;
case 3:
action3();
break;
}
}
void action0() {
int horz = analogRead(HORZ_PIN);
int vert = analogRead(VERT_PIN);
lcd.clear();
switch(downsel1){
case 0: lcd.setCursor(0,0);
lcd.write(5);
break;
case 1: lcd.setCursor(0,1);
lcd.write(5);
break;
case 2: lcd.setCursor(0,2);
lcd.write(5);
break;
case 3: lcd.setCursor(0,3);
lcd.write(5);
break;
}
lcd.setCursor(0,0);
lcd.print("SPIELER X");
lcd.setCursor(1,1);
lcd.print("Charakter 1");
lcd.setCursor(1,2);
lcd.print("Charakter 2");
lcd.setCursor(1,3);
lcd.print("Charakter 3");
if (vert < 300){
downsel1++;
delay(200);
}
if (vert > 700) {
downsel1--;
delay(100);
}
if (downsel1 > 3 ) {
downsel1 = 0;
}
if (downsel1 < 0 ) {
downsel1 = 0;
}
if(digitalRead(SEL_PIN)== LOW){
while(1){
executeAction2();
if(digitalRead(Clear)== LOW){
lcd.clear();
}
}
}
delay(100);
}
void executeAction2() {
int horz = analogRead(HORZ_PIN);
int vert = analogRead(VERT_PIN);
lcd.clear();
switch(downsel1){
case 0: lcd.setCursor(0,0);
lcd.write(5);
break;
case 1: lcd.setCursor(0,1);
lcd.write(5);
break;
case 2: lcd.setCursor(0,2);
lcd.write(5);
break;
case 3: lcd.setCursor(0,3);
lcd.write(5);
break;
}
lcd.setCursor(0,0);
lcd.print("SPIELER O");
lcd.setCursor(1,1);
lcd.print("Charakter 1");
lcd.setCursor(1,2);
lcd.print("Charakter 2");
lcd.setCursor(1,3);
lcd.print("Charakter 3");
if (vert < 300){
downsel1++;
delay(200);
}
if (vert > 700) {
downsel1--;
delay(100);
}
if (downsel1 > 3 ) {
downsel1 = 0;
}
if (downsel1 < 0 ) {
downsel1 = 0;
}
if(digitalRead(SEL_PIN)== LOW){
while(1){
executeAction3();
if(digitalRead(Clear)== LOW){
lcd.clear();
}
}
}
delay(100);
}
void executeAction3() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("NA LOS ! ");
lcd.setCursor(0,2);
lcd.print("M\xEF""ge das bessere ");
lcd.setCursor(0,3);
lcd.print("Brain gewinnen! ");
if(digitalRead(SEL_PIN)== LOW){
while(1){ mathQuiz() ;
if(digitalRead(Clear)== LOW){
lcd.clear();
}
}
}
delay(100);
}
void mathQuiz() {
mathQuizStarted = true;
const int TIME_LIMIT = 5000; // Sekunden in Millisekunden
int num1, num2, correctAnswer;
// Generiert zweistellige Multiplikation
num1 = random(5, 20);
num2 = random(20, 49);
correctAnswer = num1 * num2;
lcd.setCursor(0,2);
lcd.print(" ");
startCountdown();
// Initialisiert Timer
unsigned long startTime = millis();
// Zeigt die Rechenaufgabe auf dem LCD
quizOnLCD(String(num1), 0, 0);
quizOnLCD(" x ", 2, 0);
quizOnLCD(String(num2), 5, 0);
quizOnLCD(" =", 7, 0);
// Liest user input
while (millis() - startTime < TIME_LIMIT) {
readKeypad();
}
// Überprüfen, ob User Input richtig ist
if (userAnswer == correctAnswer) { while(1){ chooseBox(); ;
if(digitalRead(Clear)== LOW){
lcd.clear();
}
}
quizOnLCD("Richtig!", 0, 0); // Zeigt "Richtig!" auf dem LCD
delay(3000);
passedMathQuiz = true;
unsigned long startTime = millis();
while (millis() - startTime < 3000) {}
// Delay von 3 Sekunden
}
else {
quizOnLCD("Versagt!", 0, 0); // Zeigt "Falsch!" auf dem LCD
unsigned long startTime = millis();
while (millis() - startTime < 3000) {} // Delay von 3 Sekunden
}
userAnswer = 0;
}
char *activePlayer() {
if (oTurn) return "O";
if (xTurn) return "X";
}
void chooseBox() {
char message[20];
strcpy(message, "Du bist am Zug, ");
strcat(message, activePlayer());
writeOnLCD(message, 0, 0);
writeOnLCD("W\xE1""hle per Joystick", 0, 1);
writeOnLCD("ein Feld aus und be-", 0, 2);
writeOnLCD("st\xE1""ige durch Klicken", 0, 3);
eDIRECTIONS dir = readDirection();
switch (dir) {
case DOWN:
//Serial.println("s");
if (M1dir != DOWN) {
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), CRGB(0, 0, 0));
do {
if (selectedY != 4) {
selectedY++;
} else selectedY = 0;
} while (box[selectedX][selectedY] != 0);
}
break;
case RIGHT:
//Serial.println("d");
if (M1dir != RIGHT) {
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), CRGB(0, 0, 0));
do {
if (selectedX != 4) {
selectedX++;
} else selectedX = 0;
} while (box[selectedX][selectedY] != 0);
}
break;
case UP:
//Serial.println("w");
if (M1dir != UP) {
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), CRGB(0, 0, 0));
do {
if (selectedY != 0) {
selectedY--;
} else selectedY = 4;
} while (box[selectedX][selectedY] != 0);
}
break;
case LEFT:
//Serial.println("a");
if (M1dir != LEFT) {
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), CRGB(0, 0, 0));
do {
if (selectedX != 0) {
selectedX--;
} else selectedX = 4;
} while (box[selectedX][selectedY] != 0);
}
break;
case NONE:
//Serial.println("n");
blinkSelected();
break;
}
M1dir = dir; // Merker
if (digitalRead(SEL_PIN) == LOW) logInBox();
delay(50);
}
void blinkSelected() {
unsigned long blinkTime = millis();
if (blinkTime - previousMillis >= interval) {
previousMillis = blinkTime;
if (ledOn) {
CRGB blinkColor = CRGB::Black;
if (xTurn) blinkColor = playerX.getColor();
if (oTurn) blinkColor = playerO.getColor();
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), blinkColor);
ledOn = false;
} else {
// Um zu vermeiden, dass das gesamte Spielfeld geleert wird, wird im folgenden nicht die clear()-FUnktion, sondern CRGB::Black (0,0,0) verwendet
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), CRGB(0, 0, 0));
ledOn = true;
}
}
}
void logInBox() {
Serial.print(activePlayer());
Serial.print(selectedX);
Serial.print(selectedY);
if (xTurn) {
box[selectedX][selectedY] = 1;
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), playerX.getColor());
}
if (oTurn) {
box[selectedX][selectedY] = 2;
drawRect(selectedX * 2, selectedY * 2, (gameField.getWidth() / gameField.getColumns()), (gameField.getHeight() / gameField.getColumns()), playerO.getColor());
}
Serial.println();
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
Serial.print(box[x][y]);
}
Serial.println();
}
gameStatus = ROUND;
}
void action1() {
lcd.clear();
lcd.blink(); // turn on the blinking cursor
delay(3000);
int showInstructionPage = 1;
while (showInstructionPage != 13) {
if (showInstructionPage == 1)
{ // Beschreibung 1
lcd.setCursor(0,0);
lcd.print("Tic Tac Toe neu");
lcd.setCursor(0,1);
lcd.print("aufgelegt!");
lcd.setCursor(0,2);
lcd.print("Charaktere mit");
lcd.setCursor(0,3);
lcd.print("Spezialkr\xE1""ften");
} else if (showInstructionPage == 2) {
// Beschreibung 2
lcd.setCursor(0,0);
lcd.print("und Kopfrechen-");
lcd.setCursor(0,1);
lcd.print("Duelle um Leben");
lcd.setCursor(0,2);
lcd.print("und Tod! 3 zur");
lcd.setCursor(0,3);
lcd.print("Auswahl mit den");
} else if (showInstructionPage == 3) {
// Beschreibung 3
lcd.setCursor(0,0);
lcd.print("Spezialkr\xE1""ften :");
lcd.setCursor(0,1);
lcd.print("- L\xEF""sche,");
lcd.setCursor(0,2);
lcd.print("invertiere oder");
lcd.setCursor(0,3);
lcd.print("zufallsgeneriere");
} else if (showInstructionPage == 4) {
// Beschreibung 4
lcd.setCursor(0,0);
lcd.print("ausgew\xE1""hltes Feld ");
lcd.setCursor(0,1);
lcd.print("und seine Nachbarn. ");
lcd.setCursor(0,2);
lcd.print("( Ein Mal pro Runde ");
lcd.setCursor(0,3);
lcd.print("einsetzbar) ");
} else if (showInstructionPage == 5) {
// Beschreibung 5
lcd.setCursor(0,0);
lcd.print("Vor jeder Runde ");
lcd.setCursor(0,1);
lcd.print("werdet ihr beide ");
lcd.setCursor(0,2);
lcd.print("abwechselnd 'nem ");
lcd.setCursor(0,3);
lcd.print("Mathetest unterzogen");
} else if (showInstructionPage == 6) {
// Beschreibung 6
lcd.setCursor(0,0);
lcd.print("Bestanden ? ");
lcd.setCursor(0,1);
lcd.print("Begib dich zum ");
lcd.setCursor(0,2);
lcd.print("Tic-Tac-Tod-Feld. ");
lcd.setCursor(0,3);
lcd.print(" ");
} else if (showInstructionPage == 7) {
// Beschreibung 7
lcd.setCursor(0,0);
lcd.print("Versagt? ... ");
lcd.setCursor(0,1);
lcd.print("YOU SHALL NOT PASS!");
lcd.setCursor(0,2);
lcd.print(" -1 Lebenspunkt ");
lcd.setCursor(0,3);
lcd.print("Punkt(LP) ");
} else if (showInstructionPage == 8) {
// Beschreibung 8
lcd.setCursor(0,0);
lcd.print("Das Feld ist 5x5 ");
lcd.setCursor(0,1);
lcd.print("gro\xE2"" und 4 Reihe ");
lcd.setCursor(0,2);
lcd.print("f\xF5""hren zum Sieg ");
lcd.setCursor(0,3);
lcd.print("(+1 LP). ");
} else if (showInstructionPage == 9) {
// Beschreibung 9
lcd.setCursor(0,0);
lcd.print("Zum Gewinnen des ");
lcd.setCursor(0,1);
lcd.print("Spiels gilt es ");
lcd.setCursor(0,2);
lcd.print("als erstes 10 LP");
lcd.setCursor(0,3);
lcd.print("zu erreichen oder");
} else if (showInstructionPage == 10) {
// Beschreibung 10
lcd.setCursor(0,0);
lcd.print("darauf zu hoffen,");
lcd.setCursor(0,1);
lcd.print("dass dein Gegner ");
lcd.setCursor(0,2);
lcd.print("alle LP verliert.");
lcd.setCursor(0,3);
lcd.print("Beachtet : ");
} else if (showInstructionPage == 11) {
// Beschreibung 11
lcd.setCursor(0,0);
lcd.print("Charaktere haben ");
lcd.setCursor(0,1);
lcd.print("unterschiedlich " );
lcd.setCursor(0,2);
lcd.print("viel Start-LP und");
lcd.setCursor(0,3);
lcd.print("Zeit zum Rechnen,");
} else if (showInstructionPage == 12) {
// Beschreibung 12
lcd.setCursor(0,0);
lcd.print("also w\xE1""hlet ");
lcd.setCursor(0,1);
lcd.print("weise... ");
lcd.setCursor(0,2);
lcd.print("M\xEF""ge das bessere ");
lcd.setCursor(0,3);
lcd.print("Brain gewinnen! ");
}
if (digitalRead(SEL_PIN) == LOW) showInstructionPage++;
}
delay(1500);
}
void action2() {
lcd.clear();
lcd.blink(); // turn on the blinking cursor
delay(3000);
int showInstructionPage = 1;
while (showInstructionPage != 4) {
if (showInstructionPage == 1)
{ // Beschreibung 1
lcd.setCursor(0,0);
lcd.print("CHARAKTER 1 (2LP) ");
lcd.setCursor(0,1);
lcd.print("FARBE : Grun");
lcd.setCursor(0,2);
lcd.print("FAHIGKEIT : Loschen");
lcd.setCursor(0,3);
lcd.print("ZEIT : 12 Sekunden");
} else if (showInstructionPage == 2) {
// Beschreibung 2
lcd.setCursor(0,0);
lcd.print("CHARAKTER 2 (5LP) ");
lcd.setCursor(0,1);
lcd.print("FARBE : Gelb ");
lcd.setCursor(0,2);
lcd.print("FAHIGKEIT : Invers ");
lcd.setCursor(0,3);
lcd.print("ZEIT : 15 Sekunden");
} else if (showInstructionPage == 3) {
// Beschreibung 3
lcd.setCursor(0,0);
lcd.print("CHARAKTER 3 (6LP) ");
lcd.setCursor(0,1);
lcd.print("FARBE : Lilla");
lcd.setCursor(0,2);
lcd.print("FAHIGKEIT:Generieren");
lcd.setCursor(0,3);
lcd.print("ZEIT : 17 Sekunden");
}
if (digitalRead(SEL_PIN) == LOW) showInstructionPage++;
}
delay(1500);
}
void action3() {
lcd.clear();
int showInstructionPage = 1;
while (showInstructionPage != 3) {
if (showInstructionPage == 1)
{ // Beschreibung 1
lcd.setCursor(0,0);
lcd.print("PROGRAMMIERT VON : ");
lcd.setCursor(0,1);
lcd.print("Nino Cataffo");
lcd.setCursor(0,2);
lcd.print("Theodor Diehl ");
lcd.setCursor(0,3);
lcd.print("Pascal Nikiema ");
} else if (showInstructionPage == 2) {
// Beschreibung 2
lcd.setCursor(0,0);
lcd.print("HAW HAMBURG 2023 ");
lcd.setCursor(0,1);
lcd.print("ALL RIGHTS RESERVED ");
lcd.setCursor(0,3);
lcd.print("Dozent : xxxxxxxx ");
lcd.setCursor(0,3);
lcd.print(" ");
}
if (digitalRead(SEL_PIN) == LOW) showInstructionPage++;
}
delay(1500);
}
void startCountdown() {
int countdown = 5;
unsigned long startTime = millis();
while (countdown > 0) { // Zeigt Countdown und Hinweis auf dem LCD
quizOnLCD(String(countdown), 0, 0);
quizOnLCD("Dr""\xF5""cke D zum L""\xEF""schen", 0, 3);
unsigned long currentTime = millis();
if (currentTime - startTime >= 1000) { // 1 Sekunde ist vergangen
countdown--;
startTime = currentTime;
}
}
clearLCDquiz(0, 3);
}
void readKeypad() {
char key = keypad.getKey();
if (key >= '0' && key <= '9') {
if (userAnswer >= 100) {} // userAnswer ist schon eine 3-stellige Zahl, also tue nichts
else {
userAnswer = (userAnswer * 10) + (key - '0');
quizOnLCD(String(userAnswer), 0, 0);
}
} else if (key == 'D') { // Setzt userAnswer auf 0
userAnswer = 0;
quizOnLCD(String(userAnswer), 0, 0);
}
}
void evaluate() {// Auswertung des Spielfeldes und gucken ob jmd gewonnen hat
// Überprüfen, ob eine der Zeilen komplett aus X oder O besteht
for (int i = 0; i < 5; i++) {
if (box[i][0] == box[i][1] && box[i][1] == box[i][2] && box[i][2] == box[i][3] && box[i][3] == box[i][4]) {
if (box[i][0] != 0)
wonRound();
}
}
// Überprüfen, ob eine der Spalten komplett aus X oder O besteht
for (int i = 0; i < 5; i++) {
if (box[0][i] == box[1][i] && box[1][i] == box[2][i] && box[2][i] == box[3][i] && box[3][i] == box[4][i]) {
if (box[0][i] != 0)
wonRound();
}
}
for (int i = 0; i < 5; i++) {
if (box[i][i] == box[(i + 1) % 5][(i + 1) % 5] && box[(i + 1) % 5][(i + 1) % 5] == box[(i + 2) % 5][(i + 2) % 5] && box[(i + 2) % 5][(i + 2) % 5] == box[(i + 3) % 5][(i + 3) % 5] && box[(i + 3) % 5][(i + 3) % 5] == box[(i + 4) % 5][(i + 4) % 5]) {
if (box[i][i] != 0)
wonRound();
}
}
for (int i = 0; i < 5; i++) {
if (box[i][4 - i] == box[(i + 1) % 5][3 - (i + 1) % 5] && box[(i + 1) % 5][3 - (i + 1) % 5] == box[(i + 2) % 5][2 - (i + 2) % 5] && box[(i + 2) % 5][2 - (i + 2) % 5] == box[(i + 3) % 5][1 - (i + 3) % 5] && box[(i + 3) % 5][1 - (i + 3) % 5] == box[(i + 4) % 5][-(i + 4) % 5]) {
if (box[i][4 - 1] != 0)
wonRound();
}
}
// Keine Gewinnbedingung erfüllt
selectedX = 0; //Später noch ändern
selectedY = 0;
xTurn = !xTurn;
oTurn = !oTurn;
passedMathQuiz = false;
gameStatus = ROUND;
}
void wonRound() {//Wird zwischen den Runden ausgeführt, nachdem ein player gewonnen hat
// Falls noch zeit ist: Gewinnfelder-Blinkeffekt erstellen
while (digitalRead(SEL_PIN) != LOW) {
if (oTurn)
{
playerO.setLifepoint(playerO.getLifepoint() + 1);
} else {
playerX.setLifepoint(playerX.getLifepoint() + 1);
}
char message[20];
strcpy(message, activePlayer());
strcat(message, " hat gewonnen!");
writeOnLCD(message, 0, 0);
writeOnLCD("o x", 0, 1);
char points[20];
strcpy(points, playerO.getLifepoint());
strcat(points, " ");
writeOnLCD(points, 0, 2);
writeOnLCD(">> Joystick klicken", 0, 3);
}
if (digitalRead(SEL_PIN) == LOW) {
clearUpBox();
xTurn = !xTurn;
oTurn = !oTurn;
gameStatus = ROUND;
}
}
void clearUpBox() {
drawRect(0, 0, 10, 10, CRGB(0, 0, 0)); //Spielfeld für nächste Runde clearen
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
box[i][j] = 0;
}
}
}
// ---- METHODEN FÜR Bearbeitung des LCD - DISPLAYs
void writeOnLCD(char text[], int x, int y) {
if (strcmp(text, actuallyDisplayedOnLCD[y]) != 0) {
clearLCDLine(y);
lcd.setCursor(x, y);
lcd.print(text);
actuallyDisplayedOnLCD[y] = text;
Serial.println(text);
Serial.println(actuallyDisplayedOnLCD[y]);
}
}
void clearLCDLine(int line) { // Quelle der Methide: https://forum.arduino.cc/t/how-to-delete-line-on-lcd/206905/11
lcd.setCursor(0, line);
for (int n = 0; n < 20; n++) // 20 indicates symbols in line. For 2x16 LCD write - 16
{
lcd.print(" ");
}
}
void drawOnLCD(int icon, int x, int y) {
lcd.setCursor(x, y);
lcd.write(icon);
}
void quizOnLCD(String text, int x, int y) {
if (text != actuallyDisplayedOnLCD[y]) {
clearLCDquiz(x, y);
lcd.setCursor(x, y);
lcd.print(text);
}
}
void clearLCDquiz(int letter, int line) { // Quelle der Methode: https://forum.arduino.cc/t/how-to-delete-line-on-lcd/206905/11
lcd.setCursor(letter, line);
for (int n = 0; n < 20; n++)
{
lcd.print(" ");
}
}
// ---- METHODEM FÜR NEO PIXEL
void drawRect(byte xStart, byte yStart, byte width, byte height, CRGB color) {
for (byte y = 0; y < height; y++) {
for (byte x = 0; x < width; x++) {
leds[xy(xStart + x, yStart + y)] = color;
}
}
FastLED.show();
}
// ------ SENSOREN
int readDirection() { // Auslesen des Joysticks und Rückgabe eines int für Switch Case
if (analogRead(VERT_PIN) != 512 || analogRead(HORZ_PIN) != 512) {
if (analogRead(HORZ_PIN) > 700) { // >
return 0;//Links
}
if (analogRead(VERT_PIN) > 700) { // ^
return 1;//Oben
}
if (analogRead(HORZ_PIN) < 300) { // <
return 2;//Rechts
}
if (analogRead(VERT_PIN) < 300) { // v
return 3;//Unten
}
}
return 4;//Null
}
/*
NOTIZEN (FÜR SPÄTER)
---
Auslesen des Keypads:
char key = keypad.getKey();
if (key != NO_KEY) {
Serial.println(key);
}
---
Auf LCD Display schreiben
lcd.setCursor(7, 1);
lcd.print(millis() / 1000);
---
Auslesen des Joysticks:
int direction = readDirection()
switch (button) {
case DOWN:
break;
case RIGHT:
break;
case UP:
break;
case LEFT:
break;
}
*/