diff --git a/Startcode/game.c b/Startcode/game.c index 803301f..a3c8e5e 100644 --- a/Startcode/game.c +++ b/Startcode/game.c @@ -1,17 +1,93 @@ -#include "game.h" -#include -#include -#include -#define MAX_RAND_TRIES_PER_WORD 10 -#define EMPTY_CHAR 0 +#include "game.h" // Bindet die Definitionen fuer das Spielfeld ein. +#include // Stellt die Zufallsfunktion rand() bereit. +#include // Stellt die Funktion strlen() bereit. -//TODO: Spiellogik implementieren: -/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren - * restliche Felder mit zufälligen Buchstaben füllen */ +#define MAX_RAND_TRIES_PER_WORD 10 // Legt fest, wie oft eine Position versucht wird. +#define EMPTY_CHAR 0 // Kennzeichnet ein leeres Feld. -// 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) +int createWordSalad( // Erstellt das Spielfeld und gibt die Anzahl platzierter Woerter zurueck. + char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], // Speichert alle Buchstaben im Spielfeld. + unsigned int searchFieldLen, // Gibt die tatsaechliche Spielfeldgroesse an. + const char words[][MAX_WORD_LEN], // Enthaelt die einzutragenden Woerter. + unsigned int wordCount) // Gibt die Anzahl der Woerter an. { + if (searchFieldLen == 0 || searchFieldLen > MAX_SEARCH_FIELD_LEN) // Prueft die Spielfeldgroesse. + { + return 0; // Beendet die Funktion bei ungueltiger Groesse. + } + for (unsigned int row = 0; row < searchFieldLen; row++) // Durchlaeuft alle Zeilen. + { + for (unsigned int col = 0; col < searchFieldLen; col++) // Durchlaeuft alle Spalten. + { + salad[row][col] = EMPTY_CHAR; // Setzt jedes Feld auf leer. + } + } + + unsigned int placedWords = 0; // Zaehlt die erfolgreich platzierten Woerter. + + for (unsigned int w = 0; w < wordCount; w++) // Durchlaeuft alle Woerter aus der Wortliste. + { + unsigned int len = (unsigned int)strlen(words[w]); // Ermittelt die Laenge des aktuellen Wortes. + + if (len == 0 || len > searchFieldLen) // Prueft, ob das Wort in das Spielfeld passt. + { + continue; // Ueberspringt ein ungueltiges oder zu langes Wort. + } + + for (int attempt = 0; attempt < MAX_RAND_TRIES_PER_WORD; attempt++) // Versucht verschiedene Positionen. + { + int direction = rand() % 2; // Waehlt 0 fuer waagerecht oder 1 fuer senkrecht. + + unsigned int maxRow = direction == 0 ? searchFieldLen : searchFieldLen - len + 1; // Berechnet die Anzahl moeglicher Startzeilen. + unsigned int maxCol = direction == 0 ? searchFieldLen - len + 1 : searchFieldLen; // Berechnet die Anzahl moeglicher Startspalten. + + unsigned int row = (unsigned int)rand() % maxRow; // Bestimmt die zufaellige Startzeile. + unsigned int col = (unsigned int)rand() % maxCol; // Bestimmt die zufaellige Startspalte. + + int fits = 1; // Merkt sich, ob das Wort an dieser Position Platz hat. + + for (unsigned int i = 0; i < len; i++) // Prueft alle benoetigten Felder. + { + unsigned int r = row + (direction == 1 ? i : 0); // Berechnet die Zeile des aktuellen Buchstabens. + unsigned int c = col + (direction == 0 ? i : 0); // Berechnet die Spalte des aktuellen Buchstabens. + + if (salad[r][c] != EMPTY_CHAR) // Prueft, ob das Feld bereits belegt ist. + { + fits = 0; // Kennzeichnet die Position als ungeeignet. + break; // Bricht die Ueberpruefung dieser Position ab. + } + } + + if (fits == 1) // Fuehrt die Platzierung nur aus, wenn alle Felder frei sind. + { + for (unsigned int i = 0; i < len; i++) // Durchlaeuft alle Buchstaben des Wortes. + { + unsigned int r = row + (direction == 1 ? i : 0); // Berechnet die Zielzeile. + unsigned int c = col + (direction == 0 ? i : 0); // Berechnet die Zielspalte. + + salad[r][c] = words[w][i]; // Schreibt den Buchstaben in das Spielfeld. + } + + placedWords++; // Erhoeht die Anzahl der platzierten Woerter. + break; // Beendet die Versuche fuer dieses erfolgreich platzierte Wort. + } + } + } + + + for (unsigned int row = 0; row < searchFieldLen; row++) // Durchlaeuft alle Zeilen des Spielfeldes. + { + for (unsigned int col = 0; col < searchFieldLen; col++) // Durchlaeuft alle Spalten der aktuellen Zeile. + { + if (salad[row][col] == EMPTY_CHAR) // Prueft, ob das aktuelle Feld noch leer ist. + { + salad[row][col] = (char)('A' + rand() % 26); // Schreibt einen zufaelligen Grossbuchstaben von A bis Z. + } + } + } + + return (int)placedWords; // Gibt die Anzahl der erfolgreich platzierten Woerter zurueck. } + diff --git a/Startcode/input.c b/Startcode/input.c index ed77805..659a298 100644 --- a/Startcode/input.c +++ b/Startcode/input.c @@ -1,12 +1,71 @@ -#include "input.h" -#include -#include +#include "input.h" // Bindet die eigene Headerdatei mit den Konstanten ein. +#include // Stellt Funktionen wie strtok(), strlen() und strncpy() bereit. +#include // Stellt die Funktion toupper() zum Umwandeln in Grossbuchstaben bereit. +#include +#include -// TODO: -// eine Funktion implementieren, die ein einzelnes Wort aus einer Textdatei (words.txt) einliest und als C-String zurückgibt. - -// Read words from file and store in 'words' array -int readWords(FILE *file, char words[][MAX_WORD_LEN], unsigned int maxWordCount) +int readWords(FILE *file, char words[][MAX_WORD_LEN], unsigned int maxWordCount) // Liest Woerter aus einer Datei und gibt deren Anzahl zurueck. { + int count = 0; + /*Als Parameter fuer Words wird der Spaltenanzahl gegeben, der + bekannt werden muss, sonst ist die maximale Laenge des Wortes nicht eindeutig.*/ + + FILE *file_zeiger; + file_zeiger = fopen("words.txt", "r"); + /*Die Datei mit den Woertern wird geoeffnet.*/ + + if(file_zeiger == NULL){exit(1);}; + /*Code wird terminiert in dem Fall, dass die Datei nicht eingelesen werden kann.*/ + + char Text_Speicher[1000]; + /*1000 weil der .txt File offensichtlich weniger als 1000 Characters besitzt, + und passt somit in dieses Array.*/ + /*Wir speichern den Text in einen Array, sodass wir mit Zeigerarithmetik arbeiten + koennen, was fuer ein File-Pointer nicht geht. Z.B.: + (*fgets dereferenziert zeigt nicht auf das Character aus den Text auf der Addresse.) + (fgets ++ springt nicht auf die Addresse des naechsten Characters.)*/ + + int Lese_Ein = fread(Text_Speicher, 1, sizeof(Text_Speicher) - 1, file_zeiger); + Text_Speicher[Lese_Ein] = '\0'; + fclose(file_zeiger); + /*Wir kopieren die Textdatei ins Array.*/ + + char *fptr = Text_Speicher; + /*Weil man die Zeigerarithmetik nicht mit Text_Speicher machen kann.*/ + + if(fptr != NULL) + { + + /*Bis man bis zum letzten Platz in der Zeile eintragen kann*/ + while(*fptr != '\0' && count < maxWordCount) + { + while(*fptr == '\n' || *fptr == ',' || *fptr == ';' || *fptr == ' ' || *fptr == '\t' || *fptr == '\r') + { + fptr++; + } + + if(*fptr == '\0') break; /*Das wuerde heissen, dass man + schon ueber den letzten Element durchgelaufen hat.*/ + + + int char_Index = 0; + while(*fptr != '\n' && *fptr != ',' && *fptr != ';' && *fptr != ' ' && *fptr != '\t' && *fptr != '\0') + { + if (char_Index < MAX_WORD_LEN - 1) { + words[count][char_Index] = *fptr; + char_Index++; + /*char_Index++ = naechste Spalte*/ + } + fptr++; + /*geht auf die naechste Addresse.*/ + } + + /*Wir schliessen das Wort ab mit einem Null-Terminator.*/ + words[count][char_Index] = '\0'; + count++; /*naechste Zeile*/ + } +} + + return count; } \ No newline at end of file