diff --git a/Start_Windows/game.c b/Start_Windows/game.c index d8cc133..a71ca5e 100644 --- a/Start_Windows/game.c +++ b/Start_Windows/game.c @@ -3,21 +3,110 @@ #include #include +// Wie oft versucht wird, ein Wort zufällig zu platzieren #define MAX_RAND_TRIES_PER_WORD 10 +// Kennzeichen für leere Felder (wird später durch Buchstaben ersetzt) #define EMPTY_CHAR 0 -//TODO: Spiellogik implementieren: -/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren - * restliche Felder mit zufälligen Buchstaben füllen */ - -// Creates the word salad by placing words randomly and filling empty spaces -int createWordSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], unsigned int wordCount) -{ +// Richtungen für das Platzieren der Wörter +typedef enum { HORIZONTAL = 0, VERTICAL = 1 } Direction; +// Gibt einen zufälligen Großbuchstaben A–Z zurück +static char randomLetter(void) { + return 'A' + (rand() % 26); } -// Prints the word salad to console -void showWordSalad(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen) -{ +// Prüft, ob ein Wort an der gegebenen Position und Richtung ins Spielfeld passt +static int canPlace(const char field[][MAX_SEARCH_FIELD_LEN], unsigned int fieldSize, + const char *word, unsigned int row, unsigned int col, Direction dir) { + int length = strlen(word); + + if (dir == HORIZONTAL) { + if (col + length > fieldSize) return 0; // würde rechts rausgehen + for (int i = 0; i < length; i++) { + char current = field[row][col + i]; + if (current != EMPTY_CHAR && current != word[i]) + return 0; // Kollision mit anderem Wort + } + } else { // VERTICAL + if (row + length > fieldSize) return 0; // würde unten rausgehen + for (int i = 0; i < length; i++) { + char current = field[row + i][col]; + if (current != EMPTY_CHAR && current != word[i]) + return 0; + } + } + return 1; // Platz ist frei } + +// Schreibt ein Wort tatsächlich ins Spielfeld +static void placeWord(char field[][MAX_SEARCH_FIELD_LEN], const char *word, + unsigned int row, unsigned int col, Direction dir) { + + int length = strlen(word); + + if (dir == HORIZONTAL) { + for (int i = 0; i < length; i++) + field[row][col + i] = word[i]; + } else { + for (int i = 0; i < length; i++) + field[row + i][col] = word[i]; + } +} + +// Hauptfunktion: erstellt das Buchstabenfeld mit den versteckten Wörtern +int createWordSalad(char field[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int fieldSize, const char words[][MAX_WORD_LEN], unsigned int wordCount) +{ + srand((unsigned)time(NULL)); // Zufallsstartwert setzen + + // 1) Feld "leer" + for (unsigned int r = 0; r < fieldSize; r++) { + for (unsigned int c = 0; c < fieldSize; c++) { + field[r][c] = EMPTY_CHAR; + } + } + + // 2) Wörter zufällig platzieren + int placedWords = 0; + + for (unsigned int w = 0; w < wordCount; w++) { + const char *word = words[w]; + if (!word || word[0] == '\0') continue; // leere Zeilen überspringen + + int placed = 0; + for (int tries = 0; tries < MAX_RAND_TRIES_PER_WORD && !placed; tries++) { + Direction dir = (rand() % 2 == 0) ? HORIZONTAL : VERTICAL; + unsigned int row = rand() % fieldSize; + unsigned int col = rand() % fieldSize; + + if (canPlace(field, fieldSize, word, row, col, dir)) { + placeWord(field, word, row, col, dir); + placedWords++; + placed = 1; + } + } + } + + // 3) Leere Felder mit Zufallsbuchstaben füllen + for (unsigned int r = 0; r < fieldSize; r++) { + for (unsigned int c = 0; c < fieldSize; c++) { + if (field[r][c] == EMPTY_CHAR) + field[r][c] = randomLetter(); + } + } + + return placedWords; +} + +// Gibt das Spielfeld auf der Konsole aus +void showWordSalad(const char field[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int fieldSize) +{ + for (unsigned int r = 0; r < fieldSize; r++) { + for (unsigned int c = 0; c < fieldSize; c++) { + printf("%c ", field[r][c]); + } + printf("\n"); + } +} \ No newline at end of file diff --git a/Start_Windows/game.o b/Start_Windows/game.o new file mode 100644 index 0000000..c1a94f7 Binary files /dev/null and b/Start_Windows/game.o differ diff --git a/Start_Windows/graphicalGame.o b/Start_Windows/graphicalGame.o new file mode 100644 index 0000000..c572af6 Binary files /dev/null and b/Start_Windows/graphicalGame.o differ diff --git a/Start_Windows/input.c b/Start_Windows/input.c index ed77805..38477ad 100644 --- a/Start_Windows/input.c +++ b/Start_Windows/input.c @@ -2,11 +2,38 @@ #include #include -// TODO: -// eine Funktion implementieren, die ein einzelnes Wort aus einer Textdatei (words.txt) einliest und als C-String zurückgibt. - -// Read words from file and store in 'words' array int readWords(FILE *file, char words[][MAX_WORD_LEN], unsigned int maxWordCount) { + unsigned int count = 0; // Anzahl übernommener Wörter + int j = 0; // aktuelle Wortlänge + int ch; // eingelesenes Zeichen + char buf[MAX_WORD_LEN]; // Puffer für ein Wort + while ((ch = fgetc(file)) != EOF) { + unsigned char c = (unsigned char)ch; + if (isalnum(c)) { + // Teil eines Wortes → Uppercase, sicher begrenzt + if (j < (MAX_WORD_LEN - 1)) { + buf[j++] = (char)toupper(c); + } + } else { + // Trennzeichen: Wort abschließen, wenn vorhanden + if (j > 0) { + buf[j] = '\0'; + strncpy(words[count], buf, MAX_WORD_LEN); + count++; + j = 0; + if (count >= maxWordCount) break; + } + } + } + + // Letztes Wort am Dateiende übernehmen + if (j > 0 && count < maxWordCount) { + buf[j] = '\0'; + strncpy(words[count], buf, MAX_WORD_LEN); + count++; + } + + return (int)count; } \ No newline at end of file diff --git a/Start_Windows/input.o b/Start_Windows/input.o new file mode 100644 index 0000000..ba90f19 Binary files /dev/null and b/Start_Windows/input.o differ diff --git a/Start_Windows/main.c b/Start_Windows/main.c index 03da755..47ab431 100644 --- a/Start_Windows/main.c +++ b/Start_Windows/main.c @@ -5,7 +5,7 @@ #include "graphicalGame.h" #define MAX_NUMBER_OF_WORDS 100 -#define SALAD_SIZE 20 +#define SALAD_SIZE 18 int main(int argc, char *argv[]) { @@ -36,10 +36,26 @@ int main(int argc, char *argv[]) // Create the word salad by placing words into grid placedWords = createWordSalad(wordSalad, SALAD_SIZE, words, wordCount); - // TODO: - // Check if all words were successfully placed - // Start the game if successful - // error message if some words couldn't be placed + if (placedWords == wordCount) { + printf("[OK] %u/%u Wörter platziert.\n", placedWords, wordCount); + showWordSalad(wordSalad, SALAD_SIZE); + + // Optional: Grafische Ausgabe starten, falls vorhanden. + // Aktivieren durch -DSTART_GRAPHICS beim Kompilieren + // und wenn in graphicalGame.h eine passende Funktion existiert. +#ifdef START_GRAPHICS + startGame((const char (*)[MAX_SEARCH_FIELD_LEN])wordSalad, + SALAD_SIZE, + words, + wordCount, + 1000); +#endif + } else { + fprintf(stderr, "[FEHLER] Nur %u von %u Wörtern konnten platziert werden.\n", + placedWords, wordCount); + fprintf(stderr, "Tipp: Größe des Suchfeldes (SALAD_SIZE) erhöhen oder kürzere Wortliste verwenden.\n"); + exitCode = EXIT_FAILURE; + } } else diff --git a/Start_Windows/main.o b/Start_Windows/main.o new file mode 100644 index 0000000..5113b30 Binary files /dev/null and b/Start_Windows/main.o differ diff --git a/Start_Windows/makefile b/Start_Windows/makefile index 146a8c6..766dd4b 100644 --- a/Start_Windows/makefile +++ b/Start_Windows/makefile @@ -1,43 +1,48 @@ CC = gcc -CFLAGS = -g -Wall -I$(raylibfolder) -LDFLAGS = -lopengl32 -lgdi32 -lwinmm -BINARIES = ./windows raylib_folder = ./raylib -unityfolder = ./unity +unityfolder = ./unity +BINARIES = ./windows + +CFLAGS = -g -Wall -I$(raylib_folder) -DSTART_GRAPHICS +LDFLAGS = -lopengl32 -lgdi32 -lwinmm # -------------------------- # initiales Spiel bauen # -------------------------- -wordsalad_initial: - $(CC) -o wordsalad_initial $(BINARIES)/libwordsalad_complete.a $(BINARIES)/libraylib.a $(LDFLAGS) - +wordsalad_initial: $(BINARIES)/libwordsalad_complete.a $(BINARIES)/libraylib.a + $(CC) -o $@ $(BINARIES)/libwordsalad_complete.a $(BINARIES)/libraylib.a $(LDFLAGS) # -------------------------- # Normales Spiel bauen # -------------------------- -all: main.o input.o game.o graphicalGame.o $(BINARIES)/libraylib.a - $(CC) $(CFLAGS) -o wordsalad main.o input.o game.o graphicalGame.o $(BINARIES)/libraylib.a $(LDFLAGS) +all: wordsalad + +wordsalad: main.o input.o game.o graphicalGame.o $(BINARIES)/libraylib.a + $(CC) $(CFLAGS) -o $@ main.o input.o game.o graphicalGame.o $(BINARIES)/libraylib.a $(LDFLAGS) main.o: main.c - $(CC) -c $(CFLAGS) main.c + $(CC) $(CFLAGS) -c main.c -o main.o input.o: input.c - $(CC) -c $(CFLAGS)input.c + $(CC) $(CFLAGS) -c input.c -o input.o game.o: game.c - $(CC) -c $(CFLAGS) game.c + $(CC) $(CFLAGS) -c game.c -o game.o graphicalGame.o: graphicalGame.c - $(CC) -I$(raylib_folder) -c $(CFLAGS) graphicalGame.c + $(CC) $(CFLAGS) -c graphicalGame.c -o graphicalGame.o # -------------------------- # Unit Tests # -------------------------- TEST_BIN = runTests -test: input.o game.o unit_tests.c - $(CC) $(CFLAGS) -I$(unityfolder) -o $(TEST_BIN) input.o game.o unit_tests.c $(BINARIES)/libunity.a +unit_tests.o: unit_tests.c + $(CC) $(CFLAGS) -I$(unityfolder) -c unit_tests.c -o unit_tests.o + +test: input.o game.o unit_tests.o $(BINARIES)/libunity.a + $(CC) $(CFLAGS) -I$(unityfolder) -o $(TEST_BIN) input.o game.o unit_tests.o $(BINARIES)/libunity.a # -------------------------- # Clean diff --git a/Start_Windows/wordsalad.exe b/Start_Windows/wordsalad.exe new file mode 100644 index 0000000..f16d1f0 Binary files /dev/null and b/Start_Windows/wordsalad.exe differ