GameOfLife/main.c

166 lines
3.3 KiB
C

#include <SDL2/SDL.h>
#include <stdlib.h>
#include "config.h"
#define SCREEN_WIDTH (ROWS * CELL_SIZE)
#define SCREEN_HEIGHT (COLUMNS * CELL_SIZE)
int gameRunning = 1;
int simulation = 0;
int mouseHold = 0;
int board[COLUMNS][ROWS];
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Event event;
void init() {
SDL_Init(SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN,
&window, &renderer);
if (!window) {
printf("%s", SDL_GetError());
exit(1);
}
SDL_SetWindowTitle(window, "Game Of Life");
}
void destroy() {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
void clear_board() {
if (!simulation) {
for (int i = 0; i < COLUMNS; i++) {
for (int j = 0; j < ROWS; j++) {
board[i][j] = 0;
}
}
}
}
void processMotion(int x, int y) {
if (mouseHold && !simulation && x >= 0 && y >= 0 && x < SCREEN_WIDTH &&
y < SCREEN_HEIGHT) {
int cellX = x / CELL_SIZE;
int cellY = y / CELL_SIZE;
board[cellY][cellX] = 1;
}
}
void handleEvents() {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
gameRunning = 0;
break;
case SDL_MOUSEMOTION:
processMotion(event.motion.x, event.motion.y);
break;
case SDL_MOUSEBUTTONUP:
mouseHold = 0;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_c)
clear_board();
break;
case SDL_MOUSEBUTTONDOWN:
switch (event.button.button) {
case SDL_BUTTON_LEFT:
mouseHold = 1;
processMotion(event.button.x, event.button.y);
break;
case SDL_BUTTON_RIGHT:
simulation = (simulation + 1) % 2;
break;
}
break;
}
}
}
void render() {
SDL_SetRenderDrawColor(renderer, 47, 49, 54, 255);
SDL_RenderClear(renderer);
SDL_Rect rect;
rect.w = CELL_SIZE;
rect.h = CELL_SIZE;
for (int i = 0; i < COLUMNS; i++) {
for (int j = 0; j < ROWS; j++) {
rect.x = j * CELL_SIZE;
rect.y = i * CELL_SIZE;
if (board[i][j] == 1) {
SDL_SetRenderDrawColor(renderer, 185, 187, 190, 255);
SDL_RenderFillRect(renderer, &rect);
} else {
SDL_SetRenderDrawColor(renderer, 54, 57, 63, 255);
SDL_RenderDrawRect(renderer, &rect);
}
}
}
if (simulation)
SDL_Delay(1000 / GENERATIONS_PER_SECOND);
else
SDL_Delay(1000 / 120);
SDL_RenderPresent(renderer);
}
void move() {
int new_board[COLUMNS][ROWS];
for (int i = 0; i < COLUMNS; i++) {
for (int j = 0; j < ROWS; j++) {
int count = 0;
for (int di = i - 1; di <= i + 1; di++) {
for (int dj = j - 1; dj <= j + 1; dj++) {
if ((di == i && dj == j) || (di < 0 || dj < 0) ||
(di >= COLUMNS || j >= ROWS))
continue;
if (board[di][dj] == 1)
count++;
}
}
if (board[i][j] == 1 && (count == 2 || count == 3))
new_board[i][j] = 1;
else if (board[i][j] == 0 && count == 3)
new_board[i][j] = 1;
else
new_board[i][j] = 0;
}
}
memcpy(board, new_board, sizeof(int) * ROWS * COLUMNS);
}
void gameLoop() {
while (gameRunning) {
handleEvents();
if (simulation)
move();
render();
}
}
int main(int argv, char **args) {
init();
gameLoop();
destroy();
return 0;
}