diff options
author | venomade <venomade@venomade.com> | 2025-02-27 17:25:46 +0000 |
---|---|---|
committer | venomade <venomade@venomade.com> | 2025-02-27 17:25:46 +0000 |
commit | 259c727658485ea00d6ef8617ecab579be871470 (patch) | |
tree | 5f548781584cf942b0c8a9101eed124da902c9ce /src/simulator |
Initial Commit
Diffstat (limited to 'src/simulator')
-rw-r--r-- | src/simulator/main.c | 132 | ||||
-rw-r--r-- | src/simulator/rendering.c | 194 | ||||
-rw-r--r-- | src/simulator/rendering.h | 36 |
3 files changed, 362 insertions, 0 deletions
diff --git a/src/simulator/main.c b/src/simulator/main.c new file mode 100644 index 0000000..5c875fe --- /dev/null +++ b/src/simulator/main.c @@ -0,0 +1,132 @@ +#include <stdio.h> +#include <time.h> +#include <assert.h> +#include <SDL2/SDL.h> + +#include "SDL_events.h" +#include "./rendering.h" +#include "../game.h" + +Game games[2] = {0}; + +const char *tsoding_shift(int *argc, char ***argv) { + assert(*argc > 0); + const char* result = **argv; + *argc -= 1; + *argv += 1; + return result; +} + +void usage(FILE *stream) { + fprintf(stream, "./gp_simulator [input.bin]\n"); +} + +int main(int argc, char *argv[]) { + + int current = 0; + srand(time(NULL)); + + tsoding_shift(&argc, &argv); + + if (argc == 0) { + printf("WARNING: No input file provided, Generating Random State...\n"); + init_game(&games[current]); + } else { + const char *input_filepath = tsoding_shift(&argc, &argv); + printf("Loading state from %s...\n", input_filepath); + load_game(input_filepath, &games[current]); + } + + + + + + //print_chromo(stdout, game.chromos); + + scc(SDL_Init(SDL_INIT_VIDEO)); + + // Create Window + SDL_Window *window = scp(SDL_CreateWindow( + "Question Mark? (floating)", + 0, 0, + SCREEN_WIDTH, SCREEN_HEIGHT, + SDL_WINDOW_RESIZABLE)); + + // Create GPU Accelerated Renderer + SDL_Renderer *renderer = scp(SDL_CreateRenderer( + window, + -1, + SDL_RENDERER_ACCELERATED)); + + // Set Window to Scale Rendered Content on resize + scc(SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT)); + + // Keep SDL alive and continuously poll events and render. + int quit = 0; + while (!quit) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: { + quit = 1; + } break; + case SDL_KEYDOWN: { + switch (event.key.keysym.sym) { + case SDLK_SPACE: { + step_game(&games[current]); + } break; + case SDLK_r: { + init_game(&games[current]); + } break; + case SDLK_n: { + //print_best_agents(stdout, &games[current], SELECTION_POOL); + int next = 1 - current; + make_next_generation(&games[current], &games[next]); + current = next; + } break; + case SDLK_q: { + SDL_DestroyRenderer(renderer); // Writes an error, but without this, + // program doesn't close properly? + SDL_DestroyWindow(window); + SDL_Quit(); + } break; + //case SDLK_d: { + // dump_game(DUMP_FILEPATH, &games[current]); + //} break; + } + } break; + case SDL_MOUSEBUTTONDOWN: { + Coord cell; + cell.x = (int) floorf(event.button.x / CELL_WIDTH); + cell.y = (int) floorf(event.button.y / CELL_HEIGHT); + Agent *agent = agent_at(&games[current], cell); + + if (agent) { + print_agent(stdout, agent); + } + } break; + } + } + + // Draw Background + SDL_SetRenderDrawColor(renderer, HEX_COLOR(BACKGROUND_COLOR)); + scc(SDL_RenderClear(renderer)); + + // Draw Board Grid + // render_board_grid(renderer); + + // Render Agents + render_game(renderer, &games[current]); + + // Render + SDL_RenderPresent(renderer); + + } + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + + SDL_Quit(); + + return 0; +} diff --git a/src/simulator/rendering.c b/src/simulator/rendering.c new file mode 100644 index 0000000..05a93f4 --- /dev/null +++ b/src/simulator/rendering.c @@ -0,0 +1,194 @@ +#include "rendering.h" +#include "SDL_stdinc.h" +#include "../game.h" + +#include <SDL2/SDL.h> + +#define GAP_SIZE (fminf(CELL_WIDTH, CELL_HEIGHT) / 1.1f) + +int scc(int code) { + if (code < 0) { + fprintf(stderr, "SDL Error: %s\n", SDL_GetError()); + exit(1); + } + + return code; +} + +void *scp(void *ptr) { + if (ptr == NULL) { + fprintf(stderr, "SDL Error: %s\n", SDL_GetError()); + exit(1); + } + + return ptr; +} + +SDL_Vertex sdl_color_hex_vertex(int x, int y, Uint32 hex) { + SDL_Vertex vertex; + + vertex.position.x = (float)x; + vertex.position.y = (float)y; + vertex.color.r = (hex >> (3 * 8)) & 0xFF; + vertex.color.g = (hex >> (2 * 8)) & 0xFF; + vertex.color.b = (hex >> (1 * 8)) & 0xFF; + vertex.color.a = (hex >> (0 * 8)) & 0xFF; + vertex.tex_coord.x = 0; + vertex.tex_coord.y = 0; + + return vertex; +} + +void render_board_grid(SDL_Renderer *renderer) { + SDL_SetRenderDrawColor(renderer, HEX_COLOR(GRID_COLOR)); + + for (int x = 1; x < BOARD_WIDTH; ++x) { + SDL_RenderDrawLine(renderer, + x * CELL_WIDTH, + 0, + x * CELL_WIDTH, + SCREEN_HEIGHT); + } + + for (int x = 1; x < BOARD_HEIGHT; ++x) { + SDL_RenderDrawLine(renderer, + 0, + x * CELL_HEIGHT, + SCREEN_WIDTH, + x * CELL_HEIGHT); + } +} + +#define AGENT_CELL_POS_X agent.pos.x * CELL_WIDTH +#define AGENT_CELL_POS_Y agent.pos.y * CELL_HEIGHT + +#define VERTEX_0 \ + sdl_color_hex_vertex(AGENT_CELL_POS_X + GAP_SIZE, \ + AGENT_CELL_POS_Y + GAP_SIZE, \ + color) + +#define VERTEX_1 \ + sdl_color_hex_vertex(AGENT_CELL_POS_X + CELL_WIDTH - GAP_SIZE, \ + AGENT_CELL_POS_Y + GAP_SIZE, \ + color) + +#define VERTEX_2 \ + sdl_color_hex_vertex(AGENT_CELL_POS_X + GAP_SIZE, \ + AGENT_CELL_POS_Y + CELL_HEIGHT - GAP_SIZE, \ + color) + +#define VERTEX_3 \ + sdl_color_hex_vertex(AGENT_CELL_POS_X + CELL_WIDTH - GAP_SIZE, \ + AGENT_CELL_POS_Y + CELL_HEIGHT - GAP_SIZE, \ + color) + +#define FOOD_CELL_POS_X x * CELL_WIDTH +#define FOOD_CELL_POS_Y y * CELL_HEIGHT + +SDL_Vertex* sdl_draw_food_diamond(int y, int x) { + SDL_Vertex* vertices = malloc(4 * sizeof(SDL_Vertex)); + if (vertices == NULL) { + fprintf(stderr, "Vertex Memory allocation failed\n"); + exit(1); + } + + vertices[0] = sdl_color_hex_vertex(FOOD_CELL_POS_X + CELL_WIDTH - GAP_SIZE, + FOOD_CELL_POS_Y + (CELL_WIDTH / 2), + FOOD_COLOR); + + vertices[1] = sdl_color_hex_vertex(FOOD_CELL_POS_X + (CELL_WIDTH / 2), + FOOD_CELL_POS_Y + GAP_SIZE, + FOOD_COLOR); + + vertices[2] = sdl_color_hex_vertex(FOOD_CELL_POS_X + GAP_SIZE, + FOOD_CELL_POS_Y + (CELL_WIDTH / 2), + FOOD_COLOR); + + vertices[3] = sdl_color_hex_vertex(FOOD_CELL_POS_X + (CELL_WIDTH / 2), + FOOD_CELL_POS_Y + CELL_HEIGHT - GAP_SIZE, + FOOD_COLOR); + + return vertices; +} + +SDL_Vertex* sdl_draw_agent_triangle(Agent agent) { + SDL_Vertex* vertices = malloc(3 * sizeof(SDL_Vertex)); + if (vertices == NULL) { + fprintf(stderr, "Vertex Memory allocation failed\n"); + exit(1); + } + + Uint32 color = agent.health <= 0 ? AGENT_COLOR_DEAD : AGENT_COLOR_ALIVE; + + switch (agent.dir) { + case DIR_LEFT: + vertices[0] = VERTEX_0; + vertices[1] = VERTEX_2; + vertices[2] = sdl_color_hex_vertex(AGENT_CELL_POS_X + CELL_WIDTH - GAP_SIZE, + AGENT_CELL_POS_Y + (CELL_WIDTH / 2), + color); + break; + case DIR_DOWN: + vertices[0] = VERTEX_2; + vertices[1] = VERTEX_3; + vertices[2] = sdl_color_hex_vertex(AGENT_CELL_POS_X + (CELL_WIDTH / 2), + AGENT_CELL_POS_Y + GAP_SIZE, + color); + break; + case DIR_RIGHT: + vertices[0] = VERTEX_1; + vertices[1] = VERTEX_3; + vertices[2] = sdl_color_hex_vertex(AGENT_CELL_POS_X + GAP_SIZE, + AGENT_CELL_POS_Y + (CELL_WIDTH / 2), + color); + break; + case DIR_UP: + vertices[0] = VERTEX_0; + vertices[1] = VERTEX_1; + vertices[2] = sdl_color_hex_vertex(AGENT_CELL_POS_X + (CELL_WIDTH / 2), + AGENT_CELL_POS_Y + CELL_HEIGHT - GAP_SIZE, + color); + break; + } + + return vertices; +} + +void render_agent(SDL_Renderer *renderer, Agent agent) { + SDL_Vertex * vertices = sdl_draw_agent_triangle(agent); + scc(SDL_RenderGeometry(renderer, NULL, vertices, 3, NULL, 0)); + free(vertices); // sdl_draw_agent_triangle's malloc +} + +void render_game(SDL_Renderer *renderer, const Game *game) { + for (size_t i = 0; i < AGENTS_COUNT; ++i) { + render_agent(renderer, game->agents[i]); + } + + // Render Foods + const int indices[] = {0, 1, 2, 0, 3, 2}; + for(int y = 0; y < BOARD_HEIGHT; ++y) { + for (int x = 0; x < BOARD_WIDTH; ++x) { + if (game->foods_map[y][x]) { + SDL_Vertex *vertices = sdl_draw_food_diamond(y, x); + scc(SDL_RenderGeometry(renderer, NULL, vertices, 4, indices, 6)); + free(vertices); // sdl_draw_food_diamond's malloc + } + + if (game->walls_map[y][x]) { + SDL_Rect rect = {// Check why int floorf + (int)floorf(x * CELL_WIDTH), + (int)floorf(y * CELL_HEIGHT), + (int)floorf(CELL_WIDTH), (int)floorf(CELL_HEIGHT)}; + SDL_SetRenderDrawColor(renderer, HEX_COLOR(WALL_COLOR)); + SDL_RenderFillRect(renderer, &rect); + } + } + } + + // Render Walls + for (size_t i = 0; i < WALLS_COUNT; ++i) { + + } + +} diff --git a/src/simulator/rendering.h b/src/simulator/rendering.h new file mode 100644 index 0000000..a899cc2 --- /dev/null +++ b/src/simulator/rendering.h @@ -0,0 +1,36 @@ +#ifndef RENDERING_H +#define RENDERING_H + +#include <SDL2/SDL.h> +#include "../game.h" + +#define SCREEN_WIDTH 600 +#define SCREEN_HEIGHT 600 + +#define CELL_WIDTH ((float) SCREEN_WIDTH / (float) BOARD_WIDTH) +#define CELL_HEIGHT ((float) SCREEN_HEIGHT / (float) BOARD_HEIGHT) + +#define BACKGROUND_COLOR 0x190A0FFF +#define GRID_COLOR 0xEBCBF4FF +#define WALL_COLOR (GRID_COLOR) +#define AGENT_COLOR_ALIVE 0x8447FFFF +// #define AGENT_COLOR_DEAD 0x392A2FFF +#define AGENT_COLOR_DEAD (BACKGROUND_COLOR) +#define FOOD_COLOR 0xE1F0C4FF + + +#define HEX_COLOR(hex) \ + ((hex) >> (3 * 8)) & 0xFF, \ + ((hex) >> (2 * 8)) & 0xFF, \ + ((hex) >> (1 * 8)) & 0xFF, \ + ((hex) >> (0 * 8)) & 0xFF + +int scc(int code); + +void *scp(void *ptr); + +void render_board_grid(SDL_Renderer *renderer); + +void render_game(SDL_Renderer *renderer, const Game *game); + +#endif |