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

修复C语言地牢生成代码的房间重叠与无显示问题

Hey there! Let's dig into why your rooms aren't showing up and fix those overlapping issues once and for all. I spotted several key problems in your code that are causing these issues—let's break them down one by one:

1. makeRoom is modifying a copy, not your actual room array

Right now, your makeRoom function takes a room by value, which means it's working on a copy of the room you pass in. Any changes you make to aRoom inside the function won't affect the original rooms[i] in your array. That's why none of your rooms are getting populated—you're generating data that just gets discarded!

Fix: Change the function to take a pointer to a room instead, so you modify the original struct directly:

void makeRoom(room *aRoom) {
    int height = (rand() % (10 + 1 - 5)) + 5;
    int width = (rand() % (15 + 1 - 7)) + 7;
    // Add boundary checks to keep rooms inside the dungeon
    int randomY = rand() % (HEIGHT - height); // Ensure room fits vertically
    int randomX = rand() % (WIDTH - width);   // Ensure room fits horizontally

    aRoom->top_left.y = randomY;
    aRoom->top_left.x = randomX;
    aRoom->top_right.y = randomY;
    aRoom->top_right.x = randomX + width;
    aRoom->bottom_left.y = randomY + height;
    aRoom->bottom_left.x = randomX;
    aRoom->bottom_right.y = randomY + height;
    aRoom->bottom_right.x = randomX + width;
}

And when you call it, pass the address of the room in your array:

makeRoom(&rooms[counter]);

2. Overlap detection logic is broken (both in doOverlap and your placement loop)

First, the doOverlap function has inverted Y-axis logic

Since your dungeon's Y-axis increases downward (top of the terminal is y=0, bottom is y=HEIGHT-1), the condition for non-overlap on the Y-axis is wrong. Right now, your code returns false (no overlap) when l1.y < r2.y—but that's actually a case where rooms might overlap. The correct non-overlap conditions are:

  • Room 1 is completely to the right of Room 2: r1.x < l2.x
  • Room 1 is completely to the left of Room 2: l1.x > r2.x
  • Room 1 is completely below Room 2: l1.y > r2.y
  • Room 1 is completely above Room 2: r1.y < l2.y

If none of these are true, the rooms overlap. Here's the fixed doOverlap:

bool doOverlap(point l1, point r1, point l2, point r2) {
    // Check if one room is to the left/right of the other
    if (r1.x < l2.x || l1.x > r2.x) {
        return false;
    }
    // Check if one room is above/below the other
    if (r1.y < l2.y || l1.y > r2.y) {
        return false;
    }
    // Otherwise, they overlap
    return true;
}

Second, your placement loop only checks against the last placed room

Right now, you're only comparing each new room to rooms[counter], not all rooms you've already placed. That means you could still get overlaps with earlier rooms, and your counter logic is messed up (you increment counter even if the room overlaps).

Fix: Rewrite the loop to keep generating new rooms until you find one that doesn't overlap with any already placed rooms:

void createDungeon() {
    char dungeonGrid[HEIGHT][WIDTH];
    room rooms[N];
    int counter = 0;

    // Initialize dungeon to empty spaces
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            dungeonGrid[y][x] = ' ';
        }
    }

    // Generate N non-overlapping rooms
    while (counter < N) {
        room newRoom;
        makeRoom(&newRoom);
        
        // Check overlap with all already placed rooms
        bool overlaps = false;
        for (int i = 0; i < counter; i++) {
            if (doOverlap(newRoom.top_left, newRoom.bottom_right, rooms[i].top_left, rooms[i].bottom_right)) {
                overlaps = true;
                break;
            }
        }

        // If no overlap, add to the rooms array
        if (!overlaps) {
            rooms[counter] = newRoom;
            counter++;
        }
    }

    // Draw all rooms onto the dungeon grid (optimized version)
    for (int a = 0; a < N; a++) {
        for (int y = rooms[a].top_left.y; y <= rooms[a].bottom_left.y; y++) {
            for (int x = rooms[a].top_left.x; x <= rooms[a].top_right.x; x++) {
                dungeonGrid[y][x] = '.';
            }
        }
    }

    // Print the dungeon
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            printf("%c", dungeonGrid[y][x]);
        }
        printf("\n");
    }
}

Notice that we also optimized the grid drawing—instead of checking every grid cell against every room, we directly iterate over each room's area and set the '.' characters. This is way more efficient!

3. Missing boundary checks for room placement

Your original code could generate rooms that go outside the dungeon's bounds (e.g., randomY + height > HEIGHT), which would cause parts of the room to be drawn outside the terminal or even lead to undefined behavior. The fixed makeRoom function adds checks to ensure rooms fit entirely within the dungeon.

Putting it all together

With these fixes, your code should now generate 10 non-overlapping rooms that show up correctly in the terminal. Let me recap the key changes:

  • Pass room pointers to makeRoom to modify the original structs
  • Fixed the doOverlap logic to handle the terminal's Y-axis correctly
  • Rewrote the placement loop to check against all existing rooms
  • Added boundary checks to keep rooms inside the dungeon
  • Optimized the grid drawing code

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:49:44