在冒险游戏中随机连接房间

标签 c unix random adventure

我有下面的代码,我随机创建 7 个房间名称,并给它们一个类型(开始、中间、结束)。我现在需要随机连接这些房间,每个房间都有 3 到 6 个连接。我不知道该怎么办。我找到了如何使用位码执行此操作的示例,但正如我的另一篇文章中一样,我仍然不理解该版本。如果有人可以提供帮助,我们将不胜感激。以下是房间的相关代码:

这是我声明房间的地方:

    void createRooms(char *dir) {
//Name of rooms
char *roomNames[] = {
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j"
};
//Filenames for each room
char *filenames[] = {
"a.txt",
"b.txt",
"c.txt",
"d.txt",
"e.txt",
"f.txt",
"g.txt",
"h.txt",
"i.txt",
"j.txt"
};
int rooms[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//Call function to write files for rooms
writeRoomFiles(rooms, dir, filenames, roomNames);
//Call function to randomly connect rooms
//Call function to categorize rooms
categorizeRooms(rooms, dir, filenames, roomNames);
}

然后我想要一个功能来连接这些房间,并将它们的连接放入目录中创建的 .txt 文件中。稍后我还需要向用户提供连接,但我相信我知道如何做到这一点,因为我已经能够提供 roomName 和类型。

最佳答案

你并没有真正描述你如何代表你的联系。您似乎通过将所有内容零散地写入各种文件来组织您的世界,这看起来相当笨拙。

假设您有 7 个房间,通过从 0 到 6 的索引来标识它们。然后您可以将连接表示为 7×7 矩阵 conn,其中 conn[a][ b] != 0 表示房间 ab 之间有连接。如果您想要双向连接,则必须建立 conn[a][b] == conn[b][a]。另一方面,您可以表示与矩阵的单向连接。

想出一种连接房间的好方法,使每个房间与其他房间有三个或更多连接,同时确保所有房间都已连接,这并非易事。

我建议如下:

  • 从一个空矩阵开始,代表七个不相连的房间。
  • 选择两个房间,然后以广度优先的方式遍历这些房间,并在移动过程中建立连接。
  • 对于每个之前未连接的房间,选择另外三个房间。这些房间已经可以建立连接,连接同一个房间两次也没什么坏处。事实上,仅选择未连接的房间将生成一个完整的连接矩阵,其中每个房间有 6 个连接。
  • 可以通过打乱除当前房间之外的所有房间的数组,然后选择前三个房间来选择房间。

这似乎工作得很好,只是你最终可能会得到未连接的房间。您可以通过在洗牌后将未访问的房间移到前面来解决此问题,以便在后期或多或少地强制执行剩余的未访问的房间。

下面的示例程序将这一策略付诸实践:

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

#define MAX_ROOM 7

int conn[MAX_ROOM][MAX_ROOM] = {{0}};

/*
 *      Return a non-negative random value less than n.
 */
int uniform(int n)
{
    return n * (rand() / (double) RAND_MAX);
}

/*
 *      Recursively connect the two rooms
 */
void connect(int visited[], int there, int here)
{
    conn[here][there] = 1;
    conn[there][here] = 1;

    if (visited[here] == 0) {
        int room[MAX_ROOM - 1];     // connection candidate
        int next[MAX_ROOM - 1];     // ditto, orderd to [unvisited, visited]
        int i, j;

        visited[here] = 1;

        // build list of rooms
        for (i = 0; i < MAX_ROOM; i++) room[i] = i;
        room[here] = MAX_ROOM - 1;

        // shuffle rooms
        i = MAX_ROOM - 1;
        while (i) {
            int swap;

            j = uniform(i--);
            swap = room[i];
            room[i] = room[j];
            room[j] = swap;
        }

        // bring unvisited rooms to the front
        j = 0;

        for (i = 0; i < MAX_ROOM; i++) {
            if (visited[room[i]] == 0) next[j++] = room[i];
        }

        // and append the visited rooms at the back
        for (i = 0; i < MAX_ROOM; i++) {
            if (visited[room[i]] != 0) next[j++] = room[i];
        }

        // connect the first three
        for (i = 0; i < 3; i++) {
            connect(visited, here, next[i]);
        }
    }
}

int main(void)
{
    char *room_name[] = { "Eclectic", "Country", "Nautical", "Romantic",
        "Modern", "Urban", "Tropical", "Traditional", "Vintage", "European" };

    int visited[MAX_ROOM] = {0};        // was room visited in BFS?
    int i, j;

    srand(time(NULL));

    // establish two-way connections
    connect(visited, 0, 1);

    // shuffle room names (for fun)
    i = 10;
    while (i) {
        char *p;

        j = uniform(i--);
        p = room_name[i];
        room_name[i] = room_name[j];
        room_name[j] = p;
    }

    // print rooms and connections
    for (i = 0; i < MAX_ROOM; i++) {
        printf("%s\n", room_name[i]);

        for (j = 0; j < MAX_ROOM; j++) {
            if (conn[i][j]) printf(" -> %s\n", room_name[j]);
        }
        printf("\n");
    }

    return 0; 
}

关于在冒险游戏中随机连接房间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30067436/

相关文章:

c++ - 使用 Boost.Random 从种子生成多精度整数

c - posix 线程阻塞信号和解除阻塞

c - C 中的运算符结合性特别是前缀和后缀递增和递减

linux - 在单个目录中查找行数最多的文件

linux - 按时间顺序捕获 STDOUT 和 STDERR

math - 从n维单位单纯形均匀地随机采样

c - 在内存流上使用 ftell() 时的“正确”语义

c - 如何访问作为指针确定的结构体的结构体成员?

linux - 需要 SNMPv3 陷阱唯一内容分隔符

iphone - 在 cocos2d 中使用 NSTimer 制作随机对象