updates
This commit is contained in:
parent
d77afc920b
commit
6b62b29233
3 changed files with 164 additions and 80 deletions
27
src/conf.h
27
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 },
|
||||
},
|
||||
};
|
||||
|
||||
//====================
|
||||
|
|
213
src/main.c
213
src/main.c
|
@ -1,6 +1,7 @@
|
|||
#include "main.h"
|
||||
#include "conf.h"
|
||||
#include "raylib.h"
|
||||
#include <raylib.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -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_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");
|
||||
|
||||
SetTargetFPS(TARGET_FPS);
|
||||
|
||||
printf("\n===== turmites =====\n");
|
||||
|
||||
struct turmite t;
|
||||
reset_turmite(&t);
|
||||
int reset_timer = DO_SHOWCASE ? 0 : -1;
|
||||
int tick_count = 0;
|
||||
|
||||
if (!DO_SHOWCASE) {
|
||||
print_table();
|
||||
int is_oob(struct turmite *t) {
|
||||
return t->x < 0 || t->y < 0 || t->x >= GRID_SIZE || t->y >= GRID_SIZE;
|
||||
}
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
draw_frame(tick_count, &t);
|
||||
void run_showcase() {
|
||||
struct grid g;
|
||||
struct grid g_hare;
|
||||
clear_grid(&g);
|
||||
clear_grid(&g_hare);
|
||||
|
||||
if (reset_timer == 0) {
|
||||
printf("\n===== reset =====\n");
|
||||
struct turmite t;
|
||||
struct turmite t_hare;
|
||||
reset_turmite(&t);
|
||||
reset_turmite(&t_hare);
|
||||
|
||||
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, msg, &g, &t);
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
12
src/main.h
12
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue