#include "game.h" #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; } // 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 // 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) { 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"); } }