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

如何实现网格的全方位环绕效果?(C语言代码问题求助)

问题分析

你的核心问题出在checkAffShips函数的碰撞检测逻辑上——当前代码只处理了风暴区域完全在网格内部的情况,没有考虑风暴超出网格边界后环绕到另一侧的场景。比如20×20网格中,风暴从x=18、宽度5时,应该覆盖18、19、0、1、2这些坐标,但现有范围判断current->x >= x && current->x < x + w无法识别跨边界的区域。

另外代码里还有两个基础bug必须先修正:

  • shipMovement里的条件判断用了赋值运算符=而非比较运算符==,会导致所有舰船强制往'U'方向移动
  • main函数处理命令'3'时,重新定义了局部变量w和h,覆盖了全局的网格宽高参数
解决方案

1. 先修复基础bug

void shipMovement(int time, int grid_w, int grid_h) {
    Ship *current = head;
    while (current != NULL) {
        // 把赋值运算符=替换为比较运算符==
        if (current->direction == 'U') {
            current->y = (current->y + time) % grid_h;
        }
        else if (current->direction == 'D') {
            current->y = (current->y - time + grid_h) % grid_h;
        }
        else if (current->direction == 'L') {
            current->x = (current->x - time + grid_w) % grid_w;
        }
        else if (current->direction == 'R') {
            current->x = (current->x + time) % grid_w;
        }
        else {
            printf("Invalid Direction!\n");
        }
        current = current->next;
    }
}

// main函数中命令'3'的修改部分
else if (userInput == '3') {
    int x, y, storm_w, storm_h; // 改用storm前缀命名,避免覆盖全局网格宽高
    scanf("%d %d %d %d", &x, &y, &storm_w, &storm_h);
    char *affShips[1000];
    int numAffShips = 0;
    // 传入全局的网格宽高参数
    checkAffShips(x, y, storm_w, storm_h, w, h, affShips, &numAffShips);
    printf("%d\n", numAffShips);
    for (int i = 0; i < numAffShips; i++) {
        printf("%s\n", affShips[i]);
        free(affShips[i]);
    }
}

2. 实现风暴环绕的碰撞检测

修改checkAffShips函数,先将所有坐标转换为网格内的有效范围,再分情况判断舰船是否处于跨边界的风暴区域:

void checkAffShips(int storm_x, int storm_y, int storm_w, int storm_h, int grid_w, int grid_h, char **affShips, int *numAffShips) {
    Ship *current = head;
    // 将风暴起始坐标转换为网格内的有效非负坐标
    storm_x = (storm_x % grid_w + grid_w) % grid_w;
    storm_y = (storm_y % grid_h + grid_h) % grid_h;

    // 计算风暴原始结束位置(不考虑环绕)
    int storm_x_end = storm_x + storm_w;
    int storm_y_end = storm_y + storm_h;

    while (current != NULL) {
        // 确保舰船坐标在网格有效范围内
        int ship_x = (current->x % grid_w + grid_w) % grid_w;
        int ship_y = (current->y % grid_h + grid_h) % grid_h;

        // 判断x方向是否在风暴区域
        int x_in = 0;
        if (storm_x_end <= grid_w) {
            // 风暴x方向未跨边界,常规范围判断
            x_in = (ship_x >= storm_x && ship_x < storm_x_end);
        } else {
            // 风暴x方向跨边界,覆盖[storm_x, grid_w) 和 [0, 剩余长度)
            x_in = (ship_x >= storm_x || ship_x < (storm_x_end - grid_w));
        }

        // 判断y方向是否在风暴区域
        int y_in = 0;
        if (storm_y_end <= grid_h) {
            // 风暴y方向未跨边界,常规范围判断
            y_in = (ship_y >= storm_y && ship_y < storm_y_end);
        } else {
            // 风暴y方向跨边界,同理处理
            y_in = (ship_y >= storm_y || ship_y < (storm_y_end - grid_h));
        }

        // 若x和y都在风暴区域内,记录该舰船
        if (x_in && y_in) {
            affShips[*numAffShips] = (char *)malloc(sizeof(char) * 21);
            strcpy(affShips[(*numAffShips)++], current->shipName);
        }
        current = current->next;
    }
}

逻辑说明

  • 坐标归一化:通过(val % grid_size + grid_size) % grid_size将所有坐标转换为网格内的非负有效值,避免负数或超出范围的问题
  • 跨边界判断:当风暴结束位置超过网格尺寸时,说明区域环绕到网格另一侧,此时舰船坐标只要落在「起始点到网格末尾」或「网格开头到剩余长度」的任一区间内,就算处于风暴中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:05:31