0

I am working on a text adventure game in C which has become the bane of my existence. I'm working through it and making progress, however, I'm having one big problem that I can't seem to figure out.

Here's the deal: I need to create 7 files and then print the information about each room in each file.

An example of one file would be:

    ROOM NAME: Chapel
    CONNECTION 1: Arenas
    CONNECTION 2: Pantry
    CONNECTION 3: Forest
    ROOM TYPE: START_ROOM

Each file should have a different name, different connections, and a different type. However, when I run my program, it prints the exact same thing in every file.

My program is pretty long so I'm not sure where the issue is, so I'll just write where I create the files and call the function to write into it--if you guys need to see more let me know. This is also just portions of the main and createRoom() function.

    int main() {

       int buffer = 260;
       int pid = getpid();
       char *dirName = malloc(buffer);
       char *prefix = "bonnc.rooms.";
       snprintf(dirName, buffer, "%s%d", prefix, pid);

       struct stat st = {0};
       if (stat(dirName, &st) == -1) {
            mkdir(dirName, 0777);
       } 

       char rm1[260];
       snprintf(rm1, 260, "%s/room1.txt", dirName);
       roomFile1 = fopen(rm1, "w+");
       createRoom(roomFile1, connections1, 1);

       char rm2[260];
       snprintf(rm2, 260, "%s/room2.txt", dirName);
       roomFile2 = fopen(rm2, "w+");
       createRoom(roomFile2, connections2, 2);

       fclose(roomFile1);
       fclose(roomFile2);
    }

    void createRoom(FILE *fp, char *conn[6], int roomNumber) {
             srand(time(NULL));
             int randName = rand() % 10;
             int randType = rand() % 3;
             int randConnections = rand() % (6 -2) +2;

             int j = 0;
             for (j = 0; j <= randConnections; j++) { //I do have additional code in here for testing of duplicates, but that isn't essential to the problem
                 randomRoom = rand () % 10;
                 conn[j] = names[randomRoom];
             } 

             fprintf(fp, "ROOM NAME: %s\n", names[randName]); //names & randName are declared earlier
         int t = 0;
         for (t = 0; t <= randConnections; t++) {  //randConnections defined earlier
             fprintf(fp, "CONNECTION %d: %s\n", t+1, conn[t]; //conn[t] defined earlier
         }
         fprintf(fp, "ROOM TYPE: %s\n", types[randType]); //types & randType defined earlier
   }

So when I call createRoom with room1 and room2, the exact same things are printed in each file, even though a new random name, random connections, and random type should be generated each time the createRoom function is called.

Any ideas? I'm new to C and still learning, so if there's any messy code that I should change, let me know. Thank you!

Update: the random numbers aren't global, they are in the createRoom() function. I added this code, as well as a portion of how connections[1] & connections[2] are populated. Hopefully this information helps clear things up!

clb
  • 77
  • 1
  • 5
  • 1
    Nothing shown changes `randName` or `randType`, so that explains why those 2 don't change... Without seeing how `connections1` and `connections2` are populated, it is impossible to tell what is going on. – John3136 Nov 02 '15 at 06:05

1 Answers1

2

Revised answer for revised question

void createRoom(FILE *fp, char *conn[6], int roomNumber) {
    srand(time(NULL));

You should not call srand() more than once; doing so undoes the randomness. See srand() — why call it only once?

Unless you are lucky enough that room 1 is created in the dying microseconds of one second and room 2 is created in a new second, you reseed the random number generator with the same seed, so it produces the same numbers each time.

Original answer

You seem to have a global variable randName which is actually a number indexing into an array of names. You don't show where it gets set, so it is presumably the same value each time you call the createRoom() function, so it produces the same output each time.

There's also a global variable randType that likewise doesn't change. And there's a pair of arrays connections1 and connections2 in main() that are used but you don't show the code that sets them, either.

Given the context shown, you clearly aren't changing the values of these variables between calls to the createRoom() function, so it produces the same output each time it is called.

Oh, and there are reasons why people don't like global variables — this sort of problem is one of them.

As to messy code, apart from the problems already listed, it is a bit inconsistent to use malloc() to allocate dirName but then use fixed size allocations for rm1 and rm2. You may as well use a fixed size for dirName too. Nominally, you should check for buffer overflows, but the size of 260 seems to be plenty big enough for the uses shown.

You should always check that fopen() succeeds. Nominally, you should check that writes succeed, but that rule is more often ignored than not. You should always check that reads succeed; that is a rule that should never be broken.

You should always check that memory allocation calls succeed. Your program will usually crash if you don't, normally at the most inconvenient moment. If you over-allocate space, you may still run into problems on systems such as Linux which allow for optimistic memory allocation — the OOM Killer (Out of Memory Killer) may come after your process even though malloc() succeeded.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I added some additional code that explains it more. The random numbers weren't actually global--sorry about that--they are in that function. I also added the block of code that fills the connections array. – clb Nov 02 '15 at 06:38
  • There's a reason that one of the close reasons for "it doesn't work" requests an MCVE ([How to create a Minimal, Complete, and Verifiable Example?](http://stackoverflow.com/help/mcve)) — or, equivalently, an SSCCE ([Short, Self-Contained, Correct Example](http://sscce.org/)). It means that people can compile the code and see what's going on without having to guess. Please remember for next time! – Jonathan Leffler Nov 02 '15 at 06:40
  • Sorry. Thanks for the help. It's working now. – clb Nov 02 '15 at 07:02