2025-11-06 14:42:16 +01:00

162 lines
6.6 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "game.h" // Enthält Definitionen wie MAX_SEARCH_FIELD_LEN und MAX_WORD_LEN
#include <time.h> // Für Zeitfunktionen, z.B. zur Initialisierung von Zufallszahlen
#include <stdlib.h> // Für rand(), malloc(), etc.
#include <string.h> // Für Stringfunktionen wie strnlen()
#include <ctype.h> // Für toupper(), um Buchstaben in Großbuchstaben umzuwandeln
#include <stdio.h> // Für printf(), um das Spielfeld auszugeben
#define MAX_RAND_TRIES_PER_WORD 10 // Maximale Anzahl zufälliger Platzierungsversuche pro Wort
#define EMPTY_CHAR 0 // Kennzeichnung für ein leeres Feld im Spielfeld
// Prüft, ob ein Wort an Position (x,y) in gegebener Richtung ins Spielfeld 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
// Prüfen, ob das Wort über den rechten Rand hinausgeht
if (x + wordLen > searchFieldLen) return 0;
// Prüfen, ob jedes Zeichen entweder leer ist oder bereits passt
for (unsigned int k = 0; k < wordLen; ++k) {
char c = (char)toupper((unsigned char)word[k]); // Zeichen in Großbuchstaben
char cell = salad[y][x + k]; // Aktuelles Feld
if (cell != EMPTY_CHAR && cell != c) return 0; // Konflikt → nicht platzierbar
}
} else { // vertikal
// Prüfen, ob das Wort über den unteren Rand hinausgeht
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; // Wort kann platziert werden
}
// Trägt ein Wort an Position (x,y) in gegebener Richtung ins Spielfeld 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]);
}
}
}
// Erstellt das Wortsuchfeld, platziert Wörter und füllt leere Felder mit Zufallsbuchstaben
// Rückgabewert: Anzahl der erfolgreich 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
if (searchFieldLen == 0 || searchFieldLen > MAX_SEARCH_FIELD_LEN) {
return 0;
}
// Initialisiere das Spielfeld mit EMPTY_CHAR
for (unsigned int r = 0; r < searchFieldLen; ++r) {
for (unsigned int c = 0; c < searchFieldLen; ++c) {
salad[r][c] = EMPTY_CHAR;
}
}
int placedCount = 0; // Zähler für erfolgreich platzierte Wörter
// Versuche, jedes Wort zu platzieren
for (unsigned int i = 0; i < wordCount; ++i) {
const char *word = words[i];
if (!word) continue;
size_t rawLen = strnlen(word, MAX_WORD_LEN); // Wortlänge ermitteln
if (rawLen == 0) continue;
unsigned int wordLen = (unsigned int)rawLen;
// Wenn das Wort zu lang ist, überspringen
if (wordLen > searchFieldLen) {
continue;
}
int placed = 0; // Flag, ob das Wort platziert wurde
// Zufällige Platzierungsversuche
for (int t = 0; t < MAX_RAND_TRIES_PER_WORD && !placed; ++t) {
int dir = rand() % 2; // Richtung zufällig wählen: 0 = horizontal, 1 = vertikal
// Berechnung der maximalen Startpositionen
unsigned int maxX = (dir == 0) ? (searchFieldLen - wordLen) : (searchFieldLen - 1);
unsigned int maxY = (dir == 1) ? (searchFieldLen - wordLen) : (searchFieldLen - 1);
// Zufällige Startposition innerhalb der Grenzen
unsigned int x = (maxX > 0) ? (unsigned int)(rand() % (maxX + 1)) : 0;
unsigned int y = (maxY > 0) ? (unsigned int)(rand() % (maxY + 1)) : 0;
// Prüfen und ggf. platzieren
if (canPlaceAt(salad, searchFieldLen, x, y, word, wordLen, dir)) {
placeAt(salad, x, y, word, wordLen, dir);
placed = 1;
}
}
// Fallback: systematische Suche, falls Zufall nicht funktioniert hat
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++; // Erfolgreich platziertes Wort zählen
}
// Nicht platzierbare Wörter werden ignoriert
}
// Fülle alle verbleibenden Felder mit zufälligen Buchstaben
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)); // Zufallsbuchstabe AZ
}
}
}
return placedCount; // Anzahl der platzierten Wörter zurückgeben
}
// Gibt das fertige Wortsuchfeld auf der Konsole aus
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) {
char ch = salad[r][c]; // Zeichen aus dem Feld
printf("%c ", ch); // Ausgabe mit Leerzeichen
}
printf("\n"); // Zeilenumbruch nach jeder Reihe
}
}