diff --git a/Start_Linux/unit_tests.c b/Start_Linux/unit_tests.c index d1a15f5..cd72392 100644 --- a/Start_Linux/unit_tests.c +++ b/Start_Linux/unit_tests.c @@ -1,104 +1,105 @@ -#include -#include -#include #include "unity.h" +#include +#include +#include -#include "input.h" #include "game.h" +#include "input.h" // ANSI Escape Codes für Farben -// Hinweis: damit das in CLion mit der integrierten Konsole/Output funktioniert, muss man auf die Run-Config gehen und -// das Häkchen bei 'emulate terminal in the output console' setzen -// (s. auch: https://stackoverflow.com/questions/32742850/how-to-show-colored-console-output-in-clion) -#define RESET "\033[0m" -#define GREEN "\033[32m" -#define RED "\033[31m" -#define YELLOW "\033[33m" -#define CYAN "\033[36m" -#define BOLD "\033[1m" +// Hinweis: damit das in CLion mit der integrierten Konsole/Output funktioniert, +// muss man auf die Run-Config gehen und das Häkchen bei 'emulate terminal in +// the output console' setzen (s. auch: +// https://stackoverflow.com/questions/32742850/how-to-show-colored-console-output-in-clion) +#define RESET "\033[0m" +#define GREEN "\033[32m" +#define RED "\033[31m" +#define YELLOW "\033[33m" +#define CYAN "\033[36m" +#define BOLD "\033[1m" // Eine Funktion, um die Test-Ergebnisse zu färben void print_test_result(int result) { - if (result == 0) { - // Test war erfolgreich - printf(GREEN "OK\n" RESET); - } else { - // Test ist fehlgeschlagen - printf(RED "FAILED\n" RESET); - } + if (result == 0) { + // Test war erfolgreich + printf(GREEN "OK\n" RESET); + } else { + // Test ist fehlgeschlagen + printf(RED "FAILED\n" RESET); + } } // ---------- Tests für input.c ---------- void test_readWords_simple(void) { - FILE *f = fopen("testwords_simple.txt", "r"); + FILE *f = fopen("testwords_simple.txt", "r"); - char words[10][MAX_WORD_LEN]; - int count = readWords(f, words, 10); - fclose(f); + char words[10][MAX_WORD_LEN]; + int count = readWords(f, words, 10); + fclose(f); - TEST_ASSERT_EQUAL_INT(3, count); - TEST_ASSERT_EQUAL_STRING("APFEL", words[0]); - TEST_ASSERT_EQUAL_STRING("BANANE", words[1]); - TEST_ASSERT_EQUAL_STRING("KIWI", words[2]); + TEST_ASSERT_EQUAL_INT(3, count); + TEST_ASSERT_EQUAL_STRING("APFEL", words[0]); + TEST_ASSERT_EQUAL_STRING("BANANE", words[1]); + TEST_ASSERT_EQUAL_STRING("KIWI", words[2]); } void test_readWords_with_delimiters(void) { - FILE *f = fopen("testwords_delims.txt", "r"); + FILE *f = fopen("testwords_delims.txt", "r"); - char words[10][MAX_WORD_LEN]; - int count = readWords(f, words, 10); - fclose(f); + char words[10][MAX_WORD_LEN]; + int count = readWords(f, words, 10); + fclose(f); - TEST_ASSERT_EQUAL_INT(3, count); - TEST_ASSERT_EQUAL_STRING("HUND", words[0]); - TEST_ASSERT_EQUAL_STRING("KATZE", words[1]); - TEST_ASSERT_EQUAL_STRING("MAUS", words[2]); + TEST_ASSERT_EQUAL_INT(3, count); + TEST_ASSERT_EQUAL_STRING("HUND", words[0]); + TEST_ASSERT_EQUAL_STRING("KATZE", words[1]); + TEST_ASSERT_EQUAL_STRING("MAUS", words[2]); } void test_readWords_empty_file(void) { - FILE *f = fopen("testwords_empty.txt", "r"); + FILE *f = fopen("testwords_empty.txt", "r"); - char words[10][MAX_WORD_LEN]; - int count = readWords(f, words, 10); - fclose(f); + char words[10][MAX_WORD_LEN]; + int count = readWords(f, words, 10); + fclose(f); - TEST_ASSERT_EQUAL_INT(0, count); + TEST_ASSERT_EQUAL_INT(0, count); } // ---------- Tests für game.c ---------- void test_createWordSalad_all_fit(void) { - char words[3][MAX_WORD_LEN] = {"CAT", "DOG", "MOUSE"}; - char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; + char words[3][MAX_WORD_LEN] = {"CAT", "DOG", "MOUSE"}; + char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; - int placed = createWordSalad(salad, 20, words, 3); + int placed = createWordSalad(salad, 20, words, 3); - TEST_ASSERT_EQUAL_INT(3, placed); + TEST_ASSERT_EQUAL_INT(3, placed); - // Sicherstellen, dass alle Felder gefüllt sind - for (int i = 0; i < 20; i++) { - for (int j = 0; j < 20; j++) { - TEST_ASSERT_GREATER_OR_EQUAL('A', salad[i][j]); - TEST_ASSERT_LESS_OR_EQUAL('Z', salad[i][j]); - } + // Sicherstellen, dass alle Felder gefüllt sind + for (int i = 0; i < 20; i++) { + for (int j = 0; j < 20; j++) { + TEST_ASSERT_GREATER_OR_EQUAL('A', salad[i][j]); + TEST_ASSERT_LESS_OR_EQUAL('Z', salad[i][j]); } + } } void test_createWordSalad_too_small(void) { - char words[2][MAX_WORD_LEN] = {"ELEPHANT", "GIRAFFE"}; - char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; + char words[2][MAX_WORD_LEN] = {"ELEPHANT", "GIRAFFE"}; + char salad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; - int placed = createWordSalad(salad, 5, words, 2); + int placed = createWordSalad(salad, 5, words, 2); - TEST_ASSERT_GREATER_OR_EQUAL(0, placed); - TEST_ASSERT_LESS_OR_EQUAL(2, placed); + TEST_ASSERT_GREATER_OR_EQUAL(0, placed); + TEST_ASSERT_LESS_OR_EQUAL(2, placed); - // Feld muss vollständig gefüllt sein - for (int i = 0; i < 5; i++) { - for (int j = 0; j < 5; j++) { - TEST_ASSERT_GREATER_OR_EQUAL('A', salad[i][j]); - TEST_ASSERT_LESS_OR_EQUAL('Z', salad[i][j]); - } + // Feld muss vollständig gefüllt sein + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + TEST_ASSERT_GREATER_OR_EQUAL('A', salad[i][j]); + TEST_ASSERT_LESS_OR_EQUAL('Z', salad[i][j]); } + } } // ---------- Test Setup und TearDown Funktionen ---------- @@ -106,37 +107,37 @@ void test_createWordSalad_too_small(void) { // falls Vor- und Nachbereitungen für die Tests benötigt. void setUp(void) { - FILE *f = fopen("testwords_delims.txt", "w"); - fprintf(f, "Hund,Katze; Maus\n"); - fclose(f); + FILE *f = fopen("testwords_delims.txt", "w"); + fprintf(f, "Hund,Katze; Maus\n"); + fclose(f); - f = fopen("testwords_simple.txt", "w"); - fprintf(f, "Apfel\nBanane\nKiwi"); - fclose(f); + f = fopen("testwords_simple.txt", "w"); + fprintf(f, "Apfel\nBanane\nKiwi"); + fclose(f); - f = fopen("testwords_empty.txt", "w"); - fclose(f); + f = fopen("testwords_empty.txt", "w"); + fclose(f); } void tearDown(void) { - remove("testwords_delims.txt"); - remove("testwords_simple.txt"); - remove("testwords_empty.txt"); + remove("testwords_delims.txt"); + remove("testwords_simple.txt"); + remove("testwords_empty.txt"); } // ---------- Test Runner ---------- int main(void) { - UNITY_BEGIN(); + UNITY_BEGIN(); - RUN_TEST(test_readWords_simple); - RUN_TEST(test_readWords_with_delimiters); - RUN_TEST(test_readWords_empty_file); - RUN_TEST(test_createWordSalad_all_fit); - RUN_TEST(test_createWordSalad_too_small); + RUN_TEST(test_readWords_simple); + RUN_TEST(test_readWords_with_delimiters); + RUN_TEST(test_readWords_empty_file); + RUN_TEST(test_createWordSalad_all_fit); + RUN_TEST(test_createWordSalad_too_small); - int result = UNITY_END(); // Test-Ergebnisse - print_test_result(result); + int result = UNITY_END(); // Test-Ergebnisse + print_test_result(result); - return result; + return result; } \ No newline at end of file diff --git a/Start_Windows/graphicalGame.c b/Start_Windows/graphicalGame.c index fc648b6..7b708bf 100644 --- a/Start_Windows/graphicalGame.c +++ b/Start_Windows/graphicalGame.c @@ -7,449 +7,467 @@ #define MAX_MESSAGE_LEN 256 #define MAX_SOLUTION_WORD_LEN 16 -typedef struct -{ - Vector2 startPosition; - Vector2 endPosition; - int isSelected; +typedef struct { + Vector2 startPosition; + Vector2 endPosition; + int isSelected; } MouseSelection; -typedef struct -{ - Vector2 position; - char character[2]; - int isMarked; +typedef struct { + Vector2 position; + char character[2]; + int isMarked; } CharSquare; -typedef struct -{ - CharSquare *squares; - unsigned int count; - unsigned int squareSize; - unsigned int fontSize; - Vector2 position; - Vector2 size; +typedef struct { + CharSquare *squares; + unsigned int count; + unsigned int squareSize; + unsigned int fontSize; + Vector2 position; + Vector2 size; } CharSquarePanel; -typedef struct -{ - char content[MAX_WORD_LEN]; - char *solution; - Vector2 position; - int wasFound; +typedef struct { + char content[MAX_WORD_LEN]; + char *solution; + Vector2 position; + int wasFound; } SearchWord; -typedef struct -{ - SearchWord *words; - unsigned int count; - int fontSize; - Vector2 position; - Vector2 size; +typedef struct { + SearchWord *words; + unsigned int count; + int fontSize; + Vector2 position; + Vector2 size; } SearchWordPanel; -typedef struct -{ - char content[MAX_MESSAGE_LEN]; - Vector2 position; - unsigned int size; +typedef struct { + char content[MAX_MESSAGE_LEN]; + Vector2 position; + unsigned int size; } WinMessage; -typedef struct -{ - char text[MAX_MESSAGE_LEN]; - Vector2 position; - Vector2 size; - unsigned int fontSize; +typedef struct { + char text[MAX_MESSAGE_LEN]; + Vector2 position; + Vector2 size; + unsigned int fontSize; } HelperMessage; // Creates a helper message to guide the user -static HelperMessage createHelperMessage(unsigned int screenWidth) -{ - const char *text = "Please search below for the words located at the bottom \nand draw a line exactly on the desired characters ..."; - HelperMessage msg = {"", {0, 0}, {screenWidth, 0}, 18}; +static HelperMessage createHelperMessage(unsigned int screenWidth) { + const char *text = "Please search below for the words located at the bottom " + "\nand draw a line exactly on the desired characters ..."; + HelperMessage msg = {"", {0, 0}, {screenWidth, 0}, 18}; - // Copy text into msg, ensuring does not exceed max length - strncpy(msg.text, text, MAX_MESSAGE_LEN); - msg.text[MAX_MESSAGE_LEN-1] = '\0'; + // Copy text into msg, ensuring does not exceed max length + strncpy(msg.text, text, MAX_MESSAGE_LEN); + msg.text[MAX_MESSAGE_LEN - 1] = '\0'; - // Set the vertical size based on font size - msg.size.y = 3 * msg.fontSize; + // Set the vertical size based on font size + msg.size.y = 3 * msg.fontSize; - return msg; + return msg; } // Creates a winning message when the user wins -static WinMessage createWinMessage(unsigned int screenSize) -{ - WinMessage winMsg; - char *text = "Congratulations! You won!"; +static WinMessage createWinMessage(unsigned int screenSize) { + WinMessage winMsg; + char *text = "Congratulations! You won!"; - strncpy(winMsg.content, text, MAX_MESSAGE_LEN); - winMsg.content[MAX_MESSAGE_LEN-1] = '\0'; - winMsg.size = 30; // Set font size + strncpy(winMsg.content, text, MAX_MESSAGE_LEN); + winMsg.content[MAX_MESSAGE_LEN - 1] = '\0'; + winMsg.size = 30; // Set font size - // Calculate x and y positions for centering the message - winMsg.position.x = (screenSize - strlen(winMsg.content)*winMsg.size*0.52) / 2; - winMsg.position.y = screenSize / 2; + // Calculate x and y positions for centering the message + winMsg.position.x = + (screenSize - strlen(winMsg.content) * winMsg.size * 0.52) / 2; + winMsg.position.y = screenSize / 2; - return winMsg; + return winMsg; } // Frees memory associated with a search word panel -static void freeSearchWordPanel(SearchWordPanel *panel) -{ - for(int i = 0; panel->words != NULL && i < panel->count; i++) - free(panel->words[i].solution); // Free solution strings - free(panel->words); // Free word array - panel->words = NULL; - panel->count = 0; - panel->size.x = 0; - panel->size.y = 0; +static void freeSearchWordPanel(SearchWordPanel *panel) { + for (int i = 0; panel->words != NULL && i < panel->count; i++) + free(panel->words[i].solution); // Free solution strings + free(panel->words); // Free word array + panel->words = NULL; + panel->count = 0; + panel->size.x = 0; + panel->size.y = 0; } // Creates a panel to display a list of search words -static SearchWordPanel createSearchWordPanel(const char words[][MAX_WORD_LEN], unsigned int numberOfWords, unsigned int windowOffset) -{ - const int maxStringLenInPx = 200; // Max width of each word - const int fontSize = 18; // Font size for displaying words - const int rowHeight = fontSize * 1.2 + 5; // Height of each row of words +static SearchWordPanel createSearchWordPanel(const char words[][MAX_WORD_LEN], + unsigned int numberOfWords, + unsigned int windowOffset) { + const int maxStringLenInPx = 200; // Max width of each word + const int fontSize = 18; // Font size for displaying words + const int rowHeight = fontSize * 1.2 + 5; // Height of each row of words - SearchWordPanel panel = {NULL, 0, fontSize, {0, windowOffset}, {windowOffset, 0}}; + SearchWordPanel panel = { + NULL, 0, fontSize, {0, windowOffset}, {windowOffset, 0}}; - unsigned int xOffset = 5; - unsigned int yOffset = 15; + unsigned int xOffset = 5; + unsigned int yOffset = 15; - // Allocate memory for words if any are present - if(numberOfWords > 0) - panel.words = (SearchWord *)malloc(sizeof(SearchWord) * numberOfWords); + // Allocate memory for words if any are present + if (numberOfWords > 0) + panel.words = (SearchWord *)malloc(sizeof(SearchWord) * numberOfWords); - // If memory allocation is successful - if(panel.words != NULL) - { - // Loop through and set up the words and their positions - for(int i = 0; i < numberOfWords; i++) - { - strncpy(panel.words[i].content, words[i], MAX_SOLUTION_WORD_LEN); - panel.words[i].content[MAX_SOLUTION_WORD_LEN-1] = '\0'; + // If memory allocation is successful + if (panel.words != NULL) { + // Loop through and set up the words and their positions + for (int i = 0; i < numberOfWords; i++) { + strncpy(panel.words[i].content, words[i], MAX_SOLUTION_WORD_LEN); + panel.words[i].content[MAX_SOLUTION_WORD_LEN - 1] = '\0'; - // Truncate word if exceeds max length - if(strlen(words[i]) > MAX_SOLUTION_WORD_LEN-1) - strncpy(panel.words[i].content+MAX_SOLUTION_WORD_LEN-4, "...", 4); + // Truncate word if exceeds max length + if (strlen(words[i]) > MAX_SOLUTION_WORD_LEN - 1) + strncpy(panel.words[i].content + MAX_SOLUTION_WORD_LEN - 4, "...", 4); - // Allocate memory for solution word - panel.words[i].solution = (char *)malloc(sizeof(char) * (strlen(words[i]) + 1)); + // Allocate memory for solution word + panel.words[i].solution = + (char *)malloc(sizeof(char) * (strlen(words[i]) + 1)); - if(panel.words[i].solution != NULL) - strcpy(panel.words[i].solution, words[i]); - else - { - freeSearchWordPanel(&panel); // Free memory in case of failure - numberOfWords = 0; - break; - } + if (panel.words[i].solution != NULL) + strcpy(panel.words[i].solution, words[i]); + else { + freeSearchWordPanel(&panel); // Free memory in case of failure + numberOfWords = 0; + break; + } - panel.words[i].wasFound = 0; // Initialize "found" flag - panel.words[i].position.x = xOffset; - panel.words[i].position.y = yOffset; + panel.words[i].wasFound = 0; // Initialize "found" flag + panel.words[i].position.x = xOffset; + panel.words[i].position.y = yOffset; - // Move to next position for next word - xOffset += maxStringLenInPx + 5; + // Move to next position for next word + xOffset += maxStringLenInPx + 5; - // Move to next row if needed - if(xOffset > windowOffset) - { - xOffset = 5; - yOffset += rowHeight; - } - } - panel.count = numberOfWords; // Sets total word count - - // Adjust panel size based on last word's position - if(numberOfWords > 0) - panel.size.y = panel.words[numberOfWords - 1].position.y + rowHeight; + // Move to next row if needed + if (xOffset > windowOffset) { + xOffset = 5; + yOffset += rowHeight; + } } + panel.count = numberOfWords; // Sets total word count - return panel; + // Adjust panel size based on last word's position + if (numberOfWords > 0) + panel.size.y = panel.words[numberOfWords - 1].position.y + rowHeight; + } + + return panel; } // Creates a square for a character in the search grid -static CharSquare createSquare(unsigned int rowIdx, unsigned int colIdx, char character, unsigned int squareSize) -{ - CharSquare square; - square.position.x = colIdx * squareSize; - square.position.y = rowIdx * squareSize; - square.character[0] = character; - square.character[1] = '\0'; - square.isMarked = 0; // Mark as unmarked initially +static CharSquare createSquare(unsigned int rowIdx, unsigned int colIdx, + char character, unsigned int squareSize) { + CharSquare square; + square.position.x = colIdx * squareSize; + square.position.y = rowIdx * squareSize; + square.character[0] = character; + square.character[1] = '\0'; + square.isMarked = 0; // Mark as unmarked initially - return square; + return square; } // Creates a panel of character squares (the search grid) -static CharSquarePanel createCharSquarePanel(const char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldSizeInChars, int panelSizeInPx) -{ - CharSquarePanel squarePanel; - squarePanel.squares = (CharSquare *)malloc(sizeof(CharSquare) * searchFieldSizeInChars * searchFieldSizeInChars); - squarePanel.count = 0; - squarePanel.squareSize = (double)panelSizeInPx / searchFieldSizeInChars; // Calculate the square size - squarePanel.fontSize = squarePanel.squareSize * 0.75; // Set font size relative to square size - squarePanel.position.x = 0; - squarePanel.position.y = 0; - squarePanel.size.x = panelSizeInPx; - squarePanel.size.y = panelSizeInPx; +static CharSquarePanel createCharSquarePanel( + const char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int searchFieldSizeInChars, int panelSizeInPx) { + CharSquarePanel squarePanel; + squarePanel.squares = (CharSquare *)malloc( + sizeof(CharSquare) * searchFieldSizeInChars * searchFieldSizeInChars); + squarePanel.count = 0; + squarePanel.squareSize = (double)panelSizeInPx / + searchFieldSizeInChars; // Calculate the square size + squarePanel.fontSize = + squarePanel.squareSize * 0.75; // Set font size relative to square size + squarePanel.position.x = 0; + squarePanel.position.y = 0; + squarePanel.size.x = panelSizeInPx; + squarePanel.size.y = panelSizeInPx; - // If memory for squares is allocated successfully loop through grid and create squares for each character - if(squarePanel.squares != NULL) - { - for(int i = 0; i < searchFieldSizeInChars; i++) - { - for(int j = 0; j < searchFieldSizeInChars; j++) - { - squarePanel.squares[squarePanel.count] = createSquare(i, j, wordSalad[i][j], squarePanel.squareSize); - squarePanel.count++; - } - } + // If memory for squares is allocated successfully loop through grid and + // create squares for each character + if (squarePanel.squares != NULL) { + for (int i = 0; i < searchFieldSizeInChars; i++) { + for (int j = 0; j < searchFieldSizeInChars; j++) { + squarePanel.squares[squarePanel.count] = + createSquare(i, j, wordSalad[i][j], squarePanel.squareSize); + squarePanel.count++; + } } + } - return squarePanel; + return squarePanel; } // Frees memory associated with CharSquarePanel -static void freeCharSquarePanel(CharSquarePanel *squarePanel) -{ - free(squarePanel->squares); // Free squares array - squarePanel->squares = NULL; - squarePanel->count = 0; // Reset count +static void freeCharSquarePanel(CharSquarePanel *squarePanel) { + free(squarePanel->squares); // Free squares array + squarePanel->squares = NULL; + squarePanel->count = 0; // Reset count } // Draws all squares of CharSquarePanel -static void drawSquares(const CharSquarePanel squarePanel) -{ - float fontOffset = squarePanel.squareSize / 4; // Offset for font positioning +static void drawSquares(const CharSquarePanel squarePanel) { + float fontOffset = squarePanel.squareSize / 4; // Offset for font positioning - // Loop through all squares and draw them - for(int i = 0; i < squarePanel.count; i++) - { - CharSquare square = squarePanel.squares[i]; + // Loop through all squares and draw them + for (int i = 0; i < squarePanel.count; i++) { + CharSquare square = squarePanel.squares[i]; - Vector2 squareScreenCoord = {squarePanel.position.x + square.position.x, squarePanel.position.y + square.position.y}; - Color squareColor = DARKBLUE; - Color fontColor = LIGHTGRAY; + Vector2 squareScreenCoord = {squarePanel.position.x + square.position.x, + squarePanel.position.y + square.position.y}; + Color squareColor = DARKBLUE; + Color fontColor = LIGHTGRAY; - // Change colors if is marked - if(square.isMarked) - { - squareColor = GREEN; - fontColor = BLACK; - } - - // Draw square and its border - DrawRectangle(squareScreenCoord.x, squareScreenCoord.y, squarePanel.squareSize, squarePanel.squareSize, squareColor); - for(int i = 1; i <= 3; i++) - DrawRectangleLines(squareScreenCoord.x, squareScreenCoord.y, squarePanel.squareSize-i, squarePanel.squareSize-i, LIGHTGRAY); - - // Draw character inside the square - DrawText(square.character, squareScreenCoord.x + fontOffset, squareScreenCoord.y + fontOffset, squarePanel.fontSize, fontColor); + // Change colors if is marked + if (square.isMarked) { + squareColor = GREEN; + fontColor = BLACK; } + + // Draw square and its border + DrawRectangle(squareScreenCoord.x, squareScreenCoord.y, + squarePanel.squareSize, squarePanel.squareSize, squareColor); + for (int i = 1; i <= 3; i++) + DrawRectangleLines(squareScreenCoord.x, squareScreenCoord.y, + squarePanel.squareSize - i, squarePanel.squareSize - i, + LIGHTGRAY); + + // Draw character inside the square + DrawText(square.character, squareScreenCoord.x + fontOffset, + squareScreenCoord.y + fontOffset, squarePanel.fontSize, fontColor); + } } // Checks if selected word is valid solution -static int isSolution(const char *solution, SearchWordPanel searchWordPanel) -{ - for(int i = 0; i < searchWordPanel.count; i++) - if(strcmp(solution, searchWordPanel.words[i].solution) == 0) - { - // Mark word as found and return true if solution matches - searchWordPanel.words[i].wasFound = 1; - return 1; - } +static int isSolution(const char *solution, SearchWordPanel searchWordPanel) { + for (int i = 0; i < searchWordPanel.count; i++) + if (strcmp(solution, searchWordPanel.words[i].solution) == 0) { + // Mark word as found and return true if solution matches + searchWordPanel.words[i].wasFound = 1; + return 1; + } - return 0; // false if not found + return 0; // false if not found } // Updates the marked squares based on user selection -static void updateSelectedSquares(const MouseSelection selection, CharSquarePanel squarePanel, SearchWordPanel searchWordPanel) -{ - unsigned int wordIdx = 0; - char selectedWord[MAX_WORD_LEN]; - unsigned int selectedIdx[squarePanel.count]; - float radius = squarePanel.squareSize / 2; +static void updateSelectedSquares(const MouseSelection selection, + CharSquarePanel squarePanel, + SearchWordPanel searchWordPanel) { + unsigned int wordIdx = 0; + char selectedWord[MAX_WORD_LEN]; + unsigned int selectedIdx[squarePanel.count]; + float radius = squarePanel.squareSize / 2; - // Loop through all squares and check if selected - for(int i = 0; i < squarePanel.count && wordIdx < MAX_WORD_LEN-1; i++) - { - Vector2 center = {squarePanel.squares[i].position.x + squarePanel.position.x, squarePanel.squares[i].position.y + squarePanel.position.y}; - center.x += radius; - center.y += radius; + // Loop through all squares and check if selected + for (int i = 0; i < squarePanel.count && wordIdx < MAX_WORD_LEN - 1; i++) { + Vector2 center = { + squarePanel.squares[i].position.x + squarePanel.position.x, + squarePanel.squares[i].position.y + squarePanel.position.y}; + center.x += radius; + center.y += radius; - // Check if square is selected by mouse - if(CheckCollisionCircleLine(center, radius, selection.startPosition, selection.endPosition)) - { - selectedWord[wordIdx] = squarePanel.squares[i].character[0]; - selectedIdx[wordIdx] = i; - wordIdx++; - } + // Check if square is selected by mouse + if (CheckCollisionCircleLine(center, radius, selection.startPosition, + selection.endPosition)) { + selectedWord[wordIdx] = squarePanel.squares[i].character[0]; + selectedIdx[wordIdx] = i; + wordIdx++; } - selectedWord[wordIdx] = '\0'; + } + selectedWord[wordIdx] = '\0'; - // If selected word is a solution, mark it - if(isSolution(selectedWord, searchWordPanel)) - { - for(int i = 0; i < wordIdx; i++) - squarePanel.squares[selectedIdx[i]].isMarked = 1; - } + // If selected word is a solution, mark it + if (isSolution(selectedWord, searchWordPanel)) { + for (int i = 0; i < wordIdx; i++) + squarePanel.squares[selectedIdx[i]].isMarked = 1; + } } // Handles mouse input for selecting words in grid -static void handleMouseInput(MouseSelection *selection, CharSquarePanel squarePanel, SearchWordPanel searchWordPanel) -{ - if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) // Start new selection - { - selection->startPosition = GetMousePosition(); - selection->endPosition = selection->startPosition; - selection->isSelected = 1; - } - else if(IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) // End selection - { - updateSelectedSquares(*selection, squarePanel, searchWordPanel); +static void handleMouseInput(MouseSelection *selection, + CharSquarePanel squarePanel, + SearchWordPanel searchWordPanel) { + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) // Start new selection + { + selection->startPosition = GetMousePosition(); + selection->endPosition = selection->startPosition; + selection->isSelected = 1; + } else if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) // End selection + { + updateSelectedSquares(*selection, squarePanel, searchWordPanel); - selection->isSelected = 0; - } - else if(IsMouseButtonDown(MOUSE_BUTTON_LEFT)) // Update end position while selecting - { - selection->endPosition = GetMousePosition(); - } + selection->isSelected = 0; + } else if (IsMouseButtonDown( + MOUSE_BUTTON_LEFT)) // Update end position while selecting + { + selection->endPosition = GetMousePosition(); + } } // Draws selection line on screen if selection is active -static void drawSelection(const MouseSelection selection) -{ - if(selection.isSelected) - { - DrawLine(selection.startPosition.x, selection.startPosition.y, selection.endPosition.x, selection.endPosition.y, WHITE); - } +static void drawSelection(const MouseSelection selection) { + if (selection.isSelected) { + DrawLine(selection.startPosition.x, selection.startPosition.y, + selection.endPosition.x, selection.endPosition.y, WHITE); + } } // Draws search word panel (list of words to be found) -static void drawSearchWordPanel(SearchWordPanel searchWordPanel) -{ - for(int i = 0; i < searchWordPanel.count; i++) - { - Vector2 wordScreenCoord = {searchWordPanel.words[i].position.x + searchWordPanel.position.x, searchWordPanel.words[i].position.y + searchWordPanel.position.y}; - DrawText(searchWordPanel.words[i].content, wordScreenCoord.x, wordScreenCoord.y, searchWordPanel.fontSize, WHITE); +static void drawSearchWordPanel(SearchWordPanel searchWordPanel) { + for (int i = 0; i < searchWordPanel.count; i++) { + Vector2 wordScreenCoord = { + searchWordPanel.words[i].position.x + searchWordPanel.position.x, + searchWordPanel.words[i].position.y + searchWordPanel.position.y}; + DrawText(searchWordPanel.words[i].content, wordScreenCoord.x, + wordScreenCoord.y, searchWordPanel.fontSize, WHITE); - // If word has been found, highlight it - if(searchWordPanel.words[i].wasFound) - { - int xOffset = MeasureText(searchWordPanel.words[i].content, searchWordPanel.fontSize); - for(int i = 0; i <= 3; i++) - DrawLine(wordScreenCoord.x - 3, wordScreenCoord.y + 5 + i, wordScreenCoord.x + xOffset + 3, wordScreenCoord.y + 5 + i, GREEN); - } + // If word has been found, highlight it + if (searchWordPanel.words[i].wasFound) { + int xOffset = MeasureText(searchWordPanel.words[i].content, + searchWordPanel.fontSize); + for (int i = 0; i <= 3; i++) + DrawLine(wordScreenCoord.x - 3, wordScreenCoord.y + 5 + i, + wordScreenCoord.x + xOffset + 3, wordScreenCoord.y + 5 + i, + GREEN); } + } } // Draws helper message (instructions or tips for user) -static void drawHelperMessage(const HelperMessage msg) -{ - DrawRectangle(msg.position.x, msg.position.y, msg.size.x, msg.size.y, BLACK); // Background for message - DrawText(msg.text, msg.position.x + 5, msg.position.y + 5, msg.fontSize, WHITE); // Display message text +static void drawHelperMessage(const HelperMessage msg) { + DrawRectangle(msg.position.x, msg.position.y, msg.size.x, msg.size.y, + BLACK); // Background for message + DrawText(msg.text, msg.position.x + 5, msg.position.y + 5, msg.fontSize, + WHITE); // Display message text } -// Draws the entire game content, including helper message, squares, and search words -static void drawGameContent(const HelperMessage helperMsg, const CharSquarePanel squarePanel, const MouseSelection selection, const SearchWordPanel searchWordPanel) -{ - drawHelperMessage(helperMsg); - drawSquares(squarePanel); - drawSearchWordPanel(searchWordPanel); - drawSelection(selection); +// Draws the entire game content, including helper message, squares, and search +// words +static void drawGameContent(const HelperMessage helperMsg, + const CharSquarePanel squarePanel, + const MouseSelection selection, + const SearchWordPanel searchWordPanel) { + drawHelperMessage(helperMsg); + drawSquares(squarePanel); + drawSearchWordPanel(searchWordPanel); + drawSelection(selection); } // Draws success message when player wins -static void drawSuccessContent(WinMessage msg) -{ - unsigned int textWidth = MeasureText(msg.content, msg.size); - DrawRectangle(msg.position.x-20, msg.position.y-20, textWidth+40, msg.size+40, GREEN); // Background for success message +static void drawSuccessContent(WinMessage msg) { + unsigned int textWidth = MeasureText(msg.content, msg.size); + DrawRectangle(msg.position.x - 20, msg.position.y - 20, textWidth + 40, + msg.size + 40, GREEN); // Background for success message - for(int i = 0; i < 5; i++) // Draw borders around success message - DrawRectangleLines(msg.position.x-20+i, msg.position.y-20+i, textWidth+40-i*2, msg.size+40-i*2, WHITE); + for (int i = 0; i < 5; i++) // Draw borders around success message + DrawRectangleLines(msg.position.x - 20 + i, msg.position.y - 20 + i, + textWidth + 40 - i * 2, msg.size + 40 - i * 2, WHITE); - DrawText(msg.content, msg.position.x, msg.position.y, msg.size, WHITE); // Display success text + DrawText(msg.content, msg.position.x, msg.position.y, msg.size, + WHITE); // Display success text } -// Draws entire game screen, including game content and success message if applicable -static void drawAll(const CharSquarePanel squarePanel, const MouseSelection selection, const SearchWordPanel searchWordPanel, const HelperMessage helperMsg, const WinMessage msg, int hasWon) -{ - BeginDrawing(); - ClearBackground(BLACK); // Clear screen with a black background - drawGameContent(helperMsg, squarePanel, selection, searchWordPanel); // Draw game content +// Draws entire game screen, including game content and success message if +// applicable +static void drawAll(const CharSquarePanel squarePanel, + const MouseSelection selection, + const SearchWordPanel searchWordPanel, + const HelperMessage helperMsg, const WinMessage msg, + int hasWon) { + BeginDrawing(); + ClearBackground(BLACK); // Clear screen with a black background + drawGameContent(helperMsg, squarePanel, selection, + searchWordPanel); // Draw game content - if(hasWon) // If player has won, draw success message - drawSuccessContent(msg); + if (hasWon) // If player has won, draw success message + drawSuccessContent(msg); - EndDrawing(); + EndDrawing(); } // Checks if all words in the search word panel have been found -static int allWordsFound(SearchWordPanel searchWordPanel) -{ - // Loop through all words and check if any is not found - for(int i = 0; i < searchWordPanel.count; i++) - if(!searchWordPanel.words[i].wasFound) - return 0; // Return false if any word is not found - return 1; // Return true if all words are found +static int allWordsFound(SearchWordPanel searchWordPanel) { + // Loop through all words and check if any is not found + for (int i = 0; i < searchWordPanel.count; i++) + if (!searchWordPanel.words[i].wasFound) + return 0; // Return false if any word is not found + return 1; // Return true if all words are found } // Main game loop where game is run and updated -static void gameLoop(const Vector2 screenSize, MouseSelection mouseSelection, CharSquarePanel squarePanel, SearchWordPanel searchWordPanel, const HelperMessage helperMsg, const WinMessage winMsg) -{ - InitWindow(screenSize.x, screenSize.y, "Word Salad"); // Initialize game window +static void gameLoop(const Vector2 screenSize, MouseSelection mouseSelection, + CharSquarePanel squarePanel, + SearchWordPanel searchWordPanel, + const HelperMessage helperMsg, const WinMessage winMsg) { + InitWindow(screenSize.x, screenSize.y, + "Word Salad"); // Initialize game window - SetTargetFPS(60); + SetTargetFPS(60); - while (!WindowShouldClose()) // Keep running until window is closed - { - handleMouseInput(&mouseSelection, squarePanel, searchWordPanel); // Handle mouse input (selection) + while (!WindowShouldClose()) // Keep running until window is closed + { + handleMouseInput(&mouseSelection, squarePanel, + searchWordPanel); // Handle mouse input (selection) - // Draw all game content including helper message, squares, and search word panel - drawAll(squarePanel, mouseSelection, searchWordPanel, helperMsg, winMsg, allWordsFound(searchWordPanel)); - } + // Draw all game content including helper message, squares, and search word + // panel + drawAll(squarePanel, mouseSelection, searchWordPanel, helperMsg, winMsg, + allWordsFound(searchWordPanel)); + } - CloseWindow(); + CloseWindow(); } -// Initializes and starts game, setting up necessary elements and entering game loop -void startGame(const char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], unsigned int searchFieldSize, char words[][MAX_WORD_LEN], unsigned int numberOfWords, unsigned int windowSize) -{ - const int windowWidth = windowSize; +// Initializes and starts game, setting up necessary elements and entering game +// loop +void startGame(const char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN], + unsigned int searchFieldSize, char words[][MAX_WORD_LEN], + unsigned int numberOfWords, unsigned int windowSize) { + const int windowWidth = windowSize; - Vector2 screenSize; + Vector2 screenSize; - // Create necessary game elements like helper message, square panel, and search word panel - HelperMessage helperMsg = createHelperMessage(windowWidth); - CharSquarePanel squarePanel = createCharSquarePanel(wordSalad, searchFieldSize, windowWidth); - SearchWordPanel searchWordPanel = createSearchWordPanel(words, numberOfWords, windowWidth); - WinMessage winMsg = createWinMessage(windowWidth); + // Create necessary game elements like helper message, square panel, and + // search word panel + HelperMessage helperMsg = createHelperMessage(windowWidth); + CharSquarePanel squarePanel = + createCharSquarePanel(wordSalad, searchFieldSize, windowWidth); + SearchWordPanel searchWordPanel = + createSearchWordPanel(words, numberOfWords, windowWidth); + WinMessage winMsg = createWinMessage(windowWidth); - MouseSelection mouseSelection; + MouseSelection mouseSelection; - mouseSelection.isSelected = 0; // Initialize mouse selection to not be active + mouseSelection.isSelected = 0; // Initialize mouse selection to not be active - // Adjust panel positions - squarePanel.position.y = helperMsg.size.y; - searchWordPanel.position.y = helperMsg.size.y + squarePanel.size.y; + // Adjust panel positions + squarePanel.position.y = helperMsg.size.y; + searchWordPanel.position.y = helperMsg.size.y + squarePanel.size.y; - // Set screen size based on the panels' sizes - screenSize.x = squarePanel.size.x; - screenSize.y = helperMsg.size.y + squarePanel.size.y + searchWordPanel.size.y; + // Set screen size based on the panels' sizes + screenSize.x = squarePanel.size.x; + screenSize.y = helperMsg.size.y + squarePanel.size.y + searchWordPanel.size.y; - // Start game loop - gameLoop(screenSize, mouseSelection, squarePanel, searchWordPanel, helperMsg, winMsg); + // Start game loop + gameLoop(screenSize, mouseSelection, squarePanel, searchWordPanel, helperMsg, + winMsg); - // Free up allocated memory when game is done - freeCharSquarePanel(&squarePanel); - freeSearchWordPanel(&searchWordPanel); + // Free up allocated memory when game is done + freeCharSquarePanel(&squarePanel); + freeSearchWordPanel(&searchWordPanel); } /*gcc -fPIC -c input.c game.c graphicalGame.c main.c -gcc -shared -o libwortsalat.a input.o game.o graphicalGame.o main.o*/ \ No newline at end of file +gcc -shared -o libwordsalad.a input.o game.o graphicalGame.o main.o*/ \ No newline at end of file diff --git a/Start_Windows/main.c b/Start_Windows/main.c index 03da755..74024e1 100644 --- a/Start_Windows/main.c +++ b/Start_Windows/main.c @@ -1,54 +1,63 @@ -#include -#include -#include "input.h" #include "game.h" #include "graphicalGame.h" +#include "input.h" +#include +#include #define MAX_NUMBER_OF_WORDS 100 #define SALAD_SIZE 20 -int main(int argc, char *argv[]) -{ - int exitCode = EXIT_SUCCESS; +int main(int argc, char *argv[]) { + int exitCode = EXIT_SUCCESS; - // Check if the correct number of arguments is provided - if(argc != 2) - { - fprintf(stderr, "Usage: %s \n", argv[0]); + // Check if the correct number of arguments is provided + if (argc != 2) { + fprintf(stderr, "Usage: %s \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 + unsigned int wordCount = 0; + + FILE *file = fopen(argv[1], "r"); + + if (file != NULL) { + unsigned int placedWords = 0; + char wordSalad[MAX_SEARCH_FIELD_LEN] + [MAX_SEARCH_FIELD_LEN]; // 2D array to store the word salad + + // 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, + MAX_SEARCH_FIELD_LEN); + } + + else + + { + // Print error message if words couldn't be placed + // evtl noch richtigen error code einfügen + fprintf(stderr, "Could not place words...\n"); 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; } - else - { - char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LEN]; // Array to hold the words to be used in the game - unsigned int wordCount = 0; + } - FILE *file = fopen(argv[1], "r"); - - if(file != NULL) - { - unsigned int placedWords = 0; - char wordSalad[MAX_SEARCH_FIELD_LEN][MAX_SEARCH_FIELD_LEN]; // 2D array to store the word salad - - // 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 - - } - 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; - } - } - - return exitCode; + return exitCode; } \ No newline at end of file diff --git a/Start_Windows/makefile b/Start_Windows/makefile index 146a8c6..efc0b0e 100644 --- a/Start_Windows/makefile +++ b/Start_Windows/makefile @@ -12,6 +12,14 @@ unityfolder = ./unity wordsalad_initial: $(CC) -o wordsalad_initial $(BINARIES)/libwordsalad_complete.a $(BINARIES)/libraylib.a $(LDFLAGS) +#--------------------------- +# eigenes Target bauen +#--------------------------- + + +wordsalad_myversion: + $(CC) -o wordsalad_myversion main.o $(BINARIES)/libwordsalad.a $(BINARIES)/libraylib.a $(LDFLAGS) + # -------------------------- # Normales Spiel bauen diff --git a/Start_Windows/windows/libwordsalad.a b/Start_Windows/windows/libwordsalad.a index 55ba658..06a447c 100644 Binary files a/Start_Windows/windows/libwordsalad.a and b/Start_Windows/windows/libwordsalad.a differ diff --git a/Start_Windows/windows/libwordsalad_complete.a b/Start_Windows/windows/libwordsalad_complete.a deleted file mode 100644 index 817f48e..0000000 Binary files a/Start_Windows/windows/libwordsalad_complete.a and /dev/null differ diff --git a/test.c b/test.c deleted file mode 100644 index e69de29..0000000