2025-11-02 19:16:27 +01:00

193 lines
6.9 KiB
C

//Bearbeitet von Lukas Wörner, 02.11.25
#include "game.h"
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define MAX_RAND_TRIES_PER_WORD 10
#define EMPTY_CHAR 0
//Position beinhaltet x, y und Richtung
//TODO: Spiellogik implementieren:
/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren
* restliche Felder mit zufälligen Buchstaben füllen */
// 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)
{
srand(time(NULL));
Position position[(2 * MAX_SEARCH_FIELD_LEN * (MAX_SEARCH_FIELD_LEN - MIN_WORD_LEN + 1))]; //Positionsarray Größe: Formel max. nötige Größe (für minimal großes wort)
int gesetzteWoerter = 0;
clearWordSalad(salad, searchFieldLen);
gesetzteWoerter = fuelleSalatMitWoertern(salad, searchFieldLen, words, position, wordCount);
fillWordsaladRand(salad, searchFieldLen);
return gesetzteWoerter;
}
// Prints the word salad to console
void showWordSalad(const char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen)
{
for(int i = 0; i < searchFieldLen; i++)
{
for(int k = 0; k < searchFieldLen; k++)
{
printf("%c", salad[i][k]);
}
printf("\n");
}
}
//Logik für createWordSalad:
/* Salat ist das Wortsalat Array.
1. Salat wird mit "." befüllt. Diese "." symbolisieren leere noch nicht befüllte Stellen
2. Für jedes Wort aus dem Wort - Array werden nacheinander mögliche Punkte gesucht, welche als Start um dieses Wort
ins Array zu schreiben funktionieren. Diese Positionen werden in einer struct gespeichert.
3. Für das Wort wird dann per Zufall aus den möglichen Positionen eine ausgewählt
4. Das Wort wird an der ausgewählten Position in den Salat geschrieben.
5. Dies passiert für alle Wörter. Gibt es keinen Platz mehr wird das Wort nicht in den Salat geschrieben
6. Restliche leere "." Stellen des Salats werden mit zufälligen Buchstaben befüllt
*/
//Funktion dafür den gesammten Salat mit . zu befüllen.
void clearWordSalad(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen)
{
for(unsigned int zeile = 0; zeile < searchFieldLen; zeile++)
{
for(unsigned int spalte = 0; spalte < searchFieldLen; spalte++)
{
salad[zeile][spalte] = '.'; // salad wird mit Punkten befüllt.
}
}
}
//Funktion für den Schluss: Übrige leere stellen werden random befüllt.
void fillWordsaladRand(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen)
{
for(int i = 0; i < searchFieldLen; i++)
{
for(int k = 0; k < searchFieldLen; k++)
{
if(salad[i][k] == '.')
{
salad[i][k] = 'A' + rand() % 26;
}
}
}
}
//hierbei: alle Positionen werden zunächst geprüft ob leer (.) danach wird nach rechts und nach unten geschaut ob:
//a.) genügend Platz wäre, dass nicht aus dem array herausgeschrieben wird und
//b.) alle zu besetzenden Felder leer sind (.).
//Positionamount gibt aus wie viele mögliche Positionen es für dieses Wort gibt.
//Wird mit 0 initialisiert. Wenns null bleibt, bedeutet dies es gibt keine verfügbaren Positionen.
//rechtsfrei und untenfrei werden für jeden Position neu auf 1 initialisiert. Trifft a.) oder b.) nicht zu auf null gesetzt
int findPossiblePositions(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], int wordidx, Position positions[])
{
const char *word = words[wordidx];
int wordlen = strlen(word);
int positionamount = 0;
int rechtsfrei = 1;
int untenfrei = 1;
for(int i = 0; i < searchFieldLen; i++)
{
for(int k = 0; k < searchFieldLen; k++)
{
rechtsfrei = 1;
untenfrei = 1;
if(salad[i][k] == '.')
{
//nach rechts prüfen
if(searchFieldLen - k >= wordlen)
{
for(int p = k +1; p < k+ wordlen; p++)
{
if(salad[i][p] != '.')
{
rechtsfrei = 0;
break;
}
}
}
else
{
rechtsfrei = 0;
}
//nach unten prüfen
if(searchFieldLen - i >= wordlen)
{
for(int q = i+1; q < i+ wordlen; q++)
{
if(salad[q][k] != '.')
{
untenfrei = 0;
break;
}
}
}
else
{
untenfrei = 0;
}
if(rechtsfrei) //Positions array wird mit gültigen Positionen und Richtung befüllt.
{
positions[positionamount].x = k;
positions[positionamount].y = i;
positions[positionamount].richtung = RECHTS;
positionamount++;
}
if(untenfrei)
{
positions[positionamount].x = k;
positions[positionamount].y = i;
positions[positionamount].richtung = UNTEN;
positionamount++;
}
}
}
}
return positionamount;
}
//Nun muss für jedes Wort per zufall ausgesucht werden Wo es beginnt und welche richtung aus
//den ganzen möglichen fällen und dann das wort ins grid gezeichnet werden.
int fuelleSalatMitWoertern(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldLen, const char words[][MAX_WORD_LEN], Position position[], unsigned int wordcount)
{
int gesetzteWoerter = 0;
int positionsamount;
int positiongewaehlt;
const char *word;
for(int i = 0; i < wordcount; i++) //jedes Wort.
{
positionsamount = findPossiblePositions(salad, searchFieldLen, words, i, position); //für dieses Wort werden die Positionen gefunden
if(positionsamount > 0)//es gibt Positionen
{
gesetzteWoerter++;
positiongewaehlt = rand() % positionsamount; //die wie vielte Position des Positionsarrays für dieses Wort wir nehmen
if(position[positiongewaehlt].richtung == RECHTS)
{
word = words[i];
int p = position[positiongewaehlt].x;
int t = 0;
for(int k = p; k < p + strlen(word); k++)
{
salad[position[positiongewaehlt].y][k] = word[t];
t++;
}
}
if(position[positiongewaehlt].richtung == UNTEN)
{
word = words[i];
int up = position[positiongewaehlt].y;
int ut = 0;
for(int uk = up; uk < up +strlen(word); uk++)
{
salad[uk][position[positiongewaehlt].x] = word[ut];
ut++;
}
}
}
}
return gesetzteWoerter;
}