diff --git a/.clang-format b/.clang-format index 81dd40c..b5b7878 100644 --- a/.clang-format +++ b/.clang-format @@ -1,3 +1,4 @@ --- BasedOnStyle: Google +ColumnLimit: 100 IndentWidth: 4 diff --git a/.github/translations/es/README.md b/.github/translations/es/README.md index d872a90..d569bd2 100644 --- a/.github/translations/es/README.md +++ b/.github/translations/es/README.md @@ -96,12 +96,17 @@ C-Practical-Work-2024/ │ ├── main.h │ ├── utilities.c │ ├── utilities.h +│ ├── validators.c +│ ├── validators.h | | -│ └── cells/ +│ └── patterns/ │ ├── constructors.c │ ├── constructors.h +│ ├── macros.h +│ ├── main.h │ ├── methods.c -│ └── methods.h +│ ├── methods.h +│ └── structs.h | ├── .clang-format ├── .gitignore @@ -131,13 +136,18 @@ C-Practical-Work-2024/ - **[main.h](./libs/main.h)** - Archivo que indexa todos los archivos `.h` del proyecto. - **[utilities.c](./libs/utilities.c)** - Archivo con el desarrollo de los prototipos de función presentes en `utilities.h`. - **[utilities.h](./libs/utilities.h)** - Archivo con las estructuras y los prototipos de función de uso común. - - - **[cells](./libs/cells)** - Funciones y estructuras de las entidades `células`. - - - **[constructors.c](./libs/cells/constructors.c)** - Archivo con el desarrollo de los prototipos de función presentes en `constructors.h`. - - **[constructors.h](./libs/cells/constructors.h)** - Archivo con las estructuras y los prototipos de función relacionados a la creación de células. - - **[methods.c](./libs/cells/methods.c)** - Archivo con el desarrollo de los prototipos de función presentes en `methods.h`. - - **[methods.h](./libs/cells/methods.h)** - Archivo con los prototipos de función relacionados a los métodos de las células. + - **[validators.c](./libs/validators.c)** - Archivo con el desarrollo de los prototipos de función presentes en `validators.h`. + - **[validators.h](./libs/validators.h)** - Archivo con prototipos de funciones relacionadas con procesos de validación. + + - **[patterns](./libs/patterns)** - Funciones y estructuras para crear patrones con células. + + - **[constructors.c](./libs/patterns/constructors.c)** - Archivo con el desarrollo de los prototipos de función presentes en `constructors.h`. + - **[constructors.h](./libs/patterns/constructors.h)** - Archivo con las estructuras y los prototipos de función relacionados a la creación de patrones. + - **[macros.h](./libs/macros.h)** - Archivo con macros. + - **[main.h](./libs/main.h)** - Archivo que indexa todos los archivos `.h` dentro de la carpeta `patterns`. + - **[methods.c](./libs/patterns/methods.c)** - Archivo con el desarrollo de los prototipos de función presentes en `methods.h`. + - **[methods.h](./libs/patterns/methods.h)** - Archivo con los prototipos de función relacionados a los métodos de los patrones. + - **[structs.h](./libs/patterns/methods.h)** - Archivo con estructuras. - **[.clang-format](./.clang-format)** - Archivo de configuración de la herramienta de formateo de código `clang-format`. - **[.gitignore](./.gitignore)** - Archivo de configuración de Git para evitar el rastreo de archivos no deseados. diff --git a/.github/workflows/format-code-on-pr.yml b/.github/workflows/format-code-on-pr.yml new file mode 100644 index 0000000..ab6698b --- /dev/null +++ b/.github/workflows/format-code-on-pr.yml @@ -0,0 +1,39 @@ +name: 'Format code on pull request' + +on: + pull_request: + branches: + - Master + - develop + paths: + - '**.c' + - '**.h' + +jobs: + clang-format: + name: Format code + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{github.head_ref}} + + - name: Install clang-format (formatter tool) + run: sudo apt-get install clang-format + + - name: Run clang-format + run: find . -name '*.c' -o -name '*.h' | xargs clang-format -i -style=file + + - name: Commit changes + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + git add . + git diff-index --quiet HEAD || git commit -m "ci: format code" + + - name: Push changes + uses: ad-m/github-push-action@v0.8.0 + with: + branch: ${{ github.head_ref }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml index fffce3d..c5491d2 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -1,13 +1,6 @@ name: 'Format code' on: - pull_request: - branches: - - Master - - develop - paths: - - '**.c' - - '**.h' push: branches: - Master diff --git a/.gitignore b/.gitignore index ff22e18..e0a470c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,12 @@ +# ---------------------------------------------------------------------------- # +# PERSONAL FILES # +# ---------------------------------------------------------------------------- # + +personal-*.md + + + # ---------------------------------------------------------------------------- # # CODEBLOCKS # # ---------------------------------------------------------------------------- # diff --git a/.vscode/settings.json b/.vscode/settings.json index cf91a17..2d4db68 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,8 +10,6 @@ "editor.minimap.renderCharacters": false, "emojisense.unicodeCompletionsEnabled": false, "files.associations": {"*.c": "c", "*.h": "c"}, - "files.autoSave": "afterDelay", - "files.autoSaveDelay": 1000, "files.trimTrailingWhitespace": true, "markdown-preview-github-styles.colorTheme": "dark", "terminal.integrated.defaultProfile.windows": "Command Prompt", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index cf870fc..11adeae 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -14,9 +14,10 @@ { "command": [ "(gcc -Wall -O2 -pedantic-errors -c \"${workspaceFolder}\\libs\\utilities.c\" -o \"${workspaceFolder}\\libs\\obj\\Release\\utilities.o\")", - "& (gcc -Wall -O2 -pedantic-errors -c \"${workspaceFolder}\\libs\\cells\\constructors.c\" -o \"${workspaceFolder}\\libs\\obj\\Release\\constructors.o\")", - "& (gcc -Wall -O2 -pedantic-errors -c \"${workspaceFolder}\\libs\\cells\\methods.c\" -o \"${workspaceFolder}\\libs\\obj\\Release\\methods.o\")", - "& (ar -r -s \"${workspaceFolder}\\libs\\bin\\Release\\libs.a\" \"${workspaceFolder}\\libs\\obj\\Release\\constructors.o\" \"${workspaceFolder}\\libs\\obj\\Release\\methods.o\" \"${workspaceFolder}\\libs\\obj\\Release\\utilities.o\")" + "& (gcc -Wall -O2 -pedantic-errors -c \"${workspaceFolder}\\libs\\validators.c\" -o \"${workspaceFolder}\\libs\\obj\\Release\\validators.o\")", + "& (gcc -Wall -O2 -pedantic-errors -c \"${workspaceFolder}\\libs\\patterns\\constructors.c\" -o \"${workspaceFolder}\\libs\\obj\\Release\\constructors.o\")", + "& (gcc -Wall -O2 -pedantic-errors -c \"${workspaceFolder}\\libs\\patterns\\methods.c\" -o \"${workspaceFolder}\\libs\\obj\\Release\\methods.o\")", + "& (ar -r -s \"${workspaceFolder}\\libs\\bin\\Release\\libs.a\" \"${workspaceFolder}\\libs\\obj\\Release\\constructors.o\" \"${workspaceFolder}\\libs\\obj\\Release\\methods.o\" \"${workspaceFolder}\\libs\\obj\\Release\\utilities.o\" \"${workspaceFolder}\\libs\\obj\\Release\\validators.o\")" ], "group": {"kind": "build", "isDefault": false}, "label": "Compile libs project", diff --git a/README.md b/README.md index 8fcfc75..fcc8e35 100644 --- a/README.md +++ b/README.md @@ -96,12 +96,17 @@ C-Practical-Work-2024/ │ ├── main.h │ ├── utilities.c │ ├── utilities.h +│ ├── validators.c +│ ├── validators.h | | -│ └── cells/ +│ └── patterns/ │ ├── constructors.c │ ├── constructors.h +│ ├── macros.h +│ ├── main.h │ ├── methods.c -│ └── methods.h +│ ├── methods.h +│ └── structs.h | ├── .clang-format ├── .gitignore @@ -131,13 +136,18 @@ C-Practical-Work-2024/ - **[main.h](./libs/main.h)** - File indexing all `.h` files of the project. - **[utilities.c](./libs/utilities.c)** - File with the implementation of the function prototypes found in `utilities.h`. - **[utilities.h](./libs/utilities.h)** - File with common structures and function prototypes. - - - **[cells](./libs/cells)** - Functions and structures for `cell` entities. - - - **[constructors.c](./libs/cells/constructors.c)** - File with the implementation of the function prototypes found in `constructors.h`. - - **[constructors.h](./libs/cells/constructors.h)** - File with structures and function prototypes related to cell creation. - - **[methods.c](./libs/cells/methods.c)** - File with the implementation of the function prototypes found in `methods.h`. - - **[methods.h](./libs/cells/methods.h)** - File with function prototypes related to cell methods. + - **[validators.c](./libs/validators.c)** - File with the implementation of the function prototypes found in `validators.h`. + - **[validators.h](./libs/validators.h)** - File with functions prototypes related to validation process. + + - **[patterns](./libs/patterns)** - Functions and structures for create patterns with cells. + + - **[constructors.c](./libs/patterns/constructors.c)** - File with the implementation of the function prototypes found in `constructors.h`. + - **[constructors.h](./libs/patterns/constructors.h)** - File with structures and function prototypes related to patterns creation. + - **[macros.h](./libs/macros.h)** - File with macros. + - **[main.h](./libs/main.h)** - File indexing all `.h` files inside `patterns` folder. + - **[methods.c](./libs/patterns/methods.c)** - File with the implementation of the function prototypes found in `methods.h`. + - **[methods.h](./libs/patterns/methods.h)** - File with function prototypes related to pattern methods. + - **[structs.h](./libs/patterns/methods.h)** - File with structs. - **[.clang-format](./.clang-format)** - Configuration file for the `clang-format` code formatting tool. - **[.gitignore](./.gitignore)** - Git configuration file to avoid tracking unwanted files. diff --git a/libs/cells/constructors.c b/libs/cells/constructors.c deleted file mode 100644 index 2cd85c5..0000000 --- a/libs/cells/constructors.c +++ /dev/null @@ -1,2 +0,0 @@ - -void emptyFn() {} diff --git a/libs/cells/constructors.h b/libs/cells/constructors.h deleted file mode 100644 index 8afd726..0000000 --- a/libs/cells/constructors.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef CONSTRUCTORS_H_INCLUDED -#define CONSTRUCTORS_H_INCLUDED - -#endif // CONSTRUCTORS_H_INCLUDED diff --git a/libs/cells/methods.c b/libs/cells/methods.c deleted file mode 100644 index 2cd85c5..0000000 --- a/libs/cells/methods.c +++ /dev/null @@ -1,2 +0,0 @@ - -void emptyFn() {} diff --git a/libs/cells/methods.h b/libs/cells/methods.h deleted file mode 100644 index b57b27e..0000000 --- a/libs/cells/methods.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef METHODS_H_INCLUDED -#define METHODS_H_INCLUDED - -#endif // METHODS_H_INCLUDED diff --git a/libs/libs.cbp b/libs/libs.cbp index 170146e..10c077c 100644 --- a/libs/libs.cbp +++ b/libs/libs.cbp @@ -34,20 +34,27 @@ - + + + - - + + + + - - - + + + + + diff --git a/libs/macros.h b/libs/macros.h index eb1dd4f..c611743 100644 --- a/libs/macros.h +++ b/libs/macros.h @@ -1,4 +1,59 @@ + #ifndef MACROS_H_INCLUDED #define MACROS_H_INCLUDED +/** + * @def DASHBOARD_ROWS + * @brief Defines the number of rows in a grid. + * + * This macro is used to define the number of rows in a grid. + * It is typically used in conjunction with the `DASHBOARD_COLS` macro to define + * the size of a grid. + * + * @warning The value of `DASHBOARD_ROWS` must be a positive integer. + */ +#define DASHBOARD_ROWS 56 + +/** + * @def DASHBOARD_COLS + * @brief Defines the number of columns in a grid. + * + * This macro is used to define the number of columns in a grid. + * It is typically used in conjunction with the `DASHBOARD_ROWS` macro to define + * the size of a grid. + * + * @warning The value of `DASHBOARD_COLS` must be a positive integer. + */ +#define DASHBOARD_COLS 110 + +/** + * @def MAXIMUM_DELAY + * @brief Defines the maximum delay in milliseconds. + * + * This macro is used to define the maximum delay for a delay input. + * It is typically used in conjunction with the `MINIMUM_DELAY`. + * + * @warning The value of `MAXIMUM_DELAY` must be a positive integer. + */ +#define MAXIMUM_DELAY 1000 + +/** + * @def MINIMUM_DELAY + * @brief Defines the minimum delay in milliseconds. + * + * This macro is used to define the minimum delay for a delay input. + * It is typically used in conjunction with the `MAXIMUM_DELAY`. + * + * @warning The value of `MINIMUM_DELAY` must be a positive integer. + */ +#define MINIMUM_DELAY 0 + +/** + * @def NEIGHBORHOOD_RADIUS + * @brief Defines the radius of the neighborhood. + * + * @warning The value of `NEIGHBORHOOD_RADIUS` must be greater or equal to 1. + */ +#define NEIGHBORHOOD_RADIUS 1 + #endif // MACROS_H_INCLUDED diff --git a/libs/main.h b/libs/main.h index 292e27f..d7b1f1b 100644 --- a/libs/main.h +++ b/libs/main.h @@ -1,12 +1,13 @@ + #ifndef MAIN_H_INCLUDED #define MAIN_H_INCLUDED // Root -#include "macros.h" -#include "utilities.h" +#include "./macros.h" +#include "./utilities.h" +#include "./validators.h" -// Cells -#include "cells/constructors.h" -#include "cells/methods.h" +// Patterns +#include "./patterns/main.h" #endif // MAIN_H_INCLUDED diff --git a/libs/patterns/constructors.c b/libs/patterns/constructors.c new file mode 100644 index 0000000..c501ad3 --- /dev/null +++ b/libs/patterns/constructors.c @@ -0,0 +1,150 @@ + +#include "./macros.h" +#include "./methods.h" +#include "./structs.h" + +void newGliderPattern(TPattern* pattern) { + pattern->rows = 3; + pattern->cols = 3; + + setPatternCenter(pattern); + + fillPattern(pattern, DEAD_CELL); + + pattern->arr[0][2] = ALIVE_CELL; + pattern->arr[1][0] = ALIVE_CELL; + pattern->arr[1][2] = ALIVE_CELL; + pattern->arr[2][1] = ALIVE_CELL; + pattern->arr[2][2] = ALIVE_CELL; +} + +void newGliderCannonPattern(TPattern* pattern) { + pattern->rows = 9; + pattern->cols = 36; + + setPatternCenter(pattern); + + fillPattern(pattern, DEAD_CELL); + + pattern->arr[4][0] = ALIVE_CELL; + pattern->arr[5][0] = ALIVE_CELL; + pattern->arr[4][1] = ALIVE_CELL; + pattern->arr[5][1] = ALIVE_CELL; + + pattern->arr[4][10] = ALIVE_CELL; + pattern->arr[5][10] = ALIVE_CELL; + pattern->arr[6][10] = ALIVE_CELL; + pattern->arr[7][11] = ALIVE_CELL; + pattern->arr[8][12] = ALIVE_CELL; + pattern->arr[8][13] = ALIVE_CELL; + pattern->arr[7][15] = ALIVE_CELL; + pattern->arr[5][14] = ALIVE_CELL; + pattern->arr[3][11] = ALIVE_CELL; + pattern->arr[2][12] = ALIVE_CELL; + pattern->arr[2][13] = ALIVE_CELL; + pattern->arr[3][15] = ALIVE_CELL; + pattern->arr[4][16] = ALIVE_CELL; + pattern->arr[5][16] = ALIVE_CELL; + pattern->arr[6][16] = ALIVE_CELL; + pattern->arr[5][17] = ALIVE_CELL; + pattern->arr[4][20] = ALIVE_CELL; + pattern->arr[3][20] = ALIVE_CELL; + pattern->arr[2][20] = ALIVE_CELL; + pattern->arr[4][21] = ALIVE_CELL; + pattern->arr[3][21] = ALIVE_CELL; + pattern->arr[2][21] = ALIVE_CELL; + pattern->arr[5][22] = ALIVE_CELL; + pattern->arr[1][22] = ALIVE_CELL; + pattern->arr[1][24] = ALIVE_CELL; + pattern->arr[0][24] = ALIVE_CELL; + pattern->arr[5][24] = ALIVE_CELL; + pattern->arr[6][24] = ALIVE_CELL; + + pattern->arr[3][34] = ALIVE_CELL; + pattern->arr[2][34] = ALIVE_CELL; + pattern->arr[3][35] = ALIVE_CELL; + pattern->arr[2][35] = ALIVE_CELL; +} + +void newPressPattern(TPattern* pattern) { + pattern->rows = 13; + pattern->cols = 13; + + setPatternCenter(pattern); + + fillPattern(pattern, DEAD_CELL); + + pattern->arr[0][2] = ALIVE_CELL; + pattern->arr[0][3] = ALIVE_CELL; + pattern->arr[0][4] = ALIVE_CELL; + pattern->arr[0][8] = ALIVE_CELL; + pattern->arr[0][9] = ALIVE_CELL; + pattern->arr[0][10] = ALIVE_CELL; + + pattern->arr[2][0] = ALIVE_CELL; + pattern->arr[2][5] = ALIVE_CELL; + pattern->arr[2][7] = ALIVE_CELL; + pattern->arr[2][12] = ALIVE_CELL; + + pattern->arr[3][0] = ALIVE_CELL; + pattern->arr[3][5] = ALIVE_CELL; + pattern->arr[3][7] = ALIVE_CELL; + pattern->arr[3][12] = ALIVE_CELL; + + pattern->arr[4][0] = ALIVE_CELL; + pattern->arr[4][5] = ALIVE_CELL; + pattern->arr[4][7] = ALIVE_CELL; + pattern->arr[4][12] = ALIVE_CELL; + + pattern->arr[5][2] = ALIVE_CELL; + pattern->arr[5][3] = ALIVE_CELL; + pattern->arr[5][4] = ALIVE_CELL; + pattern->arr[5][8] = ALIVE_CELL; + pattern->arr[5][9] = ALIVE_CELL; + pattern->arr[5][10] = ALIVE_CELL; + + pattern->arr[7][2] = ALIVE_CELL; + pattern->arr[7][3] = ALIVE_CELL; + pattern->arr[7][4] = ALIVE_CELL; + pattern->arr[7][8] = ALIVE_CELL; + pattern->arr[7][9] = ALIVE_CELL; + pattern->arr[7][10] = ALIVE_CELL; + + pattern->arr[8][0] = ALIVE_CELL; + pattern->arr[8][5] = ALIVE_CELL; + pattern->arr[8][7] = ALIVE_CELL; + pattern->arr[8][12] = ALIVE_CELL; + + pattern->arr[9][0] = ALIVE_CELL; + pattern->arr[9][7] = ALIVE_CELL; + pattern->arr[9][5] = ALIVE_CELL; + pattern->arr[9][12] = ALIVE_CELL; + + pattern->arr[10][0] = ALIVE_CELL; + pattern->arr[10][5] = ALIVE_CELL; + pattern->arr[10][7] = ALIVE_CELL; + pattern->arr[10][12] = ALIVE_CELL; + + pattern->arr[12][2] = ALIVE_CELL; + pattern->arr[12][3] = ALIVE_CELL; + pattern->arr[12][4] = ALIVE_CELL; + pattern->arr[12][8] = ALIVE_CELL; + pattern->arr[12][9] = ALIVE_CELL; + pattern->arr[12][10] = ALIVE_CELL; +} + +void newToadPattern(TPattern* pattern) { + pattern->rows = 2; + pattern->cols = 4; + + setPatternCenter(pattern); + + fillPattern(pattern, DEAD_CELL); + + pattern->arr[0][1] = ALIVE_CELL; + pattern->arr[0][2] = ALIVE_CELL; + pattern->arr[0][3] = ALIVE_CELL; + pattern->arr[1][0] = ALIVE_CELL; + pattern->arr[1][1] = ALIVE_CELL; + pattern->arr[1][2] = ALIVE_CELL; +} diff --git a/libs/patterns/constructors.h b/libs/patterns/constructors.h new file mode 100644 index 0000000..3e8c043 --- /dev/null +++ b/libs/patterns/constructors.h @@ -0,0 +1,51 @@ + +#ifndef PATTERNS_CONSTRUCTORS_H_INCLUDED +#define PATTERNS_CONSTRUCTORS_H_INCLUDED + +#include "./structs.h" + +/** + * @brief Initializes a new Glider pattern. + * + * This function sets up a new Glider pattern in the provided pattern structure. + * The Glider pattern is a pattern of cells that travels across a Conway's Game of Life grid. + * + * @param pattern Pointer to the pattern structure to be initialized with the glider pattern. + */ +void newGliderPattern(TPattern* pattern); + +/** + * @brief Initializes a new Glider Cannon pattern. + * + * This function sets up a Glider Cannon pattern in the provided pattern structure. + * The Glider Cannon is a pattern of cells that periodically produces gliders that travels across a + * Conway's Game of Life grid. + * + * @param pattern Pointer to the pattern structure to be initialized with the Glider Cannon + * pattern. + */ +void newGliderCannonPattern(TPattern* pattern); + +/** + * @brief Initializes a new Press pattern. + * + * This function sets up a new Press pattern by initializing the provided pattern structure. + * The Press is a pattern of cells that oscillates with a period of 3 generations in a Conway's Game + * of Life grid. + * + * @param pattern Pointer to the pattern structure to be initialized with the Press pattern. + */ +void newPressPattern(TPattern* pattern); + +/** + * @brief Initializes a new Toad pattern. + * + * This function sets up a new Toad pattern by initializing the provided pattern structure. + * The Toad is a pattern of cells that oscillates with a period of 2 generations in a Conway's Game + * of Life grid. + * + * @param pattern Pointer to the pattern structure to be initialized with the Toad pattern. + */ +void newToadPattern(TPattern* pattern); + +#endif // PATTERNS_CONSTRUCTORS_H_INCLUDED diff --git a/libs/patterns/macros.h b/libs/patterns/macros.h new file mode 100644 index 0000000..40da383 --- /dev/null +++ b/libs/patterns/macros.h @@ -0,0 +1,63 @@ + +#ifndef PATTERNS_MACROS_H_INCLUDED +#define PATTERNS_MACROS_H_INCLUDED + +/** + * @def ALIVE_CELL + * @brief Represents a live cell. + * + * @warning The value of `ALIVE_CELL` must be a single character. + */ +#define ALIVE_CELL 'o' + +/** + * @def ALIVE_CELL_NG + * @brief Represents a cell that is going to be alive in the next generation. + * + * @warning The value of `ALIVE_CELL_NG` must be a single character and must not be equal to + * `ALIVE_CELL`, `DEAD_CELL`, or `DEAD_CELL_NG` macros. + */ +#define ALIVE_CELL_NG '1' + +/** + * @def DEAD_CELL + * @brief Represents a dead cell. + * + * @warning The value of `DEAD_CELL` must be a single character. + */ +#define DEAD_CELL ' ' + +/** + * @def DEAD_CELL_NG + * @brief Represents a cell that is going to be dead in the next generation. + * + * @warning The value of `DEAD_CELL_NG` must be a single character and must not be equal to + * `ALIVE_CELL`, `ALIVE_CELL_NG`, or `DEAD_CELL` macros. + */ +#define DEAD_CELL_NG '0' + +/** + * @def PATTERN_ROWS + * @brief Defines the number of rows in a 2D array pattern. + * + * This macro is used to define the number of rows in a 2D array pattern. + * It is typically used in conjunction with the `PATTERN_COLS` macro to define + * the size of a pattern. + * + * @warning The value of `PATTERN_ROWS` should be a positive integer. + */ +#define PATTERN_ROWS 13 + +/** + * @def PATTERN_COLS + * @brief Defines the number of columns in a 2D array pattern. + * + * This macro is used to define the number of columns in a 2D array pattern. + * It is typically used in conjunction with the `PATTERN_ROWS` macro to define + * the size of a pattern. + * + * @warning The value of `PATTERN_COLS` should be a positive integer. + */ +#define PATTERN_COLS 36 + +#endif // PATTERNS_MACROS_H_INCLUDED diff --git a/libs/patterns/main.h b/libs/patterns/main.h new file mode 100644 index 0000000..78e6d7b --- /dev/null +++ b/libs/patterns/main.h @@ -0,0 +1,11 @@ + +#ifndef PATTERNS_MAIN_H_INCLUDED +#define PATTERNS_MAIN_H_INCLUDED + +// Root +#include "./constructors.h" +#include "./macros.h" +#include "./methods.h" +#include "./structs.h" + +#endif // PATTERNS_MAIN_H_INCLUDED diff --git a/libs/patterns/methods.c b/libs/patterns/methods.c new file mode 100644 index 0000000..3a7ba8b --- /dev/null +++ b/libs/patterns/methods.c @@ -0,0 +1,36 @@ + +#include + +#include "./structs.h" + +void fillPattern(TPattern* pPattern, char with) { + int i; + int j; + + for (i = 0; i < pPattern->rows; i++) { + for (j = 0; j < pPattern->cols; j++) { + pPattern->arr[i][j] = with; + } + } +} + +void printPatternByConsole(TPattern* pPattern) { + int i; + int j; + + for (i = 0; i < pPattern->rows; i++) { + for (j = 0; j < pPattern->cols; j++) { + printf("%c", pPattern->arr[i][j]); + } + + printf("\n"); + } +} + +void setPatternCenter(TPattern* pPattern) { + int row = pPattern->rows / 2; + int col = pPattern->cols / 2; + + pPattern->center[0] = row; + pPattern->center[1] = col; +} \ No newline at end of file diff --git a/libs/patterns/methods.h b/libs/patterns/methods.h new file mode 100644 index 0000000..9adcf85 --- /dev/null +++ b/libs/patterns/methods.h @@ -0,0 +1,36 @@ + +#ifndef PATTERNS_METHODS_H_INCLUDED +#define PATTERNS_METHODS_H_INCLUDED + +#include "./structs.h" + +/** + * @brief Fills the `arr` field of a pattern structure with a specified value. + * + * @param pPattern A pointer to the pattern structure. + * @param with The value to fill the `arr` field. + * + * @warning This function assumes that `pPattern` has been properly initialized. + */ +void fillPattern(TPattern* pPattern, char with); + +/** + * @brief Prints the `arr` field of a pattern structure by console. + * + * @param pPattern A pointer to the pattern structure. + * + * @warning This function assumes that `pPattern` has been properly initialized. + */ +void printPatternByConsole(TPattern* pPattern); + +/** + * @brief Sets the center of a pattern structure. + * + * @param pPattern A pointer to the pattern structure. + * + * @warning This function assumes that `pPattern` has been properly initialized with valid `rows` + * and `cols` field values. + */ +void setPatternCenter(TPattern* pPattern); + +#endif // PATTERNS_METHODS_H_INCLUDED \ No newline at end of file diff --git a/libs/patterns/structs.h b/libs/patterns/structs.h new file mode 100644 index 0000000..ab0adb5 --- /dev/null +++ b/libs/patterns/structs.h @@ -0,0 +1,21 @@ + +#ifndef PATTERNS_STRUCTS_H_INCLUDED +#define PATTERNS_STRUCTS_H_INCLUDED + +#include "./macros.h" + +/** + * @struct TPattern + * @brief Represents a pattern structure. + * + * This structure is used to represent a pattern in a 2D array. It contains a 2D array representing + * the pattern, as well as other properties such as the number of rows and columns of the pattern. + */ +typedef struct { + char (*arr)[PATTERN_COLS]; /** 2D array representing the pattern. */ + int rows; /** Number of rows of the pattern. */ + int cols; /** Number of columns of the pattern. */ + int center[2]; /** Array (row, and column) representing the center of the pattern. */ +} TPattern; + +#endif // PATTERNS_STRUCTS_H_INCLUDED diff --git a/libs/utilities.c b/libs/utilities.c index 2ef3375..ea5d830 100644 --- a/libs/utilities.c +++ b/libs/utilities.c @@ -1,14 +1,315 @@ + +#include "./utilities.h" + +#include #include +#include +#include +#include + +#include "./patterns/main.h" + +int countAliveNeighbors(TGame* pGame, int cellRow, int cellCol, int radius) { + int i; + int j; + + int startRow = cellRow - radius; + int startCol = cellCol - radius; + + int endRow = cellRow + radius + 1; + int endCol = cellCol + radius + 1; + + int aliveNeighbors = 0; + + for (i = startRow; i < endRow; i++) { + if (i > pGame->rows - 1) break; + if (i < 0) continue; + + for (j = startCol; j < endCol; j++) { + if (j > pGame->cols - 1) break; + if (j < 0) continue; + + if (i == cellRow && j == cellCol) continue; + + if (pGame->dashboard[i][j] == ALIVE_CELL || pGame->dashboard[i][j] == DEAD_CELL_NG) + aliveNeighbors++; + } + } + + return aliveNeighbors; +} + +void drawPattern(TGame* pGame, char* pattern) { + TPattern SPattern; + + char arr[PATTERN_ROWS][PATTERN_COLS]; + + SPattern.arr = arr; + + fillDashboard(pGame, DEAD_CELL); + + if (strcmpi(pattern, "glider") == 0) { + newGliderPattern(&SPattern); + pGame->cellsAlive = 5; + } else if (strcmpi(pattern, "glider cannon") == 0) { + newGliderCannonPattern(&SPattern); + pGame->cellsAlive = 36; + } else if (strcmpi(pattern, "press") == 0) { + newPressPattern(&SPattern); + pGame->cellsAlive = 48; + } else if (strcmpi(pattern, "toad") == 0) { + newToadPattern(&SPattern); + pGame->cellsAlive = 6; + } else { + return; + } + + pGame->cellsDead = (pGame->cols * pGame->rows) - pGame->cellsAlive; + pGame->generation = 0; + + drawPatternInDashboard(pGame, &SPattern); +} + +void drawPatternInDashboard(TGame* pGame, TPattern* pPattern) { + int i; + int j; + + int pI = 0; + int pJ = 0; -int getStrLength(char* str) { - int length = 0; + int startRow = pGame->center[0] - pPattern->center[0]; + int startCol = pGame->center[1] - pPattern->center[1]; - while (*str != '\0') { - length++; - str++; + for (i = startRow; pI < pPattern->rows; i++) { + if (i < 0) continue; + if (i > pGame->rows - 1) break; + + for (j = startCol; pJ < pPattern->cols; j++) { + if (j < 0) continue; + if (j > pGame->cols - 1) break; + + pGame->dashboard[i][j] = pPattern->arr[pI][pJ]; + pJ++; + }; + + pJ = 0; + pI++; + } +} + +void fillDashboard(TGame* pGame, char with) { + int i; + int j; + + for (i = 0; i < pGame->rows; i++) { + for (j = 0; j < pGame->cols; j++) { + pGame->dashboard[i][j] = with; + } + } +} + +void generateNextGeneration(TGame* pGame) { + int i; + int j; + + int aliveNeighbors; + + for (i = 0; i < pGame->rows; i++) { + for (j = 0; j < pGame->cols; j++) { + aliveNeighbors = countAliveNeighbors(pGame, i, j, NEIGHBORHOOD_RADIUS); + + if (pGame->dashboard[i][j] == DEAD_CELL) { + if (aliveNeighbors == 3) { + pGame->cellsDead--; + pGame->cellsAlive++; + pGame->dashboard[i][j] = ALIVE_CELL_NG; + }; + + continue; + } + + if (aliveNeighbors < 2 || aliveNeighbors > 3) { + pGame->cellsAlive--; + pGame->cellsDead++; + pGame->dashboard[i][j] = DEAD_CELL_NG; + }; + } + } + + for (i = 0; i < pGame->rows; i++) { + for (j = 0; j < pGame->cols; j++) { + if (pGame->dashboard[i][j] == DEAD_CELL_NG) { + pGame->dashboard[i][j] = DEAD_CELL; + continue; + } + + if (pGame->dashboard[i][j] == ALIVE_CELL_NG) pGame->dashboard[i][j] = ALIVE_CELL; + } + } +} + +char* getUserInputStr(char* message, char* onInvalidMessage, int strLength, + int (*validator)(char* userInput)) { + char* userInput = malloc(strLength * sizeof(char)); + if (userInput == NULL) { + printf("Memory allocation failed!\n"); + exit(EXIT_FAILURE); + } + + printf(message); + fflush(stdin); + fgets(userInput, strLength, stdin); + trimStr(userInput); + + while (!(*validator)(userInput)) { + puts(onInvalidMessage); + printf(message); + fflush(stdin); + fgets(userInput, strLength, stdin); + trimStr(userInput); }; - return length; + return userInput; +} + +int isStrIn(char* str, char* arr[], int size) { + int i; + + for (i = 0; i < size; i++) { + if (strcmpi(str, *(arr + i)) == 0) return 1; + } + + return 0; } -void sayhi() { printf("hello guys"); } +void printDashboardByConsole(TGame* pGame) { + int i; + int j; + + for (i = 0; i < pGame->cols + 2; i++) printf("-"); + printf("\n"); + + for (i = 0; i < pGame->rows; i++) { + printf("|"); + for (j = 0; j < pGame->cols; j++) { + printf("%c", pGame->dashboard[i][j]); + } + + printf("|\n"); + } + + for (i = 0; i < pGame->cols + 2; i++) printf("-"); +} + +void printGame(TGame* pGame) { + int i; + for (i = 0; i < pGame->cols + 2; i++) printf("-"); + + printf("\n| Cells alive: %*d |", pGame->cols - 17 + 2, pGame->cellsAlive); + printf("\n| Cells dead: %*d |", pGame->cols - 16 + 2, pGame->cellsDead); + printf("\n| Generation: %*d |", pGame->cols - 16 + 2, pGame->generation); + printf("\n| Maximum generation: %*d |", pGame->cols - 25 + 3, pGame->maximumGeneration); + printf("\n| Delay between generations: %*d |\n", pGame->cols - 32 + 3, + pGame->delayBetweenGenerations); + + printDashboardByConsole(pGame); +} +void setDashboardCenter(TGame* pGame) { + int row = pGame->rows / 2; + int col = pGame->cols / 2; + + pGame->center[0] = row; + pGame->center[1] = col; +} + +void sleep(int miliseconds) { + clock_t startTime = clock(); + while (clock() < (startTime + miliseconds)) + ; +} + +void startGameByConsole(TGame* pGame, int maxGeneration, int delayBetweenGenerations) { + int generation = 0; + + pGame->generation = 0; + pGame->maximumGeneration = maxGeneration; + pGame->delayBetweenGenerations = delayBetweenGenerations; + + system("cls"); + printGame(pGame); + if (generation == maxGeneration) return; + sleep(delayBetweenGenerations); + + while (generation < maxGeneration) { + generateNextGeneration(pGame); + + generation++; + + pGame->generation = generation; + + system("cls"); + printGame(pGame); + if (generation != maxGeneration) sleep(delayBetweenGenerations); + } +} + +int strcmpi(const char* str01, const char* str02) { + int i; + + int lengthStr01 = strlen(str01); + int lengthStr02 = strlen(str02); + + char charStr01; + char charStr02; + int cmp = 1; + + if (lengthStr01 != lengthStr02) return lengthStr01 > lengthStr02 ? 1 : -1; + + for (i = 0; i < lengthStr01; i++) { + charStr01 = toupper(*(str01 + i)); + charStr02 = toupper(*(str02 + i)); + cmp = charStr01 - charStr02; + + if (cmp != 0) return cmp; + }; + + return cmp; +} + +void trimStr(char* str) { + trimLeftStr(str); + trimRightStr(str); +} + +void trimLeftStr(char* str) { + int i; + int j; + int strLength = strlen(str); + + int counter = 0; + + for (i = 0; i < strLength; i++) { + if (!isspace(*(str + i))) break; + counter++; + }; + + for (j = 0; j < strLength - counter; j++) { + *(str + j) = *(str + j + counter); + }; + + *(str + strLength - counter) = '\0'; +} + +void trimRightStr(char* str) { + int i; + int strLength = strlen(str); + + int counter = 0; + + for (i = strLength - 1; i > 0; i--) { + if (!isspace(*(str + i))) break; + counter++; + } + + *(str + strLength - counter) = '\0'; +} diff --git a/libs/utilities.h b/libs/utilities.h index ced1c89..5815779 100644 --- a/libs/utilities.h +++ b/libs/utilities.h @@ -1,22 +1,210 @@ + #ifndef UTILITIES_H_INCLUDED #define UTILITIES_H_INCLUDED +#include + +#include "./macros.h" +#include "./patterns/main.h" + +/** + * @struct TGame + * @brief Represents a Conway's Game of Life structure. + * + * This structure represents a Conway's Game of Life in which the cells moves + * are recorded. It contains a dashboard, which is a 2D array representing the + * game board, as well as other properties such as the number of rows and + * columns in the dashboard, and the values to represent alive and dead cells. + */ +typedef struct { + char (*dashboard)[DASHBOARD_COLS]; /** Board (2D array) in which the cells moves. */ + int rows; /** Number of rows in `dashboard`. */ + int cols; /** Number of columns in `dashboard`. */ + int center[2]; /** Array (row, and column) representing the center of the `dashboard`. */ + int cellsAlive; /** Number of alive cells. */ + int cellsDead; /** Number of dead cells. */ + int generation; /** Represents the generation number. */ + int maximumGeneration; /** TODO: Documentation */ + int delayBetweenGenerations; /** TODO: Documentation */ +} TGame; + +/** + * @brief Counts the number of alive neighbors around a given position inside the `dashboard` field + * of a Conway's Game of Life structure. + * + * This function iterates through the cells within a specified radius around the given cell + * (excluding the cell itself) and counts how many of those cells are alive. + * + * @param pGame Pointer to the Conway's Game of Life structure. + * @param row Row index of the cell. + * @param col Column index of the cell. + * @param radius Radius around the cell to check for alive neighbors. + * + * @return The number of alive neighbors around the specified cell. + * + * @warning This function assumes that `pGame` has been properly initialized. + */ +int countAliveNeighbors(TGame* pGame, int row, int col, int radius); + +/** + * @brief Draws a specified pattern on a Conway's Game of Life board. + * + * @param pGame Pointer to the Conway's Game of Life structure where the pattern will be drawn. + * @param pattern Pattern to be drawn. + * + * @warning The pattern must be `glider`, `toad`, `press`, or `glider cannon`. + */ +void drawPattern(TGame* pGame, char* pattern); + +/** + * @brief Draws a specified pattern on a Conway's Game of Life board. + * + * @param pGame Pointer to the Conway's Game of Life structure where the pattern will be drawn. + * @param pPattern Pointer to pattern structure to be drawn. + * + * @warning This functions is intended for internal use only and should not be used outside of this + * library. + */ +void drawPatternInDashboard(TGame* pGame, TPattern* pPattern); + +/** + * @brief Fills the dashboard of a Conway's Game of Life structure with a + * specified value. + * + * @param pGame A pointer to the Conway's Game of Life structure. + * @param with The value to fill the dashboard with. + * + * @warning This function assumes that `pGame` has been + * properly initialized. + */ +void fillDashboard(TGame* pGame, char with); + +// TODO: Documentation +void generateNextGeneration(TGame* pGame); + /** - * @brief Calculates the length of a string. + * @brief Gets user input as a string. * - * This function takes a null-terminated string as input and returns the number - * of characters in the string, excluding the null character. + * This function prompts the user with a message and retrieves their input as a + * string. The user's input is validated using the provided validator function. * - * @param str The null-terminated string for which the length needs to be - * calculated. + * @param message The message to display as a prompt to the user. + * @param onInvalidMessage The message to display when the user input is + * invalid. + * @param strLength The maximum length of the string to be inputted by the user. + * @param validator A function pointer to a validator function that takes a + * string as input and returns an integer. The validator function should return + * 1 if the input is valid, and 0 otherwise. + * + * @return A pointer to the string entered by the user. + */ +char* getUserInputStr(char* message, char* onInvalidMessage, int strLength, + int (*validator)(char* userInput)); + +/** + * @brief Checks if a string is present in an array of strings. + * + * This function checks if a given string is present in an array of strings. + * + * @param str The string to search for. + * @param arr The array of strings to search in. + * @param arrLength The arrLength of the array. + * + * @return 1 if the string is found in the array, 0 otherwise. + */ +int isStrIn(char* str, char* arr[], int arrLength); + +/** + * @brief Prints the dashboard of a Conway's Game of Life structure by console. * - * @return The length of the string. + * @param pGame A pointer to the Conway's Game of Life structure. * - * @warning The input string must be null-terminated, otherwise the behavior is - * undefined. + * @warning This function assumes that `pGame` has been properly initialized. */ -int getStrLength(char* str); +void printDashboardByConsole(TGame* pGame); -void sayhi(); +// TODO: Documentation +void printGame(TGame* pGame); + +/** + * @brief Sets the center of a Conway's Game of Life structure. + * + * @param pGame A pointer to the Conway's Game of Life structure. + * + * @warning This function assumes that `pGame` has been properly initialized with valid `rows` and + * `cols` field values. + */ +void setDashboardCenter(TGame* pGame); + +/** + * @brief Pauses the execution of the program. + * + * @warning The actual delay may be longer than specified due to system timer. + */ +void sleep(int milliseconds); + +/** + * @brief Starts a Conway's Game of Life game using the console as the output. + * + * @param pGame Pointer to a Conway's Game of Life structure. + * @param maxGeneration Maximum number of generations. + * @param delayBetweenGenerations Delay in milliseconds between each generation. + * + * @warning This function assumes that `pGame` has been properly initialized. + */ +void startGameByConsole(TGame* pGame, int maxGeneration, int delayBetweenGenerations); + +/** + * @brief Compares two strings case-insensitively. + * + * This function compares two strings case-insensitively and returns an integer + * indicating their relative order. The comparison is based on the ASCII values + * of the characters in the strings. + * + * @param str01 The first string to compare. + * @param str02 The second string to compare. + * + * @return An integer less than zero if str01 is less than str02, zero if str01 + * matches str02, or greater than zero if str01 is greater than str02. + * + * @warning This function assumes that the input strings are null-terminated. + */ +int strcmpi(const char* str01, const char* str02); + +/** + * @brief Trims leading and trailing whitespace characters from a string. + * + * This function trims leading and trailing whitespace characters from a string + * by modifying the string in-place. + * + * @param str The string to trim. + * + * @warning This function assumes that the input string is null-terminated. + */ +void trimStr(char* str); + +/** + * @brief Trims leading whitespace characters from a string. + * + * This function trims leading whitespace characters from a string by modifying + * the string in-place. + * + * @param str The string to trim. + * + * @warning This function assumes that the input string is null-terminated. + */ +void trimLeftStr(char* str); + +/** + * @brief Trims trailing whitespace characters from a string. + * + * This function trims trailing whitespace characters from a string by modifying + * the string in-place. + * + * @param str The string to trim. + * + * @warning This function assumes that the input string is null-terminated. + */ +void trimRightStr(char* str); -#endif // UTILITIES_H_INCLUDED +#endif // UTILITIES_H_INCLUDED \ No newline at end of file diff --git a/libs/validators.c b/libs/validators.c new file mode 100644 index 0000000..9ecd32c --- /dev/null +++ b/libs/validators.c @@ -0,0 +1,45 @@ + +#include +#include +#include +#include + +#include "./macros.h" +#include "./utilities.h" + +int validateDelay(char* delay) { + int i; + int delayInt; + int delayLength = strlen(delay); + + for (i = 0; i < delayLength; i++) { + if (!isdigit(*(delay + i))) return 0; + } + + sscanf(delay, "%d", &delayInt); + return delayInt >= MINIMUM_DELAY && delayInt <= MAXIMUM_DELAY; +} + +int validateGeneration(char* generation) { + int i; + int generationInt; + int generationLength = strlen(generation); + + for (i = 0; i < generationLength; i++) { + if (*(generation + i) != '-' && !isdigit(*(generation + i))) return 0; + } + + sscanf(generation, "%d", &generationInt); + return generationInt >= INT_MIN && generationInt <= INT_MAX; +} + +int validatePattern(char* pattern) { + char* options[] = {"glider", "toad", "press", "glider cannon"}; + return isStrIn(pattern, options, 4); +} + +int validatePlatform(char* userInput) { + char* options[] = {"console", "simple directmedia layer (sdl)", "simple directmedia layer", + "sdl"}; + return isStrIn(userInput, options, 4); +} \ No newline at end of file diff --git a/libs/validators.h b/libs/validators.h new file mode 100644 index 0000000..a2d4ae5 --- /dev/null +++ b/libs/validators.h @@ -0,0 +1,44 @@ + +#ifndef VALIDATORS_H_INCLUDED +#define VALIDATORS_H_INCLUDED + +/** + * @brief Validates a delay. + * + * This function checks if a provided delay is between the minimum number, and the + * maximum number for a delay in milliseconds. + * + * @param delay The delay to be validated. + * + * @return 1 if the delay is valid, 0 otherwise. + */ +int validateDelay(char* delay); + +/** + * @brief Validates a generation. + * + * This function checks if a provided generation string is between the minimum number, and the + * maximum number for a generation. + * + * @param generation The generation to be validated. + * + * @return 1 if the generation is valid, 0 otherwise. + */ +int validateGeneration(char* generation); + +/** + * @brief Validates the pattern of user input. + * + * This function checks if the user input matches `glider`, `toad`, `press`, or + * `glider cannon` pattern. The comparison is case insensitive. + * + * @param userInput The user input to be validated. + * + * @return 1 if the pattern is valid, 0 otherwise. + */ +int validatePattern(char* pattern); + +// TODO: Documentation +int validatePlatform(char* platform); + +#endif // VALIDATORS_H_INCLUDED diff --git a/src/main.c b/src/main.c index 49a8b07..f225f77 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,89 @@ #include "../libs/main.h" +#include #include -#include int main() { - char str[] = "Hello World!"; - int strLength = getStrLength(str); + TGame game; - printf("> The length of the string \"%s\" is %d.", str, strLength); + char dashboard[DASHBOARD_ROWS][DASHBOARD_COLS]; + int rows = DASHBOARD_ROWS; + int cols = DASHBOARD_COLS; + + char* requestedPattern; + char* maxGeneration; + char* delayBetweenGenerations; + char delayBetweenGenerationsMsg[120]; + char* platformSelected; + + int maxGenerationInt; + int delayBetweenGenerationsInt; + + game.dashboard = dashboard; + game.rows = rows; + game.cols = cols; + game.cellsAlive = 0; + game.cellsDead = cols * rows; + game.generation = 0; + + setDashboardCenter(&game); + + fillDashboard(&game, DEAD_CELL); + + /* ----------------------------- Request Pattern ---------------------------- */ + + requestedPattern = getUserInputStr( + "> Which pattern do you want? ('Glider','Toad', 'Press', or 'Glider cannon'): ", + "> Invalid pattern! Try again...", 50, &validatePattern); + + printf("> Pattern received: '%s'.\n\n", requestedPattern); + + drawPattern(&game, requestedPattern); + + /* ----------------------- Request Maximum Generation ----------------------- */ + + maxGeneration = getUserInputStr( + "> Which is maximum generation do you want? (a negative number is equal to infinity): ", + "> Invalid generation! Try again...", 10, &validateGeneration); + + sscanf(maxGeneration, "%d", &maxGenerationInt); + + if (maxGenerationInt < 0) { + maxGeneration = "'infinity'"; + maxGenerationInt = INT_MAX; + }; + + printf("> Maximum generation received: %s.\n\n", maxGeneration); + + /* ------------------------------ Request Delay ----------------------------- */ + + sprintf(delayBetweenGenerationsMsg, + "> What should be the milliseconds delay between generations? (must be between %d and " + "%d, both included): ", + MINIMUM_DELAY, MAXIMUM_DELAY); + + delayBetweenGenerations = getUserInputStr(delayBetweenGenerationsMsg, + "> Invalid delay! Try again...", 5, &validateDelay); + + sscanf(delayBetweenGenerations, "%d", &delayBetweenGenerationsInt); + + printf("> Delay received: %s milliseconds.\n\n", delayBetweenGenerations); + + /* ---------------------------- Request Platform ---------------------------- */ + + platformSelected = getUserInputStr( + "> In which platform do you want to start the Conway's Game of Life game? (console, or " + "Simple DirectMedia Layer (SDL)): ", + "> Invalid option! Try again...", 32, &validatePlatform); + + printf("> Platform selected: '%s'.\n", platformSelected); + + if (strcmpi(platformSelected, "console") == 0) { + startGameByConsole(&game, maxGenerationInt, delayBetweenGenerationsInt); + return 0; + } + + // TODO: Start game in SDL. return 0; } diff --git a/todos.md b/todos.md new file mode 100644 index 0000000..572d14b --- /dev/null +++ b/todos.md @@ -0,0 +1,5 @@ +# Falta + +- Colocar las macros donde corresponden. +- Crear una función para mostrar el juego en _Simple DirectMedia Layer (SDL)_. +- Mover las funciones y métodos dedicados a actuar sobre una estructura `TGame` a una carpeta propia para asi separar responsabilidades.