#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAP_WIDTH 64
#define MAP_HEIGHT 64
// 简化版Perlin噪声生成器 (实际开发应使用专业噪声库)
static unsigned int seed = 12345;
static float perm[512];
void init_noise() {
for (int i = 0; i < 256; i++) perm[i] = (float)i / 256.0f;
for (int i = 255; i > 0; i--) {
int j = rand() % (i + 1);
float temp = perm[i];
perm[i] = perm[j];
perm[j] = temp;
}
for (int i = 0; i < 256; i++) perm[i + 256] = perm[i];
}
static float fade(float t) { return t * t * t * (t * (t * 6 - 15) + 10); }
static float lerp(float t, float a, float b) { return a + t * (b - a); }
static float grad(int hash, float x, float y) {
int h = hash & 3;
float u = h < 2 ? x : y;
float v = h < 2 ? y : x;
return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
}
float perlin_noise(float x, float y) {
int xi = (int)floorf(x) & 255;
int yi = (int)floorf(y) & 255;
float xf = x - floorf(x);
float yf = y - floorf(y);
float u = fade(xf);
float v = fade(yf);
int aa = perm[perm[xi] + yi];
int ab = perm[perm[xi] + yi + 1];
int ba = perm[perm[xi + 1] + yi];
int bb = perm[perm[xi + 1] + yi + 1];
float x1 = lerp(u, grad(aa, xf, yf), grad(ba, xf - 1, yf));
float x2 = lerp(u, grad(ab, xf, yf - 1), grad(bb, xf - 1, yf - 1));
return lerp(v, x1, x2);
}
// 分形布朗运动生成地形高度图
void generate_terrain_heightmap(float heightmap[MAP_HEIGHT][MAP_WIDTH],
float scale, int octaves, float persistence, float lacunarity) {
float max_val = 0.0f;
for (int y = 0; y < MAP_HEIGHT; y++) {
for (int x = 0; x < MAP_WIDTH; x++) {
float value = 0.0f;
float amplitude = 1.0f;
float frequency = 1.0f;
for (int i = 0; i < octaves; i++) {
value += perlin_noise(x * scale * frequency, y * scale * frequency) * amplitude;
max_val += amplitude;
amplitude *= persistence;
frequency *= lacunarity;
}
heightmap[y][x] = value;
}
}
// 归一化到 0-1
for (int y = 0; y < MAP_HEIGHT; y++) {
for (int x = 0; x < MAP_WIDTH; x++) {
heightmap[y][x] = (heightmap[y][x] + max_val) / (2.0f * max_val);
}
}
}
void print_heightmap_ascii(float heightmap[MAP_HEIGHT][MAP_WIDTH]) {
char symbols[] = " .:-=+*#%@";
for (int y = 0; y < MAP_HEIGHT; y += 2) {
for (int x = 0; x < MAP_WIDTH; x++) {
int idx = (int)(heightmap[y][x] * 9.0f);
if (idx > 9) idx = 9;
printf("%c", symbols[idx]);
}
printf("\n");
}
}
int main() {
init_noise();
float heightmap[MAP_HEIGHT][MAP_WIDTH];
generate_terrain_heightmap(heightmap, 0.05f, 4, 0.5f, 2.0f);
printf("=== Pro#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define GRID_W 20
#define GRID_H 20
#define MAX_EDGES (GRID_W * GRID_H * 4)
typedef struct { int x, y; } Point;
typedef struct { Point from, to; int exists; } Edge;
static Edge edges[MAX_EDGES];
static int edge_count = 0;
void init_grid_graph() {
edge_count = 0;
for (int y = 0; y < GRID_H; y++) {
for (int x = 0; x < GRID_W; x++) {
if (x + 1 < GRID_W) {
edges[edge_count++] = (Edge){{x, y}, {x + 1, y}, 1};
}
if (y + 1 < GRID_H) {
edges[edge_count++] = (Edge){{x, y}, {x, y + 1}, 1};
}
}
}
}
// 简化版:随机移除边模拟自然道路
void remove_random_edges(float remove_prob) {
for (int i = 0; i < edge_count; i++) {
if ((float)rand() / RAND_MAX < remove_prob) {
edges[i].exists = 0;
}
}
}
// 移除死胡同 (度为1的节点)
void remove_dead_ends() {
int changed = 1;
while (changed) {
changed = 0;
for (int i = 0; i < edge_count; i++) {
if (!edges[i].exists) continue;
// 检查两个端点的度
int deg_from = 0, deg_to = 0;
for (int j = 0; j < edge_count; j++) {
if (!edges[j].exists) continue;
if ((edges[j].from.x == edges[i].from.x && edges[j].from.y == edges[i].from.y) ||
(edges[j].to.x == edges[i].from.x && edges[j].to.y == edges[i].from.y)) deg_from++;
if ((edges[j].from.x == edges[i].to.x && edges[j].from.y == edges[i].to.y) ||
(edges[j].to.x == edges[i].to.x && edges[j].to.y == edges[i].to.y)) deg_to++;
}
if (deg_from == 1 || deg_to == 1) {
if ((float)rand() / RAND_MAX > 0.7f) { // 保留部分死胡同
edges[i].exists = 0;
changed = 1;
}
}
}
}
}
void print_road_network() {
printf("\n=== Procedural Road Network ===\n");
for (int y = 0; y < GRID_H; y++) {
// 水平边
for (int x = 0; x < GRID_W - 1; x++) {
int found = 0;
for (int i = 0; i < edge_count; i++) {
if (edges[i].exists && edges[i].from.x == x && edges[i].from.y == y &&
edges[i].to.x == x + 1 && edges[i].to.y == y) { found = 1; break; }
}
printf(found ? "──" : " ");
}
printf("\n");
// 垂直边 + 节点
for (int x = 0; x < GRID_W; x++) {
int found = 0;
for (int i = 0; i < edge_count; i++) {
if (edges[i].exists && edges[i].from.x == x && edges[i].from.y == y &&
edges[i].to.x == x && edges[i].to.y == y + 1) { found = 1; break; }
}
printf(found ? "│" : " ");
printf("·");
}
printf("\n");
}
}
int main() {
srand(42);
init_grid_graph();
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LSYS_LEN 10000
#define MAX_COMMANDS 5000
typedef struct {
char type; // 'R'=road, 'P'=push, 'O'=pop
float x1, y1, x2, y2;
} RoadCommand;
static RoadCommand commands[MAX_COMMANDS];
static int cmd_count = 0;
// L-System迭代生成
void l_system_iterate(char *output, const char *input, const char *rules[][2], int rule_count) {
int pos = 0;
for (int i = 0; input[i] != '\0' && pos < MAX_LSYS_LEN - 1; i++) {
int matched = 0;
for (int r = 0; r < rule_count; r++) {
if (input[i] == rules[r][0][0]) {
int len = strlen(rules[r][1]);
if (pos + len < MAX_LSYS_LEN - 1) {
strcpy(output + pos, rules[r][1]);
pos += len;
}
matched = 1;
break;
}
}
if (!matched) output[pos++] = input[i];
}
output[pos] = '\0';
}
// 解析L-System字符串为道路生成指令
void parse_l_system(const char *l_string, float step_size) {
cmd_count = 0;
float x = 0, y = 0;
float angle = 0;
float stack_x[MAX_COMMANDS], stack_y[MAX_COMMANDS], stack_a[MAX_COMMANDS];
int stack_top = 0;
for (int i = 0; l_string[i] != '\0' && cmd_count < MAX_COMMANDS; i++) {
char c = l_string[i];
if (c == 'F') {
float nx = x + step_size * cosf(angle * 3.14159265f / 180.0f);
float ny = y + step_size * sinf(angle * 3.14159265f / 180.0f);
commands[cmd_count++] = (RoadCommand){'R', x, y, nx, ny};
x = nx; y = ny;
} else if (c == '+') {
angle += 90;
} else if (c == '-') {
angle -= 90;
} else if (c == '[') {
if (stack_top < MAX_COMMANDS) {
stack_x[stack_top] = x;
stack_y[stack_top] = y;
stack_a[stack_top] = angle;
stack_top++;
commands[cmd_count++] = (RoadCommand){'P', 0, 0, 0, 0};
}
} else if (c == ']') {
if (stack_top > 0) {
stack_top--;
x = stack_x[stack_top];
y = stack_y[stack_top];
angle = stack_a[stack_top];
commands[cmd_count++] = (RoadCommand){'O', 0, 0, 0, 0};
}
}
}
}
void print_town_layout() {
printf("\n=== L-System Town Layout ===\n");
printf("Total road segments: %d\n", cmd_count);
for (int i = 0; i < cmd_count && i < 10; i++) {
if (commands[i].type == 'R') {
printf("Road: (%.1f,%.1f) -> (%.1f,%.1f)\n",
commands[i].x1, commands[i].y1, commands[i].x2, commands[i].y2);
}
}
if (cmd_count > 10) printf("... (%d more segments)\n", cmd_count - 10);
}
int main() {
char current[MAX_LSYS_LEN], next[MAX_LSYS_LEN];
strcpy(current, "F+F-F-F+F");
char *rules[][2] = {{"F", "F+F-F-F+F"}};
for (int i = 0; i < 3; i++) {
l_system_iterate(next, current, rules, 1);
strcpy(current, n# 编译地形生成
gcc -o terrain terrain.c -lm
./terrain
# 编译道路网络
gcc -o roads roads.c
./roads
# 编译L-System城镇
gcc -o town town.c -lm
./town
ext);
}
parse_l_system(current, 10.0f);
print_town_layout();
return 0;
}
remove_random_edges(0.3f);
remove_dead_ends();
print_road_network();
return 0;
}
cedural Terrain Heightmap ===\n");
print_heightmap_ascii(heightmap);
return 0;
}