From 6b62b292330594ab5b86ce10cc075ce64e1a8659 Mon Sep 17 00:00:00 2001 From: trimill Date: Sat, 25 Jan 2025 00:56:46 -0500 Subject: [PATCH] updates --- src/conf.h | 27 +++---- src/main.c | 205 ++++++++++++++++++++++++++++++++++++++++------------- src/main.h | 12 ---- 3 files changed, 164 insertions(+), 80 deletions(-) diff --git a/src/conf.h b/src/conf.h index 2a9ddcc..f46d75c 100644 --- a/src/conf.h +++ b/src/conf.h @@ -4,53 +4,46 @@ // Edit the definitions in this file to configure the turmite // size of the window (pixels) -#define SCR_SIZE 800 +#define SCR_SIZE 960 // size of grid cells -#define CELL_SIZE 8 +#define CELL_SIZE 16 // target FPS #define TARGET_FPS 60 // enable showcase mode - randomly cycle through // turmites given N_STATES and N_COLORS -#define DO_SHOWCASE 0 +#define DO_SHOWCASE 1 // number of ticks to simulate each turmite for -#define SHOWCASE_TIME 120 +#define SHOWCASE_TIME 1800 // frames to freeze for after each showcase -#define FREEZE_FRAMES 60 +#define FREEZE_FRAMES 90 // turmite iterations per frame -#define TICKS_PER_FRAME 10 +#define TICKS_PER_FRAME 5 // initial turmite facing #define INIT_DIR DIR_N // number of states -#define N_STATES 2 +#define N_STATES 3 // number of colors -#define N_COLORS 2 +#define N_COLORS 3 // turmite colors #define TURMITE_ALPHA 0xff static uint32_t turmite_colors[N_STATES] = { - 0xff2222, 0x3366ff, //0x00ff11, 0x00ddee, 0xdd11ee, 0xffff00, + 0xff2222, 0x3366ff, 0x00ff11, //0x00ddee, 0xdd11ee, 0xffff00, }; // grid colors static uint32_t colors[N_COLORS] = { 0xffffff, 0x000000, + 0x888888, }; // transition table (not used in showcase mode) static struct transition trans_table[N_STATES][N_COLORS] = { - { - { 1, R, 0 }, - { 1, N, 1 }, - }, - { - { 1, U, 1 }, - { 0, L, 0 }, - }, }; //==================== diff --git a/src/main.c b/src/main.c index fd0308d..6de574e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include "main.h" #include "conf.h" -#include "raylib.h" +#include +#include #include #include #include @@ -9,23 +10,28 @@ #define GRID_SIZE (2 * VIEW_SIZE) #define OFFSET ((GRID_SIZE - VIEW_SIZE) / 2) +struct grid { + uint8_t grid[GRID_SIZE * GRID_SIZE]; +}; -uint8_t grid[GRID_SIZE * GRID_SIZE]; - -uint8_t grid_get(int x, int y) { - return grid[x + y * GRID_SIZE]; +int grid_eq(struct grid *g1, struct grid *g2) { + return 0 == memcmp(g1->grid, g2->grid, sizeof(g2->grid)); } -void grid_set(int x, int y, uint8_t val) { - grid[x + y * GRID_SIZE] = val; +uint8_t grid_get(struct grid *g, int x, int y) { + return g->grid[x + y * GRID_SIZE]; } -void draw_grid(void) { +void grid_set(struct grid *g, int x, int y, uint8_t val) { + g->grid[x + y * GRID_SIZE] = val; +} + +void draw_grid(struct grid *g) { for (int x = 0; x < VIEW_SIZE; x++) { for (int y = 0; y < VIEW_SIZE; y++) { int px = x * CELL_SIZE; int py = y * CELL_SIZE; - uint8_t colno = grid_get(x + OFFSET, y + OFFSET); + uint8_t colno = grid_get(g, x + OFFSET, y + OFFSET); Color col = GetColor(colors[colno] << 8 | 0xff); DrawRectangle(px, py, CELL_SIZE, CELL_SIZE, col); } @@ -38,7 +44,7 @@ void print_table(void) { printf("\t{\n"); for (int c = 0; c < N_COLORS; c++) { struct transition tr = trans_table[s][c]; - char turn; + char turn = '?'; switch (tr.turn) { case N: turn = 'N'; break; case R: turn = 'R'; break; @@ -72,13 +78,34 @@ void rand_table(void) { } } +struct turmite { + int x; + int y; + uint8_t state; + enum dir dir; +}; -void update_turmite(struct turmite *t) { - uint8_t read = grid_get(t->x, t->y); +int turmite_eq(struct turmite *t1, struct turmite *t2) { + return t1->x == t2->x + && t1->y == t2->y + && t1->state == t2->state + && t1->dir == t2->dir; + +} + +void reset_turmite(struct turmite *t) { + t->x = OFFSET + VIEW_SIZE/2; + t->y = OFFSET + VIEW_SIZE/2; + t->state = 0; + t->dir = INIT_DIR; +} + +void update_turmite(struct grid *g, struct turmite *t) { + uint8_t read = grid_get(g, t->x, t->y); struct transition tr = trans_table[t->state][read]; - grid_set(t->x, t->y, tr.write); + grid_set(g, t->x, t->y, tr.write); t->dir = (t->dir + tr.turn) % 4; switch (t->dir) { case DIR_N: t->y -= 1; break; @@ -89,13 +116,8 @@ void update_turmite(struct turmite *t) { t->state = tr.state; } -void reset_turmite(struct turmite *t) { - memset(grid, 0, sizeof(grid)); - - t->x = OFFSET + VIEW_SIZE/2; - t->y = OFFSET + VIEW_SIZE/2; - t->state = 0; - t->dir = INIT_DIR; +void clear_grid(struct grid *g) { + memset(g->grid, 0, sizeof(g->grid)); } void draw_turmite(struct turmite *t) { @@ -107,7 +129,7 @@ void draw_turmite(struct turmite *t) { case DIR_N: oy = -CELL_SIZE*0.4; break; case DIR_E: ox = CELL_SIZE*0.4; break; case DIR_S: oy = CELL_SIZE*0.4; break; - case DIR_W: ox = -CELL_SIZE*0.; break; + case DIR_W: ox = -CELL_SIZE*0.4; break; } Vector2 v1 = { x + ox, y + oy }; Vector2 v2 = { x - ox + oy, y - ox - oy }; @@ -115,70 +137,151 @@ void draw_turmite(struct turmite *t) { DrawTriangle(v1, v2, v3, GetColor(col)); } -void draw_frame(int tick_count, struct turmite *t) { +void draw_frame(int tick_count, char *msg, struct grid *g, struct turmite *t) { BeginDrawing(); ClearBackground(GetColor(colors[0] << 8 | 0xff)); - draw_grid(); + draw_grid(g); draw_turmite(t); DrawFPS(10, 10); char counter[16]; snprintf(counter, 15, "t=%d", tick_count); DrawText(counter, 10, SCR_SIZE-30, 20, GetColor(colors[1] << 8 | 0xff)); + DrawText(msg, 100, 10, 20, GetColor(colors[1] << 8 | 0xff)); + EndDrawing(); } -int main(void) { - InitWindow(SCR_SIZE, SCR_SIZE, "turmites"); +int is_oob(struct turmite *t) { + return t->x < 0 || t->y < 0 || t->x >= GRID_SIZE || t->y >= GRID_SIZE; +} - SetTargetFPS(TARGET_FPS); - - printf("\n===== turmites =====\n"); +void run_showcase() { + struct grid g; + struct grid g_hare; + clear_grid(&g); + clear_grid(&g_hare); struct turmite t; + struct turmite t_hare; reset_turmite(&t); - int reset_timer = DO_SHOWCASE ? 0 : -1; - int tick_count = 0; + reset_turmite(&t_hare); - if (!DO_SHOWCASE) { - print_table(); - } + int wait_timer = 1; + int tick_count = 0; + int running_hare = 1; + int found_cycle = 0; + + char *msg = "Running"; while (!WindowShouldClose()) { - draw_frame(tick_count, &t); + draw_frame(tick_count, msg, &g, &t); - if (reset_timer == 0) { - printf("\n===== reset =====\n"); + if (wait_timer > 0) { + wait_timer -= 1; + + if (wait_timer != 0) { + continue; + } + + printf("\n(%s)", msg); + printf("\n===== Reset =====\n"); + clear_grid(&g); + clear_grid(&g_hare); reset_turmite(&t); + reset_turmite(&t_hare); rand_table(); print_table(); + running_hare = 1; tick_count = 0; - reset_timer = -1; - continue; - } else if (reset_timer > 0) { - reset_timer--; - continue; - } else if (reset_timer == -2) { - continue; + found_cycle = 0; + msg = "Running"; } for (int i = 0; i < TICKS_PER_FRAME; i++) { - update_turmite(&t); + update_turmite(&g, &t); + + for (int i = 0; i < 2; i++) { + if (running_hare) { + update_turmite(&g_hare, &t_hare); + if (is_oob(&t_hare)) { + running_hare = 0; + } + } + } + tick_count++; - int oob = t.x < 0 || t.y < 0 || t.x >= GRID_SIZE || t.y >= GRID_SIZE; - if (DO_SHOWCASE && (oob || tick_count >= SHOWCASE_TIME)) { - reset_timer = FREEZE_FRAMES; + + if (tick_count >= SHOWCASE_TIME) { + msg = "Timeout"; + wait_timer = FREEZE_FRAMES; break; - } else if (oob) { - printf("\n===== out of bounds =====\n"); - reset_timer = -2; + } + + if (is_oob(&t)) { + msg = "Out of bounds"; + wait_timer = FREEZE_FRAMES; + break; + } + + if (turmite_eq(&t, &t_hare) && grid_eq(&g, &g_hare)) { + if (found_cycle) { + msg = "Cycle detected"; + wait_timer = FREEZE_FRAMES; + break; + } else { + found_cycle = 1; + running_hare = 0; + } + } + + } + } +} + +void run_through() { + struct grid g; + clear_grid(&g); + + struct turmite t; + reset_turmite(&t); + + int tick_count = 0; + int halted = 0; + + print_table(); + + while (!WindowShouldClose()) { + draw_frame(tick_count, "", &g, &t); + + if (halted) continue; + + for (int i = 0; i < TICKS_PER_FRAME; i++) { + update_turmite(&g, &t); + tick_count++; + if (is_oob(&t)) { + printf("\n===== Out of bounds =====\n"); + halted = 1; break; } } } +} + +int main(void) { + InitWindow(SCR_SIZE, SCR_SIZE, "Turmites"); + SetTargetFPS(TARGET_FPS); + + printf("\n===== Turmites =====\n"); + + if (DO_SHOWCASE) { + run_showcase(); + } else { + run_through(); + } CloseWindow(); - return 0; + } diff --git a/src/main.h b/src/main.h index 6cd1ed6..cdfd555 100644 --- a/src/main.h +++ b/src/main.h @@ -13,18 +13,6 @@ enum turn { L = 3, }; -enum mode { - ENDLESS, - SHOWCASE, -}; - -struct turmite { - int x; - int y; - uint8_t state; - enum dir dir; -}; - struct transition { uint8_t write; enum turn turn;