simulation: add mutation (disabled) and fix bf interpreter

So I was using safe subtraction to fix the heads at 0, but BF itself
wraps heads around the tape if they overflow/underflow.  This
completely changes the presentation of the simulation.
This commit is contained in:
2026-03-18 09:33:03 +00:00
parent eebe39c241
commit 7ab65da761
4 changed files with 54 additions and 40 deletions

View File

@@ -25,20 +25,31 @@ static const Color possible_colors[] = {
void simulation_iterate(simulation_t *sim)
{
sim->a = 0;
sim->b = 0;
while (sim->a == sim->b)
// Mutate cells if an option
#if MUTATION_CHANCE
for (u64 i = 0; i < SIMULATION_SIZE; ++i)
{
sim->a = rand() % NUM_PROGRAMS;
sim->b = rand() % NUM_PROGRAMS;
if ((rand() % MUTATION_CHANCE) == 0)
{
sim->memory[i] += (rand() % MUTATION_OFFSET) - (MUTATION_OFFSET / 2);
}
}
#endif
u64 a = 0, b = 0;
while (a == b)
{
a = rand() % NUM_PROGRAMS;
b = rand() % NUM_PROGRAMS;
}
// Perform the catalytic reaction
struct ProgramConcat a_b_concat = {0};
program_concat(&a_b_concat, sim->memory + (sim->a * SIZEOF_PROGRAM),
sim->memory + (sim->b * SIZEOF_PROGRAM));
program_execute(&a_b_concat);
program_split(&a_b_concat);
// Perform the reaction
struct ProgramConcat *a_b_concat = calloc(1, sizeof(*a_b_concat));
program_concat(a_b_concat, sim->memory + (a * SIZEOF_PROGRAM),
sim->memory + (b * SIZEOF_PROGRAM));
program_execute(a_b_concat);
program_split(a_b_concat);
free(a_b_concat);
}
bf_token get_op(const bf_token cell)
@@ -56,42 +67,38 @@ Color simulation_cell_color(const bf_token cell)
void simulation_draw(simulation_t *sim)
{
auto const PROGRAM_ROW = (1 << (SIZEOF_PROGRAM_POW_2 / 2));
auto const SIMULATION_ROW = (1 << (NUM_PROGRAMS_POW_2 / 2));
auto const CELL_WIDTH = WIDTH / ((f64)(PROGRAM_ROW * SIMULATION_ROW));
auto const CELL_HEIGHT = HEIGHT / ((f64)(PROGRAM_ROW * SIMULATION_ROW));
const u64 PROGRAM_ROW = (1 << (SIZEOF_PROGRAM_POW_2 / 2));
const u64 SIMULATION_ROW = (1 << (NUM_PROGRAMS_POW_2 / 2));
const u64 ROW_NUM_CELLS = (PROGRAM_ROW * SIMULATION_ROW);
const f64 CELL_WIDTH = WIDTH / (f64)ROW_NUM_CELLS;
const f64 CELL_HEIGHT = HEIGHT / (f64)ROW_NUM_CELLS;
for (size_t i = 0; i < NUM_PROGRAMS; ++i)
{
auto s_x = (i / SIMULATION_ROW) * PROGRAM_ROW;
auto s_y = (i % SIMULATION_ROW) * PROGRAM_ROW;
// printf("%lu => (%lu, %lu)\n", i, s_x, s_y);
const bf_token *base = sim->memory + (i * SIZEOF_PROGRAM);
u64 s_x = (i / SIMULATION_ROW) * PROGRAM_ROW;
u64 s_y = (i % SIMULATION_ROW) * PROGRAM_ROW;
for (u64 j = 0; j < SIZEOF_PROGRAM; ++j)
{
auto p_x = j / PROGRAM_ROW;
auto p_y = j % PROGRAM_ROW;
u64 p_x = j / PROGRAM_ROW;
u64 p_y = j % PROGRAM_ROW;
p_x += s_x;
p_y += s_y;
// printf("\t%lu => (%lu, %lu)\n", j, p_x, p_y);
auto color = simulation_cell_color(base[j]);
Color color = simulation_cell_color(base[j]);
// DrawRectangle(p_x * CELL_WIDTH, p_y * CELL_HEIGHT, CELL_WIDTH,
// CELL_HEIGHT, color);
DrawRectangleV((Vector2){CELL_WIDTH * p_x, CELL_HEIGHT * p_y},
(Vector2){CELL_WIDTH, CELL_HEIGHT}, color);
}
if (sim->a == i || sim->b == i)
{
DrawRectangleLinesEx((Rectangle){.x = s_x * CELL_WIDTH,
.y = s_y * CELL_HEIGHT,
.width = PROGRAM_ROW * CELL_WIDTH,
.height = PROGRAM_ROW * CELL_HEIGHT},
1, BLUE);
}
DrawRectangleLinesEx((Rectangle){.x = s_x * CELL_WIDTH,
.y = s_y * CELL_HEIGHT,
.width = CELL_WIDTH * SIMULATION_ROW,
.height = CELL_HEIGHT * SIMULATION_ROW},
1, WHITE);
}
}