diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18d2eaf --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +main diff --git a/Makefile b/Makefile index dc3bcad..05fb64c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC := gcc CFLAGS := -Wall -Wextra -g -fsanitize=address,undefined $(shell sdl2-config --cflags) LDFLAGS := $(shell sdl2-config --libs) -TARGET := main +TARGET := game_of_life SRC_DIR := src BLD_DIR := build @@ -28,4 +28,7 @@ clean: fclean: clean rm -f $(TARGET) +run: + ./$(TARGET) + re: fclean all diff --git a/src/game_core.c b/src/game_core.c new file mode 100644 index 0000000..875f23c --- /dev/null +++ b/src/game_core.c @@ -0,0 +1,81 @@ +#include "game_core.h" +#include + +const int directions[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, + {0, 1}, {1, -1}, {1, 0}, {1, 1}}; + +const uint32_t colors[2] = {BLACK, WHITE}; + +Board init_board(size_t width, size_t height, int random) { + Board board = {NULL, width, height}; + board.pixels = malloc(height * sizeof(uint32_t *)); + for (size_t y = 0; y < height; y++) { + + board.pixels[y] = malloc(width * sizeof(uint32_t)); + for (size_t x = 0; x < width; x++) { + if (random) + board.pixels[y][x] = colors[rand() % 2]; + else + board.pixels[y][x] = BLACK; + } + } + return board; +} + +void free_board(Board board) { + for (size_t y = 0; y < board.height; y++) + free(board.pixels[y]); + free(board.pixels); +} + +Board copy_board(Board board) { + Board copy = init_board(board.width, board.height, 0); + for (size_t x = 0; x < board.width; x++) { + for (size_t y = 0; y < board.height; y++) { + copy.pixels[y][x] = board.pixels[y][x]; + } + } + return copy; +} + +void display_board(Board board) { + for (size_t y = 0; y < board.height; y++) { + for (size_t x = 0; x < board.width; x++) { + printf("%c", board.pixels[y][x] == BLACK ? ' ' : 'X'); + } + puts(""); + } +} + +int count_adjacent(Board board, size_t x, size_t y) { + size_t i; + int w, h; + uint8_t count = 0; + for (i = 0; i < 8; i++) { + w = x + directions[i][1]; + h = y + directions[i][0]; + if (!((w < 0 || w >= (int)board.width) || + (h < 0 || h >= (int)board.height))) + if (board.pixels[h][w] == WHITE) + count++; + } + return count; +} + +Board process_game(Board board) { + Board new_board = copy_board(board); + size_t x, y; + uint8_t count = 0; + for (y = 0; y < board.height; y++) { + for (x = 0; x < board.width; x++) { + count = count_adjacent(board, x, y); + if (board.pixels[y][x] == BLACK && count == 3) { + new_board.pixels[y][x] = WHITE; + } else if (board.pixels[y][x] == WHITE && count != 2 && count != 3) { + new_board.pixels[y][x] = BLACK; + } + } + } + free_board(board); + return new_board; +} diff --git a/src/game_core.h b/src/game_core.h new file mode 100644 index 0000000..5dce605 --- /dev/null +++ b/src/game_core.h @@ -0,0 +1,22 @@ +#ifndef GAME_CORE_H +#define GAME_CORE_H +#include +#include +#include + +#define BLACK (0xFF000000) +#define WHITE (0xFFFFFFFF) + +typedef struct { + uint32_t **pixels; + size_t width; + size_t height; +} Board; + +void free_board(Board board); +Board init_board(size_t width, size_t height, int random); +int count_adjacent(Board board, size_t x, size_t y); +Board process_game(Board board); +void display_board(Board board); + +#endif diff --git a/src/main.c b/src/main.c index 28f956d..796d046 100644 --- a/src/main.c +++ b/src/main.c @@ -1,12 +1,16 @@ +#include "game_core.h" #include "utils.h" #include #include #include #include +#include -#define SEED (42) +#define SEED (5) #define WIDTH (800) #define HEIGHT (600) +#define SIM_WIDTH (10) +#define SIM_HEIGHT (10) t_flags process_args(int argc, char **argv) { t_flags output_flags = {0}; @@ -32,8 +36,10 @@ t_flags process_args(int argc, char **argv) { int main(int argc, char *argv[]) { t_flags flags = process_args(argc, argv); + srand(time(NULL)); + if (flags.graphical) { - srand(SEED); + Board b = init_board(WIDTH, HEIGHT, 1); SDL_Init(SDL_INIT_VIDEO); @@ -42,12 +48,9 @@ int main(int argc, char *argv[]) { SDL_Texture *tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT); + SDL_TEXTUREACCESS_STREAMING, SIM_WIDTH, SIM_HEIGHT); uint32_t pixels[HEIGHT][WIDTH]; - for (int y = 0; y < HEIGHT; y++) - for (int x = 0; x < WIDTH; x++) - pixels[y][x] = 0xFFFFFF00; int running = 1; SDL_Event e; while (running) { @@ -56,16 +59,34 @@ int main(int argc, char *argv[]) { running = 0; // Envoie la matrice à la texture - SDL_UpdateTexture(tex, NULL, pixels, WIDTH * sizeof(uint32_t)); + uint32_t flat[HEIGHT * WIDTH]; + for (size_t y = 0; y < HEIGHT; y++) + for (size_t x = 0; x < WIDTH; x++) + flat[y * WIDTH + x] = b.pixels[y][x]; + SDL_Rect dst = {0, 0, WIDTH, HEIGHT}; + SDL_UpdateTexture(tex, NULL, flat, SIM_WIDTH * sizeof(uint32_t)); SDL_RenderClear(ren); - SDL_RenderCopy(ren, tex, NULL, NULL); + SDL_RenderCopy(ren, tex, NULL, &dst); SDL_RenderPresent(ren); + b = process_game(b); + SDL_Delay(500); } SDL_DestroyTexture(tex); SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); SDL_Quit(); + free_board(b); + + } else { + + Board b = init_board(SIM_WIDTH, SIM_HEIGHT, 1); + display_board(b); + puts("----------"); + b = process_game(b); + display_board(b); + free_board(b); } + return EXIT_SUCCESS; }