summary refs log tree commit diff
path: root/src/simulator
diff options
context:
space:
mode:
authorvenomade <venomade@venomade.com>2025-02-27 17:25:46 +0000
committervenomade <venomade@venomade.com>2025-02-27 17:25:46 +0000
commit259c727658485ea00d6ef8617ecab579be871470 (patch)
tree5f548781584cf942b0c8a9101eed124da902c9ce /src/simulator
Initial Commit
Diffstat (limited to 'src/simulator')
-rw-r--r--src/simulator/main.c132
-rw-r--r--src/simulator/rendering.c194
-rw-r--r--src/simulator/rendering.h36
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