forked from arslee07/GameOfLife
166 lines
3.3 KiB
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;
|
|
}
|