From b7089376a1b07480d48156a6379813011b6e690e Mon Sep 17 00:00:00 2001 From: jw Date: Mon, 3 Nov 2025 16:27:59 +0100 Subject: [PATCH] Spiellogik fertig (Spiel komplett fertig) --- Start_Windows/game.c | 146 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 139 insertions(+), 7 deletions(-) diff --git a/Start_Windows/game.c b/Start_Windows/game.c index d8cc133..4cf2f99 100644 --- a/Start_Windows/game.c +++ b/Start_Windows/game.c @@ -2,22 +2,154 @@ #include #include #include +#include +#include #define MAX_RAND_TRIES_PER_WORD 10 #define EMPTY_CHAR 0 +// Prüft, ob ein Wort an (x,y) in gegebener Richtung passt. +// dir = 0 -> horizontal; dir = 1 -> vertikal +static int canPlaceAt(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int searchFieldLen, + unsigned int x, unsigned int y, + const char *word, unsigned int wordLen, + int dir) +{ + if (dir == 0) { // horizontal + if (x + wordLen > searchFieldLen) return 0; + for (unsigned int k = 0; k < wordLen; ++k) { + char c = (char)toupper((unsigned char)word[k]); + char cell = salad[y][x + k]; + if (cell != EMPTY_CHAR && cell != c) return 0; + } + } else { // vertikal + if (y + wordLen > searchFieldLen) return 0; + for (unsigned int k = 0; k < wordLen; ++k) { + char c = (char)toupper((unsigned char)word[k]); + char cell = salad[y + k][x]; + if (cell != EMPTY_CHAR && cell != c) return 0; + } + } + return 1; +} -//TODO: Spiellogik implementieren: -/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren - * restliche Felder mit zufälligen Buchstaben füllen */ +// Trägt ein Wort an (x,y) in gegebener Richtung ein +static void placeAt(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int x, unsigned int y, + const char *word, unsigned int wordLen, + int dir) +{ + if (dir == 0) { // horizontal + for (unsigned int k = 0; k < wordLen; ++k) { + salad[y][x + k] = (char)toupper((unsigned char)word[k]); + } + } else { // vertikal + for (unsigned int k = 0; k < wordLen; ++k) { + salad[y + k][x] = (char)toupper((unsigned char)word[k]); + } + } +} // 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) +// Rückgabewert: Anzahl der tatsächlich platzierten Wörter +int createWordSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int searchFieldLen, + const char words[][MAX_WORD_LEN], + unsigned int wordCount) { + // Ungültige Feldgröße -> nichts tun und 0 zurückgeben + if (searchFieldLen == 0 || searchFieldLen > MAX_SEARCH_FIELD_LEN) { + return 0; + } + // Feld initial mit EMPTY_CHAR füllen + for (unsigned int r = 0; r < searchFieldLen; ++r) { + for (unsigned int c = 0; c < searchFieldLen; ++c) { + salad[r][c] = EMPTY_CHAR; + } + } + + int placedCount = 0; + + // Für jedes Wort versuchen wir eine Platzierung + for (unsigned int i = 0; i < wordCount; ++i) { + const char *word = words[i]; + if (!word) continue; + + size_t rawLen = strnlen(word, MAX_WORD_LEN); + if (rawLen == 0) continue; + + unsigned int wordLen = (unsigned int)rawLen; + + // Wenn Wort länger als die Feldkante ist, passt es weder horizontal noch vertikal -> überspringen + if (wordLen > searchFieldLen) { + continue; + } + + int placed = 0; + + // Zufällige Versuche + for (int t = 0; t < MAX_RAND_TRIES_PER_WORD && !placed; ++t) { + int dir = rand() % 2; // 0=H, 1=V + + unsigned int maxX = (dir == 0) ? (searchFieldLen - wordLen) : (searchFieldLen - 1); + unsigned int maxY = (dir == 1) ? (searchFieldLen - wordLen) : (searchFieldLen - 1); + + unsigned int x = (maxX > 0) ? (unsigned int)(rand() % (maxX + 1)) : 0; + unsigned int y = (maxY > 0) ? (unsigned int)(rand() % (maxY + 1)) : 0; + + if (canPlaceAt(salad, searchFieldLen, x, y, word, wordLen, dir)) { + placeAt(salad, x, y, word, wordLen, dir); + placed = 1; + } + } + + // Fallback: deterministische Vollsuche + if (!placed) { + for (int dir = 0; dir < 2 && !placed; ++dir) { + unsigned int limitX = (dir == 0) ? (searchFieldLen - wordLen + 1) : searchFieldLen; + unsigned int limitY = (dir == 1) ? (searchFieldLen - wordLen + 1) : searchFieldLen; + + for (unsigned int y = 0; y < limitY && !placed; ++y) { + for (unsigned int x = 0; x < limitX && !placed; ++x) { + if (canPlaceAt(salad, searchFieldLen, x, y, word, wordLen, dir)) { + placeAt(salad, x, y, word, wordLen, dir); + placed = 1; + } + } + } + } + } + + if (placed) { + placedCount++; + } + // Nicht platzierbare Wörter werden einfach ignoriert (zählen nicht). + } + + // Restliche Felder **immer** mit Zufallsbuchstaben füllen, auch wenn 0 Wörter platziert wurden + 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)); + } + } + } + + // Anzahl der platzierten Wörter zurückgeben (Tests erwarten dies) + return placedCount; } // Prints the word salad to console -void showWordSalad(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen) +void showWordSalad(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int searchFieldLen) { - -} + for (unsigned int r = 0; r < searchFieldLen; ++r) { + for (unsigned int c = 0; c < searchFieldLen; ++c) { + // Da wir immer auffüllen, sollte hier nie EMPTY_CHAR erscheinen + char ch = salad[r][c]; + printf("%c ", ch); + } + printf("\n"); + } +} \ No newline at end of file