diff --git a/Wordsalat/game.c b/Wordsalat/game.c index e0f5a83..b5ba2a8 100644 --- a/Wordsalat/game.c +++ b/Wordsalat/game.c @@ -2,76 +2,94 @@ #include #include #include +#include #define MAX_RAND_TRIES_PER_WORD 10 #define EMPTY_CHAR 0 -//TODO: Spiellogik implementieren: -/* * Wörter aus der Wortliste zufällig horizontal oder vertikal platzieren - * restliche Felder mit zufälligen Buchstaben füllen */ +static int canPlace(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + const char *word, unsigned int len, + unsigned int row, unsigned int col, + unsigned int dRow, unsigned int dCol) +{ + for (unsigned int i = 0; i < len; i++) + { + char cell = salad[row + i * dRow][col + i * dCol]; + if (cell != EMPTY_CHAR && cell != (char)toupper((unsigned char)word[i])) + { + return 0; + } + } + return 1; +} + +static void placeWord(char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + const char *word, unsigned int len, + unsigned int row, unsigned int col, + unsigned int dRow, unsigned int dCol) +{ + for (unsigned int i = 0; i < len; i++) + { + salad[row + i * dRow][col + i * dCol] = (char)toupper((unsigned char)word[i]); + } +} -// 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) { - // Initialize the salad with empty characters - for (unsigned int i = 0; i < searchFieldLen; i++) { - for (unsigned int j = 0; j < searchFieldLen; j++) { - salad[i][j] = EMPTY_CHAR; - } - } - - // Seed the random number generator - srand((unsigned int)time(NULL)); - - // Place each word in the salad - for (unsigned int w = 0; w < wordCount; w++) { - const char *word = words[w]; - unsigned int wordLen = strlen(word); - int placed = 0; - - for (int tries = 0; tries < MAX_RAND_TRIES_PER_WORD && !placed; tries++) { - // Randomly choose orientation: 0 for horizontal, 1 for vertical - int orientation = rand() % 2; - unsigned int row, col; - - if (orientation == 0) { // Horizontal - row = rand() % searchFieldLen; - col = rand() % (searchFieldLen - wordLen + 1); - // Check if the space is free - int canPlace = 1; - for (unsigned int k = 0; k < wordLen; k++) { - if (salad[row][col + k] != EMPTY_CHAR) { - canPlace = 0; - break; - } - } - if (canPlace) { - for (unsigned int k = 0; k < wordLen; k++) { - salad[row][col + k] = word[k]; - } - placed = 1; - } - } else { // Vertical - row = rand() % (searchFieldLen - wordLen + 1); - col = rand() % searchFieldLen; - // Check if the space is free - int canPlace = 1; - for (unsigned int k = 0; k < wordLen; k++) { - if (salad[row + k][col] != EMPTY_CHAR) { - canPlace = 0; - break; - } - } - if (canPlace) { - for (unsigned int k = 0; k < wordLen; k++) { - salad[row + k][col] = word[k]; - } - placed = 1; - } - } - } - - if (!placed) { - return -1; // Failed to place the word after max tries - } -} + unsigned int placed = 0; + + srand((unsigned int)time(NULL)); + + for (unsigned int r = 0; r < searchFieldLen; r++) + { + for (unsigned int c = 0; c < searchFieldLen; c++) + { + salad[r][c] = EMPTY_CHAR; + } + } + + + for (unsigned int w = 0; w < wordCount; w++) + { + unsigned int len = (unsigned int)strlen(words[w]); + + if (len == 0 || len > searchFieldLen) + { + continue; + } + + for (unsigned int attempt = 0; attempt < MAX_RAND_TRIES_PER_WORD; attempt++) + { + int horizontal = rand() % 2; + unsigned int dRow = horizontal ? 0 : 1; + unsigned int dCol = horizontal ? 1 : 0; + + + unsigned int maxRow = searchFieldLen - (len - 1) * dRow; + unsigned int maxCol = searchFieldLen - (len - 1) * dCol; + unsigned int row = (unsigned int)rand() % maxRow; + unsigned int col = (unsigned int)rand() % maxCol; + + if (canPlace(salad, words[w], len, row, col, dRow, dCol)) + { + placeWord(salad, words[w], len, row, col, dRow, dCol); + placed++; + break; + } + } + } + + + 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); + } + } + } + + return (int)placed; +} \ No newline at end of file diff --git a/Wordsalat/game.o b/Wordsalat/game.o new file mode 100644 index 0000000..ab67b1f Binary files /dev/null and b/Wordsalat/game.o differ diff --git a/Wordsalat/graphicalGame.o b/Wordsalat/graphicalGame.o new file mode 100644 index 0000000..e75d53f Binary files /dev/null and b/Wordsalat/graphicalGame.o differ diff --git a/Wordsalat/input.c b/Wordsalat/input.c index 8116178..c22d81c 100644 --- a/Wordsalat/input.c +++ b/Wordsalat/input.c @@ -2,24 +2,46 @@ #include #include -// TODO: -// eine Funktion implementieren, die ein einzelnes Wort aus einer Textdatei (words.txt) einliest und als C-String zurückgibt. +// Trennzeichen, die in words.txt zwischen den Wörtern vorkommen +static int isDelimiter(int c) +{ + return c == ',' || c == ';' || isspace((unsigned char)c); +} // Read words from file and store in 'words' array int readWords(FILE *file, char words[][MAX_WORD_LEN], unsigned int maxWordCount) { - unsigned int wordCount = 0; - char buffer[MAX_WORD_LEN]; - - while (wordCount < maxWordCount && fscanf(file, "%s", buffer) == 1) { - - for (int i = 0; buffer[i]; i++) { - buffer[i] = tolower(buffer[i]); - } - strncpy(words[wordCount], buffer, MAX_WORD_LEN - 1); - words[wordCount][MAX_WORD_LEN - 1] = '\0'; - wordCount++; + if (file == NULL || words == NULL) + { + return 0; } - return wordCount; + unsigned int count = 0; + unsigned int len = 0; + int c; + + while (count < maxWordCount && (c = fgetc(file)) != EOF) + { + if (isDelimiter(c)) + { + if (len > 0) + { + words[count][len] = '\0'; + count++; + len = 0; + } + } + else if (len < MAX_WORD_LEN - 1) + { + words[count][len++] = (char)toupper((unsigned char)c); + } + } + + if (len > 0 && count < maxWordCount) + { + words[count][len] = '\0'; + count++; + } + + return (int)count; } \ No newline at end of file diff --git a/Wordsalat/input.o b/Wordsalat/input.o new file mode 100644 index 0000000..ca5932f Binary files /dev/null and b/Wordsalat/input.o differ diff --git a/Wordsalat/main.c b/Wordsalat/main.c index 03da755..5ca2839 100644 --- a/Wordsalat/main.c +++ b/Wordsalat/main.c @@ -6,45 +6,52 @@ #define MAX_NUMBER_OF_WORDS 100 #define SALAD_SIZE 20 +#define WINDOW_SIZE 700 int main(int argc, char *argv[]) { int exitCode = EXIT_SUCCESS; - // Check if the correct number of arguments is provided - if(argc != 2) + if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, "%s Textdatei mit angeben\n", argv[0]); exitCode = EXIT_FAILURE; } else { - char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LEN]; // Array to hold the words to be used in the game + char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LEN]; unsigned int wordCount = 0; FILE *file = fopen(argv[1], "r"); - if(file != NULL) + if (file != NULL) { unsigned int placedWords = 0; - char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; // 2D array to store the word salad + char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; - // Read words from file and store in 'words' array + wordCount = readWords(file, words, MAX_NUMBER_OF_WORDS); fclose(file); - // Create the word salad by placing words into grid + placedWords = createWordSalad(wordSalad, SALAD_SIZE, words, wordCount); - // TODO: - // Check if all words were successfully placed - // Start the game if successful - // error message if some words couldn't be placed - + + if (placedWords == wordCount) + { + + startGame(wordSalad, SALAD_SIZE, words, wordCount, WINDOW_SIZE); + } + else + { + + fprintf(stderr, "Only %u of %u words could be placed in the word salad.\n", placedWords, wordCount); + exitCode = EXIT_FAILURE; + } } else { - // Print error message if file couldn't be opened + fprintf(stderr, "Could not open file %s for reading ...\n", argv[1]); exitCode = EXIT_FAILURE; } diff --git a/Wordsalat/main.o b/Wordsalat/main.o new file mode 100644 index 0000000..6d4bb7e Binary files /dev/null and b/Wordsalat/main.o differ diff --git a/Wordsalat/runTests b/Wordsalat/runTests new file mode 100755 index 0000000..a556ba6 Binary files /dev/null and b/Wordsalat/runTests differ diff --git a/Wordsalat/wordsalad b/Wordsalat/wordsalad new file mode 100755 index 0000000..610d520 Binary files /dev/null and b/Wordsalat/wordsalad differ