Spiellogik fertig (Spiel komplett fertig)

This commit is contained in:
jw 2025-11-03 16:27:59 +01:00
parent a0523f0ad3
commit b7089376a1

View File

@ -2,22 +2,154 @@
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#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");
}
}