Archived
1
Fork 0

Initial commit

This commit is contained in:
Hadeed 2024-09-11 22:48:22 +05:00
commit 1a564b75ca
16 changed files with 424 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
build/
life

28
Makefile Normal file
View file

@ -0,0 +1,28 @@
# Written with extensive help from https://makefiletutorial.com
CC = g++
TARGET_EXEC = life
SRC_DIR = src
INC_DIR = include
BUILD_DIR = build
CFLAGS = -I $(INC_DIR) -MMD -MP -I c:/SDL2/include -I c:/SDL2/include/SDL2 -Dmain=SDL_main
LDFLAGS = -L c:/SDL2/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -static-libstdc++ -static-libgcc
SRC = $(wildcard $(SRC_DIR)/*.cpp)
OBJ = $(SRC:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
DEP = $(OBJ:%.o=%.d)
$(TARGET_EXEC): $(OBJ)
$(CC) $(OBJ) -o $(TARGET_EXEC) $(LDFLAGS)
$(OBJ): $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
@mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
clean:
@rm -rf $(BUILD_DIR) $(TARGET_EXEC)
-include $(DEP)

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# Game of life
A CS100 project. The git history is lost because the original git repository was deleted, this one was reconstructed from the files I submitted. A compiled version for windows is provided, you can compile for mac and linux using the provided makefile, minor changes to makefile might be required.

11
include/drawing.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef DRAWING_H
#define DRAWING_H
// Public
void draw();
// Private
static void draw_grid_lines();
static void draw_cells();
#endif

13
include/events.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef EVENTS_H
#define EVENTS_H
#include <SDL_events.h>
// Public
void handle_events();
//Private
void handle_key_event(SDL_Keycode key_pressed);
void handle_mouse_event(int x, int y);
#endif

13
include/game.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef GAME_H
#define GAME_H
// Public
void start_game();
void toggle_pause();
extern bool paused;
// Private
static void game_loop();
#endif

17
include/globals.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef CONFIG_H
#define CONFIG_H
#define CELL_SIZE 20
#define GRID_WIDTH 64
#define GRID_HEIGHT 48
#define WINDOW_WIDTH GRID_WIDTH * CELL_SIZE
#define WINDOW_HEIGHT GRID_HEIGHT * CELL_SIZE
#define FRAMES_PER_SECOND 60
#define UPDATES_PER_SECOND 5
#define ALIVE true
#define DEAD false
#endif

12
include/grid.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef GRID_H
#define GRID_H
#include "globals.h"
// Public
void clear_grid();
void iterate_grid();
extern bool grid[GRID_HEIGHT][GRID_WIDTH];
#endif

14
include/main.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef MAIN_H
#define MAIN_H
#include <SDL.h>
// Public
void quit_application(int exit_code);
extern SDL_Window *window;
// Private
static void init();
#endif

9
include/timing.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef TIMING_H
#define TIMING_H
// Public
void limit_fps();
extern double delta_time;
#endif

93
src/drawing.cpp Normal file
View file

@ -0,0 +1,93 @@
#include <SDL.h>
#include "drawing.h" // This file
#include "game.h" // Get paused state
#include "globals.h" // Size macros
#include "grid.h" // Get grid state
#include "main.h" // Get window
void clear_window() {
SDL_Surface *surface = SDL_GetWindowSurface(window);
Uint32 background = SDL_MapRGB(surface->format, 0x2E, 0x34, 0x40);
SDL_FillRect(surface, NULL, background);
}
SDL_Surface* grid_lines_surface() {
Uint32 rmask, gmask, bmask, amask;
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
SDL_Surface *grid_lines = SDL_CreateRGBSurface(0, WINDOW_WIDTH, WINDOW_HEIGHT, 32, rmask, gmask, bmask, amask);
Uint32 lines_color = SDL_MapRGB(grid_lines->format, 0x3B, 0x42, 0x52);
SDL_Surface *vertical = SDL_CreateRGBSurface(0, 2, WINDOW_HEIGHT, 32, rmask, gmask, bmask, amask);
SDL_FillRect(vertical, NULL, lines_color);
for (int i = 0; i <= GRID_WIDTH; i++) {
SDL_Rect destination;
destination.x = i * CELL_SIZE - 1;
destination.y = 0;
SDL_BlitSurface(vertical, NULL, grid_lines, &destination);
}
SDL_FreeSurface(vertical);
SDL_Surface *horizontal = SDL_CreateRGBSurface(0, WINDOW_WIDTH, 2, 32, rmask, gmask, bmask, amask);
SDL_FillRect(horizontal, NULL, lines_color);
for (int i = 0; i <= GRID_HEIGHT; i++) {
SDL_Rect destination;
destination.x = 0;
destination.y = i * CELL_SIZE - 1;
SDL_BlitSurface(horizontal, NULL, grid_lines, &destination);
}
SDL_FreeSurface(horizontal);
return grid_lines;
}
SDL_Surface* cell_surface() {
SDL_Surface *cell = SDL_CreateRGBSurface(0, CELL_SIZE, CELL_SIZE, 32, 0, 0, 0, 0);
Uint32 cell_color = SDL_MapRGB(cell->format, 0xE5, 0xE9, 0xF0);
SDL_FillRect(cell, NULL, cell_color);
return cell;
}
void draw() {
clear_window();
draw_cells();
if (paused) draw_grid_lines();
SDL_UpdateWindowSurface(window);
}
void draw_grid_lines() {
SDL_Surface *surface = SDL_GetWindowSurface(window);
static SDL_Surface *grid_lines = grid_lines_surface();
SDL_BlitSurface(grid_lines, NULL, surface, &surface->clip_rect);
}
void draw_cells() {
SDL_Surface *surface = SDL_GetWindowSurface(window);
static SDL_Surface *cell = cell_surface();
for (int i = 0; i < GRID_HEIGHT; i++)
for (int j = 0; j < GRID_WIDTH; j++) {
if (grid[i][j] == ALIVE) {
SDL_Rect destination;
destination.x = j * CELL_SIZE;
destination.y = i * CELL_SIZE;
SDL_BlitSurface(cell, NULL, surface, &destination);
}
}
}

49
src/events.cpp Normal file
View file

@ -0,0 +1,49 @@
#include <SDL_events.h>
#include "events.h" // This file
#include "game.h" // Get and set paused state
#include "globals.h" // Cell size macros
#include "grid.h" // Set grid
#include "main.h" // Quit
void handle_events() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
handle_key_event(event.key.keysym.sym);
break;
case SDL_MOUSEBUTTONDOWN:
handle_mouse_event(event.button.x, event.button.y);
break;
case SDL_QUIT:
quit_application(0);
break;
}
}
}
void handle_key_event(SDL_Keycode key_pressed) {
switch (key_pressed) {
case SDLK_q:
quit_application(0);
break;
case SDLK_SPACE:
case SDLK_RETURN:
toggle_pause();
break;
case SDLK_r:
if (paused) clear_grid();
break;
}
}
void handle_mouse_event(int x, int y) {
if (!paused) return;
int i = y / CELL_SIZE;
int j = x / CELL_SIZE;
grid[i][j] = !grid[i][j];
}

43
src/game.cpp Normal file
View file

@ -0,0 +1,43 @@
#include <SDL.h>
#include "drawing.h" // Draw in game loop
#include "events.h" // Handle events in loop
#include "game.h" // This file
#include "globals.h" // Timing macros
#include "grid.h" // Iterate the grid
#include "timing.h" // Timings
// Public
bool paused;
// Private
const double req_update_time = 1.0 / UPDATES_PER_SECOND;
double time_since_update;
void start_game() {
clear_grid();
paused = true;
time_since_update = 0;
while(true) {
game_loop();
limit_fps();
}
}
void game_loop() {
handle_events();
if (!paused) if ((time_since_update += delta_time) >= req_update_time) {
iterate_grid();
time_since_update -= req_update_time;
}
draw();
}
void toggle_pause() {
paused = !paused;
time_since_update = 0;
}

46
src/grid.cpp Normal file
View file

@ -0,0 +1,46 @@
#include "globals.h" // Grid size macros
bool grid[GRID_HEIGHT][GRID_WIDTH];
void clear_grid() {
for (int i = 0; i < GRID_HEIGHT; i++)
for (int j = 0; j < GRID_WIDTH; j++) grid[i][j] = DEAD;
}
int count_alive_neighbours(int x, int y) {
int count = 0;
for (int i = x - 1; i <= x + 1; i++)
for (int j = y - 1; j <= y + 1; j++){
if (i == x && j == y) continue;
int m = (i + GRID_HEIGHT) % GRID_HEIGHT;
int n = (j + GRID_WIDTH) % GRID_WIDTH;
if (grid[m][n] == ALIVE) count++;
}
return count;
}
void iterate_grid() {
bool new_grid[GRID_HEIGHT][GRID_WIDTH];
for (int i = 0; i < GRID_HEIGHT; i++)
for (int j = 0; j < GRID_WIDTH; j++) {
int neighbours = count_alive_neighbours(i, j);
if (grid[i][j] == ALIVE) {
if (neighbours < 2) new_grid[i][j] = DEAD;
else if (neighbours == 2 || neighbours == 3) new_grid[i][j] = ALIVE;
else new_grid[i][j] = DEAD;
} else {
if (neighbours == 3) new_grid[i][j] = ALIVE;
else new_grid[i][j] = DEAD;
}
}
for (int i = 0; i < GRID_HEIGHT; i++)
for (int j = 0; j < GRID_WIDTH; j++) grid[i][j] = new_grid[i][j];
}

44
src/main.cpp Normal file
View file

@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include "game.h" // To start the game
#include "globals.h" // Window dimensions
#include "main.h" // This file
// Public
SDL_Window *window;
int main(int argc, char** argv) {
init();
start_game();
quit_application(0);
}
void init() {
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Could not start SDL.\nSDL error: %s\n", SDL_GetError());
quit_application(1);
}
window = SDL_CreateWindow("Game of Life",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WINDOW_WIDTH, WINDOW_HEIGHT, 0);
if (window == NULL) {
printf("Could not create window: %s\n", SDL_GetError());
quit_application(1);
}
}
void quit_application(int exit_code) {
if (window != NULL) SDL_DestroyWindow(window);
SDL_Quit();
exit(exit_code);
}

27
src/timing.cpp Normal file
View file

@ -0,0 +1,27 @@
#include <SDL.h>
#include "globals.h" // Timing macros
#include "timing.h" // This file
// Public
double delta_time;
// Private
const double req_delta_time = 1.0 / FRAMES_PER_SECOND;
int t_start = 0;
void limit_fps() {
int t_end = SDL_GetTicks();
delta_time = (t_end - t_start) / 1000.0;
double extra_time = req_delta_time - delta_time;
int sleep_time = extra_time * 1000;
if (sleep_time > 0) SDL_Delay(sleep_time);
t_end = SDL_GetTicks();
delta_time = (t_end - t_start) / 1000.0;
t_start = t_end;
}