0

I have the following code where I randomly create 7 room names, and give them a type (start, middle, end). I now need to randomly connect these rooms to each have anywhere between 3 and 6 connections. I am at a loss of what to do. I have found an example of how to do it using bitcode, but as in my other post, I still do not understand that version. If anyone could help, that would be greatly appreciated. Below is the relevant code for the rooms:

Here is where the I declare the rooms:

    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);
}

I then want to have a function to connect these rooms, and put their connections into the .txt files created in the directory. I will also need to provide the connections later to the user, but I believe I know how to do this, since I am able to provide roomName and type already.

  • You have not defined what you mean by "connect". – kaylum May 06 '15 at 05:18
  • The code you've shown is hardly relevant to your problem. Don't you have a struct that describes a room? Also: Should your connections be two-way? And all rooms should be connected and be reachable in the end, I guess? – M Oehm May 06 '15 at 05:23
  • I'll add where I define the rooms in the question above. But yes, if A is connected to B, B is connected to A. And yes, they are all connected in the end by some path, but individually each room is to have at least 3 connections and at most connected to each room – user3719014 May 06 '15 at 05:57
  • @Alan Au By connect, I mean Room A connects to B, D, E. Therefore B, D, and E each connect to A. – user3719014 May 06 '15 at 06:02

1 Answers1

0

You don't really describe how you represent your connections. You seem to organise your world by writing everything to various files piecemeal, which looks quite clumsy.

Let's say you have 7 rooms which you identify by an index from 0 to 6. Then you can represent the connections as a 7×7 matrix conn, where conn[a][b] != 0 means there is a connection between rooms a and b. If you want two-way connections, you must establish that conn[a][b] == conn[b][a]. On the other hand, you could represent one-way connections with the matrix.

Coming up with a good way to connect the rooms so that each room has three or more connections to other rooms while at the same time ensuring that all rooms are connected isn't trivial.

I suggest the following:

  • Start with an empty matrix that represents seven unconnected rooms.
  • Pick two rooms and then traverse the rooms in a breadth-first traversal where you establish connections as you go.
  • For each previously unconnected room, pick three other rooms. These rooms can already have connections it doesn't hurt to connect the same room twice. In fact, chosing only unconnected rooms will generate a full connection matrix where each room has 6 connections.
  • The rooms can be picked by shuffling an array of all rooms except the present and then picking the first three.

This seems to work quite well, except that you might end up with unconnected rooms. You can fix that by moving the unvisited rooms to the front after shuffling, so that remaining unvisited rooms are more or less enforced in a late stage.

The example program below puts this strategy into practice:

#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; 
}
M Oehm
  • 28,726
  • 3
  • 31
  • 42
  • Thank you! I have adjusted the code to fit what I already have. I am only getting random connections for one file though (or it's only printing for one file). Also when I call writeConnections, it will not print out Connection 1:, 2:, - i.e. it always says Connection 1: in the output file, even if it's the 4th room connected. I have added my new code to the original question. Please take a look @M Oehm – user3719014 May 07 '15 at 05:17
  • Nevermind! I just found errors in my code that was causing it not to work! Thanks again for all your help! – user3719014 May 07 '15 at 05:30