You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言粒子模拟代码优化:消除嵌套if-else与提升扩展性

C语言粒子表面相互作用模拟代码优化方案

问题背景

使用C语言模拟两种粒子在方形表面的相互作用,模拟流程为:

  • 从空表面随机选择一个位点
  • 生成随机数r,若r小于阈值Y则选择粒子#1,否则选择粒子#2
  • 若选择粒子#1,检查四个近邻,任一近邻为粒子#2则反应生成粒子#3,否则粒子#1吸附
  • 粒子#2逻辑类似,检测近邻是否存在粒子#1

现有代码存在大量嵌套if-else,维护调试难度高,后续需扩展更多粒子类型及交互逻辑,需进行代码精简优化。

核心优化方向

1. 用数组封装邻居偏移量,消除重复代码

将四个方向的邻居偏移量存入数组,通过循环统一计算邻居坐标,替代原有的rightneighbor/leftneighbor等重复函数,减少冗余代码。

2. 抽象粒子交互规则,用结构体映射逻辑

定义结构体存储粒子类型、反应目标、计数器等信息,新增粒子时只需扩展结构体数组,无需修改核心执行逻辑。

3. 简化随机选择逻辑,避免多层嵌套

通过随机数直接索引邻居数组,替代原有的多个if-else判断分支,简化代码结构。

4. 修复原代码bug

原代码中粒子#2吸附时错误累加particle1计数,已修正为particle2。

优化后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 网格尺寸定义
#define MAX_X 5
#define MAX_Y 5
#define TOTAL_CELLS (MAX_X * MAX_Y)
// 粒子1选择阈值
#define Y 0.55

// 粒子状态枚举
typedef enum {
    S_EMPTY,
    P1_OCCUPIED,
    P2_OCCUPIED,
    P3_OCCUPIED  // 补充粒子3的状态定义
} gstate;

// 邻居方向偏移量:右、左、上、下
typedef struct {
    int dx;
    int dy;
} NeighborOffset;
const NeighborOffset neighbor_offsets[] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
#define NEIGHBOR_COUNT (sizeof(neighbor_offsets)/sizeof(neighbor_offsets[0]))

// 粒子交互规则结构体
typedef struct {
    gstate self_type;       // 当前粒子类型
    gstate react_target;    // 触发反应的目标粒子类型
    int* self_counter;      // 当前粒子计数器
    int* product_counter;   // 反应产物计数器
} ParticleRule;

// 生成网格内随机坐标
void generate_coords(int* x, int* y) {
    *x = rand() % MAX_X;
    *y = rand() % MAX_Y;
}

// 初始化网格为空
void grid_init(gstate grid[MAX_Y][MAX_X]) {
    for (int y = 0; y < MAX_Y; y++) {
        for (int x = 0; x < MAX_X; x++) {
            grid[y][x] = S_EMPTY;
        }
    }
}

// 计算周期性边界下的坐标
int wrap_coord(int coord, int max) {
    if (coord < 0) return coord + max;
    if (coord >= max) return coord - max;
    return coord;
}

// 获取指定方向的邻居坐标及状态
gstate get_neighbor_state(gstate grid[MAX_Y][MAX_X], int x, int y, int offset_idx) {
    int nx = wrap_coord(x + neighbor_offsets[offset_idx].dx, MAX_X);
    int ny = wrap_coord(y + neighbor_offsets[offset_idx].dy, MAX_Y);
    return grid[ny][nx];
}

// 更新邻居坐标(用于调试打印)
void get_neighbor_coord(int x, int y, int offset_idx, int* nx, int* ny) {
    *nx = wrap_coord(x + neighbor_offsets[offset_idx].dx, MAX_X);
    *ny = wrap_coord(y + neighbor_offsets[offset_idx].dy, MAX_Y);
}

int main() {
    srand((unsigned)time(0));
    gstate grid[MAX_Y][MAX_X];
    grid_init(grid);

    int particle1 = 0, particle2 = 0, particle3 = 0;
    int avail_cells = TOTAL_CELLS;
    int rounds = 0;

    // 定义粒子交互规则
    ParticleRule p1_rule = {P1_OCCUPIED, P2_OCCUPIED, &particle1, &particle3};
    ParticleRule p2_rule = {P2_OCCUPIED, P1_OCCUPIED, &particle2, &particle3};

    while (rounds < TOTAL_CELLS) {
        int x, y;
        generate_coords(&x, &y);

        if (grid[y][x] != S_EMPTY) {
            rounds++;
            continue;
        }

        // 选择粒子类型
        double r = (double)rand() / RAND_MAX;
        printf("r = %.4lf\n", r);
        ParticleRule* rule = (r <= Y) ? &p1_rule : &p2_rule;
        printf("选择粒子%s (r = %.4lf %s Y = %.2lf)\n", 
               rule == &p1_rule ? "#1" : "#2", 
               r, rule == &p1_rule ? "<=" : ">", Y);

        // 随机选择一个邻居方向
        int neighbor_idx = rand() % NEIGHBOR_COUNT;
        int nx, ny;
        get_neighbor_coord(x, y, neighbor_idx, &nx, &ny);
        const char* dir_names[] = {"右", "左", "上", "下"};
        printf("选择%s邻居: (%d,%d)\n", dir_names[neighbor_idx], ny, nx);

        // 检查邻居状态并执行交互
        gstate neighbor_state = get_neighbor_state(grid, x, y, neighbor_idx);
        if (neighbor_state == rule->react_target) {
            // 发生反应:清空邻居位点,产物计数+1
            grid[ny][nx] = S_EMPTY;
            (*rule->product_counter)++;
            avail_cells++;
        } else {
            // 吸附当前粒子
            grid[y][x] = rule->self_type;
            (*rule->self_counter)++;
            avail_cells--;
        }

        rounds++;
    }

    // 输出结果
    printf("\n模拟结束,共执行%d轮\n", rounds);
    printf("粒子#1数量: %d\n", particle1);
    printf("粒子#2数量: %d\n", particle2);
    printf("粒子#3数量: %d\n", particle3);
    printf("可用位点数量: %d\n", avail_cells);
    printf("已占用位点数量: %d\n", TOTAL_CELLS - avail_cells);

    return 0;
}

优化后优势

  • 可扩展性:新增粒子类型时,只需添加对应的ParticleRule结构体和状态枚举,核心逻辑无需修改
  • 可读性:消除多层嵌套,代码结构清晰,交互逻辑集中在规则结构体中
  • 可维护性:重复逻辑统一封装,减少代码冗余,调试时只需关注核心规则和坐标计算

内容的提问来源于stack exchange,提问作者Auyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 08:57:02