问题
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.
回答1:
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;
}
来源:https://stackoverflow.com/questions/30067436/connect-rooms-randomly-in-adventure-game