diff --git a/Startcode/game.c b/Startcode/game.c index 803301f..098f225 100644 --- a/Startcode/game.c +++ b/Startcode/game.c @@ -6,12 +6,150 @@ #define MAX_RAND_TRIES_PER_WORD 10 #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 */ +// Hilfsfunktion: Sichere Längenermittlung mit Obergrenze +static size_t safeStrnlen(const char *str, size_t maxLen) +{ + size_t len = 0; + while (len < maxLen && str[len] != '\0') + { + len++; + } + return len; +} -// Creates the word salad by placing words randomly and filling empty spaces +// Hilfsfunktion: Prüft kollisionsfrei, ob ein Wort an die Position passt +// Arraygrößen (fieldLen, wordLen) werden explizit als Parameter übergeben + +static int canPlaceWord(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int fieldLen, + const char *word, + unsigned int wordLen, + unsigned int row, + unsigned int col, + int isVertical) +{ + for (unsigned int k = 0; k < wordLen; k++) + { + unsigned int r = isVertical ? (row + k) : row; + unsigned int c = isVertical ? col : (col + k); + // Überlaufschutz: Innerhalb der Arraygrenzen bleiben + if (r >= fieldLen || c >= fieldLen) + { + return 0; + } + char cell = salad[r][c]; + if (cell != EMPTY_CHAR && cell != word[k]) + { + return 0; // Kollision mit einem anderen Buchstaben + } + } + return 1; +} + +// Hilfsfunktion: Schreibt das Wort in das Spielfeld +// Arraygrößen (fieldLen, wordLen) werden explizit als Parameter übergeben +static void placeWord(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int fieldLen, + const char *word, + unsigned int wordLen, + unsigned int row, + unsigned int col, + int isVertical) +{ + for (unsigned int k = 0; k < wordLen; k++) + { + unsigned int r = isVertical ? (row + k) : row; + unsigned int c = isVertical ? col : (col + k); + if (r < fieldLen && c < fieldLen) + { + salad[r][c] = word[k]; + } + } +} + +// Erzeugt Wortsalat und platziert leere Felder mit random Buchstaben int createWordSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], unsigned int wordCount) { - -} + // Sicherheitsprüfung der übergebenen Parameter + if (salad == NULL || words == NULL || searchFieldLen == 0 || searchFieldLen > MAX_SEARCH_FIELD_LEN) + { + return -1; + } + // Zufallsgenerator initialisieren + static int seeded = 0; + if (!seeded) + { + srand((unsigned int)time(NULL)); + seeded = 1; + } + // 1. Spielfeld komplett mit EMPTY_CHAR leeren + for (unsigned int r = 0; r < searchFieldLen; r++) + { + for (unsigned int c = 0; c < searchFieldLen; c++) + { + salad[r][c] = EMPTY_CHAR; + } + } + // Sicherer lokaler Puffer für strncpy + char currentWord[MAX_WORD_LEN]; + // 2. Wörter platzieren +for (unsigned int i = 0; i < wordCount; i++) + { + // Wort sicher mit strncpy kopieren und terminieren + memset(currentWord, 0, sizeof(currentWord)); + strncpy(currentWord, words[i], MAX_WORD_LEN - 1); + currentWord[MAX_WORD_LEN - 1] = '\0'; + unsigned int wordLen = (unsigned int)safeStrnlen(currentWord, MAX_WORD_LEN); + if (wordLen == 0) + { + continue; + } + // Falls das Wort länger als das Spielfeld ist, abbrechen + if (wordLen > searchFieldLen) + { + return -1; + } + int placed = 0; + for (int attempt = 0; attempt < MAX_RAND_TRIES_PER_WORD; attempt++) + { + // Richtung würfeln: 0 = Horizontal, 1 = Vertikal + int isVertical = rand() % 2; + unsigned int row = 0; + unsigned int col = 0; + if (isVertical) + { + row = rand() % (searchFieldLen - wordLen + 1); + col = rand() % searchFieldLen; + } + else + { + row = rand() % searchFieldLen; + col = rand() % (searchFieldLen - wordLen + 1); + } + // Prüfen, ob das Wort passt, und platzieren + if (canPlaceWord(salad, searchFieldLen, currentWord, wordLen, row, col, isVertical)) + { + placeWord(salad, searchFieldLen, currentWord, wordLen, row, col, isVertical); + placed = 1; + break; + } + } + // Wenn das Wort nach MAX_RAND_TRIES_PER_WORD Versuchen nicht platziert werden konnte + if (!placed) + { + return -1; + } + } + // 3. Restliche Felder mit zufälligen Großbuchstaben ('A'-'Z') füllen + for (unsigned int r = 0; r < searchFieldLen; r++) + { + for (unsigned int c = 0; c < searchFieldLen; c++) + { + if (salad[r][c] == EMPTY_CHAR) + { + salad[r][c] = (char)('A' + (rand() % 26)); + } + } + } + return 0; // Erfolg +} \ No newline at end of file