Lost, need help again~

This is a discussion on Lost, need help again~ within the C Programming forums, part of the General Programming Boards category; This might get a little troublesome, please help if u can. Code: // In main.c this line is triggered initial_room ...

  1. #1
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73

    Lost, need help again~

    This might get a little troublesome, please help if u can.



    Code:
    //In main.c this line is triggered
    
          initial_room = load_level(default_level);
    
    //In level.c this line is called, once it is triggered from main
    
    
    // loads a level from a config file and returns a pointer to the starting room
    
    room_t *load_level(char *filename) {
     . . .
     . . .
    return room_array;
    
    //And some where along the main.c, 2-5 lines later this is called
    
        look(0, NULL);
    
    //My code is buggy when it hits this point of main.c
    
    //This is what look() does
    
    // prints out the room description, the exits, and monsters
    int look(int argc, char **argv) {
        room_t *r = the_player.current_room;
        printf("%s\n", r->description);
    
    // My code doesn't print out the room description and the_player is inside the globals.h
    
       init_player(initial_room);
    
    //[B] This is init_player, existing inside main.c
    
    void init_player(room_t *starting_room) {
        the_player.current_room  = starting_room;
        the_player.experience    = 0;
        the_player.level         = get_level(the_player.experience);
        the_player.hp            = 10;
        the_player.max_hp        = 10;
    }
    
    //[B] The starting_room is a pointer to the first room in the room_array[\B]
    
    //This is how I initialize my room array inside level.c 
    
        struct room* rooms = malloc(num_rooms * sizeof(struct room));
        room_array = &rooms;
    Question: What am I doing wrong? Why wouldn't the first room description print itself?

    Code:
    #include "level.h"
    #include "common.h"
    #include "util.h"
    
    // array of directio names. must be consistent with the order of the enum
    // in level.h
    char *direction_names[] = {
        "north",
        "south",
        "east",
        "west",
        "up",
        "down"
    };
    
    
    // loads a level from a config file and returns a pointer to the starting room
    room_t *load_level(char *filename) {
        char buf[2048];
        char *whitespace = " \t\n";
        FILE *levelfile = fopen(filename,"r");
    
        if(levelfile == NULL) {
            printf("Could not open %s\n", filename);
            exit(1);
        }
    
        skip_characters(levelfile, whitespace);
        
        // get the total number of rooms
        fgets(buf,256,levelfile);
        num_rooms = atoi(buf);
    
        skip_characters(levelfile, whitespace);
    
        // allocate an array for all of the room structs to be stored
    	// store the pointer in the global room_array variable
    	/*** YOUR CODE HERE ***/
    
        // Initialize room_array
    	/*** YOUR CODE HERE ***/
    
        skip_characters(levelfile, whitespace);
    
    	// one line at a time, read in room description strings and set 
    	// the appropriate field in each string's corresponding room struct
        while(fgets(buf, 256, levelfile), buf[0] != '\n') {
    		/*** YOUR CODE HERE ***/
        }
    
        skip_characters(levelfile, whitespace);
    
    	// hook up rooms so that exits point to each other appropriately.
    	// exits should also be set to locked or unlocked as necessary
        while(fgets(buf, 256, levelfile), buf[0] != '\n' && !feof(levelfile)) {
            char *words[32];
            tokenizer(buf, words, " \t\n");
            
    		assert(!strcmp("can-go", words[0]) || !strcmp("cant-go", words[0]));
            
    		direction dir;
            switch(words[1][0]) {
                case 'n':
                    dir = NORTH;
                    break;
                case 's':
                    dir = SOUTH;
                    break;
                case 'e':
                    dir = EAST;
                    break;
                case 'w':
                    dir = WEST;
                    break;
                case 'u':
                    dir = UP;
                    break;
                case 'd':
                    dir = DOWN;
                    break;
                default:
                    printf("%s isn't a direction\n", words[1]);
                    assert(false);
            }
    		
    		/*** YOUR CODE HERE ***/
        }
    
        return room_array; // equivalent to a pointer to the first element of the array
    }
    This is main.c
    Code:
    #include "common.h"
    #include "util.h"
    
    char *default_level = "cs61c-world.lvl";
    
    char *usage =
        "usage: %s [LEVEL_FILE]\n"
        "LEVEL_FILE will be loaded if provided, otherwise \"%s\" will be used.\n"
    ;
    
    void init_player(room_t *starting_room) {
        the_player.current_room  = starting_room;
        the_player.experience    = 0;
        the_player.level         = get_level(the_player.experience);
        the_player.hp            = 10;
        the_player.max_hp        = 10;
    }
    
    void tick_world(int elapsed_time, bool player_vulnerable) {
        static int time = 0;
        static int last_attack_time = 0;
        const int attack_period = 15;
    
        time += elapsed_time;
    
        while(time - last_attack_time > attack_period) {
            // monsters attack every attack_period seconds
            if(player_vulnerable) {
                monster_t *attacker;
                mob_iterator_t *iter = make_mob_iterator(&the_player.current_room->mob);
                while((attacker = next_monster(iter))) {
                    // does monster attack? 75% chance...
                    if (rand() % 4 <= 0) {
                        printf("The %s tries to %s you, but misses\n",
                                attacker->name,attacker->attack);   
                        continue;
                    }
    
                    printf("The %s %ss you for %d points of damage\n",
                            attacker->name, attacker->attack, attacker->damage);
                    the_player.hp -= attacker->damage;
                    if(the_player.hp <= 0) {
                        printf("that %s was too much for you. you die.\n", attacker->attack);
                        exit(0);
                    }
                }
                delete_mob_iterator(iter);
            }
    
            last_attack_time += attack_period;
        }
    
        static int last_spawn_time = 0;
        const int spawn_period = 120;
        while(time - last_spawn_time > spawn_period) {
            if(rand() % MONSTER_RARITY == 0) {
                for(int i = 0; i < NUM_DIRECTIONS; i++) {
                    exit_t *exit = (the_player.current_room->exits + i);
                    if(exit->dest != NULL && !exit->locked) {
                        spawn_new_monster(&exit->dest->mob);
                    }
                }
            }
            last_spawn_time += spawn_period;
        }
    }
    
    void print_border(char a, char b, int length) {
        for(int i = 0; i < length; i++)
            putchar(i % 2 == 0 ? a : b);
        putchar('\n');
    }
    
    int main(int argc, char **argv) {
        //load level from cmd line arg
        if(argc > 2) {
            printf(usage, argv[0], default_level);
            exit(1);
        }
    
        char *welcome_message = "Welcome to %s, the CS 61C adventure extravaganza!\n";
        int border_length = strlen(welcome_message) + strlen(argv[0]) - 3;
    
        print_border('-', '=', border_length);
        printf(welcome_message, argv[0]);
        print_border('-', '=', border_length);
    
        room_t *initial_room = NULL;
        if(argc == 1) {
            initial_room = load_level(default_level);
            assert(initial_room != NULL);
            for (int i = 0; i < num_rooms; i++) {
                room_array[i].puzzle.description_fxn = get_puzzle_description(i);
                room_array[i].puzzle.interact_fxn = get_puzzle_solver(i);
            }
        } else {
            initial_room = load_level(argv[1]); // returns a room array or null         
        }
    
        assert(initial_room != NULL);
    
        init_player(initial_room);
        
        printf("You wake up.\n");
        
        look(0, NULL);
    
        // Read-eval-print loop
        for(;;) {
            char buf[256];
            char *words[32];
            int num_words;
            char delimiters[] = " \t\n";
            printf("> "); fflush(stdout);
            fgets(buf, 256, stdin);
            if(feof(stdin)) {
                printf("\n");
                break;
            }
    
            num_words = tokenizer(buf, words, delimiters);
            char *command_name = words[0];
            if(command_name == NULL) continue;
            
            // try to find a command to do
            cmd_fxn_t cmd_to_do = lookup_command(command_name);
            
            if(cmd_to_do != NULL) {
                // and do it
                int elapsed_time = cmd_to_do(num_words, words);
                tick_world(elapsed_time, is_player_vulnerable(command_name));
            } else {
                printf("Huh?\n");
            }
        }
    }
    This is commands.c

    Code:
    #include "commands.h"
    #include "common.h"
    #include "level.h"
    #include "monsters.h"
    #include "game.h"
    
    // A name/command pair
    typedef struct {
        char *name;
        cmd_fxn_t fxn;
        bool player_vulnerable; // Whether or not monsters can attack the player during this command
    } cmd_entry_t;
    
    // commands[] maps command names to command functions
    cmd_entry_t commands[] = {
        {"look",   look,     true},
        {"attack", attack,   true},
        {"dawdle", dawdle,   true},
        {"wait",   dawdle,   true},
        {"quit",   quit,     true},
        {"exit",   quit,     true},
        {"status", status,   true},
        {"help",   help,     true},
        {"cast",   cast,     true},
    
        // TA FUNCTION FOR PUZZLES 
        {"interact",  interact,    false},
    
        // movement aliases
        {"go",     go,       false},
        {"walk",   go,       false},
        {"move",   go,       false},
        {"north",  go_north, false},
        {"n",      go_north, false},
        {"south",  go_south, false},
        {"s",      go_south, false},
        {"east",   go_east,  false},
        {"e",      go_east,  false},
        {"west",   go_west,  false},
        {"w",      go_west,  false},
        {"up",     go_up,    false},
        {"u",      go_up,    false},
        {"down",   go_down,  false},
        {"d",      go_down,  false},
    };
    
    const unsigned int num_commands = sizeof(commands) / sizeof(cmd_entry_t);
    
    // finds the command with the given name string in commands[]
    // returns NULL if the command is not found
    cmd_fxn_t lookup_command(char *name) {
        for(int i = 0; i < num_commands; i++) {
            if(!strcmp(name, commands[i].name)) {
                return commands[i].fxn;
            }
        }
        return NULL;
    }
    
    bool is_player_vulnerable(char *name) {
        for(int i = 0; i < num_commands; i++) {
            if(!strcmp(name, commands[i].name)) {
                return commands[i].player_vulnerable;
            }
        }
        // We have no out-of-bandwidth failure value, so just bail
        assert(false);
        return false; // to avoid a compiler error
    }
    
    // prints the player's status
    int status(int argc, char **argv) {
        printf("level: %d\n", get_level(the_player.experience));
        printf("exp:   %d\n", the_player.experience);
        printf("hp:    %d/%d\n", the_player.hp, the_player.max_hp);
        i_love_additional_status_its_so_bad();
        return STATUS_TIME;
    }
    
    // attacks the first monster of monster type argv[1]
    int attack(int argc, char **argv) {
        if(argc == 1) {
            printf("Please specify a monster to attack.\n");
            return 0;
        }
    
        // find the monster
        monster_t *target = find_monster(&the_player.current_room->mob, argv[1]);
        
        // give up if we can't find it
        if(target == NULL) {
            printf("There's no %s here...\n", argv[1]);
            return 0;
        }
    
        // inflict damage
        int damage_amount = the_player.level;
        printf("You attack the %s for %d damage...\n", target->name, damage_amount);
        damage(target, damage_amount);
        return ATTACK_TIME;
    }
    
    // waits for the specified number of seconds (15 by default)
    int dawdle(int argc, char **argv) {
        int amount = argc == 2 ? atoi(argv[1]) : DAWDLE_DEFAULT_TIME;
        printf("You %s for %d seconds...\n", argv[0], amount);
        return amount;
    }
    
    // prints out the room description, the exits, and monsters
    int look(int argc, char **argv) {
        room_t *r = the_player.current_room;
        printf("%s\n", r->description);
    
        if(r->puzzle.description_fxn != NULL) {
            r->puzzle.description_fxn(argc, argv);
        }
    
        int num_exits = 0;
        for(int i = 0; i < NUM_DIRECTIONS; i++) {
            if(r->exits[i].dest != NULL) {
                num_exits++;
            }
        }
    
        switch(num_exits) {
            case 0:
                break;
            case 1:
                for(int i = 0; i < NUM_DIRECTIONS; i++) {
                    if(r->exits[i].dest != NULL) {
                        printf("There is an exit %s%s%s%s.\n", 
                                (i == UP || i == DOWN) ? "" : "to the ",
                                direction_names[i],
                                (i == UP || i == DOWN) ? "wards" : "",
                                r->exits[i].locked ? " (locked)" : "");
                        break;
                    }
                }
                break;
            default:
                printf("There are exits");
                int exits_remaining = num_exits;
                int i = 0;
                while(exits_remaining) {
                    if(r->exits[i].dest != NULL) {
                        exits_remaining--;
                        printf(" %s%s%s", direction_names[i],
                               r->exits[i].locked ? " (locked)" : "", 
                               exits_remaining == 1 ? " and" :
                               exits_remaining == 0 ? ".\n"   :
                                                       ","
                        );
                    }
                    if(exits_remaining == 0) break;
                    i++;
                }
        }
    
        if(num_monsters(&r->mob) > 0) {
            print_monsters(&r->mob);
        }
    
        return LOOK_TIME;
    }
    
    // calls the puzzle function for the current room
    int interact(int argc, char **argv) {
    	if (the_player.current_room->puzzle.interact_fxn != NULL) {
    		return the_player.current_room->puzzle.interact_fxn(argc, argv);
    	} else {
    		printf("There is no puzzle in this room.\n");
            return INTERACT_TIME;
    	} 
    }
    
    
    // quit the game
    int quit(int argc, char **argv) {
        printf("goodbye!\n");
        exit(0);
    }
    
    int help(int argc, char **argv) {
        printf("available commands:\n");
        unsigned int num_commands = sizeof(commands) / sizeof(cmd_entry_t);
        for (int i = 0; i < num_commands; i++) {
            printf("\t%s\n",commands[i].name);   
        }   
        return HELP_TIME;
    }
    
    
    // go moves the player from room to room by updating the_player.current_room
    // and returns the amount of time movement has taken
    // the argc and argv[] arguments are passed similarly to command-line arguments
    // a typical "go" command would be:
    //    > go north
    // and would be passed in as:
    //    argc = 2, argv = {"go", "north"}
    int go(int argc, char **argv) {
    	/*** YOUR CODE HERE ***/
    	printf("What's this!? You can't move! You'll need to implement the go() function before you can get out of this place...\n");
        
        // print the room description
        assert(look(0, NULL) == 0); // we're assuming that look doesn't take any time
        return MOVE_TIME;
    }
    
    // cast() handles spellcasting
    // uses get_spell() to check level_table[] in game.c for a spell name that matches argv[1] 
    // and acquire the corresponding function pointer
    // uses get_spell_level() to check that the spell's level is <= the player's level before casting
    // this function should return whatver the spell itself returns.
    int cast(int argc, char **argv) {
        // for part 3, remove this line
        printf("Cast? There's no such thing as magic...\n");
        return 0;
    }
    PLS help!
    Last edited by NoobieGecko; 02-16-2008 at 10:09 PM.

  2. #2
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    Because i always liked this games i 'll try.
    I'll start working on it, and fill you up with details later in 30 minutes at least.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  3. #3
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    So far i have done this:
    Code:
        // allocate an array for all of the room structs to be stored
        // store the pointer in the global room_array variable
    
        room_array = malloc(num_rooms * sizeof(*room_array));
        // Initialize room_array   <- To what? Clear memory?
    
        memset(room_array, 0, num_rooms * sizeof(*room_array));
    Code:
    
        // Before the while you need a counter.
        cur_room = 0;	// The room being read in.
    
        while(fgets(buf, 256, levelfile), buf[0] != '\n') {
    		/*** YOUR CODE HERE ***/
    
    	// I recall you had a pointer that was pointing at the description, named rest
    	if(rest[strlen(rest)-1] == '\n')
    		rest[strlen(rest)-1] = 0;
    	room_array[cur_room]->description = malloc(strlen(rest)+1);
    	strcpy(room_array[cur_room]->description, rest);
    	cur_room++;
        }
    WAIT A MINUTE!
    Is room_array an array of POINTERS to room_t structures???
    This is very important, as the allocation needs to be done differently.
    Please respond for further assistance.
    Last edited by xuftugulus; 02-16-2008 at 11:17 PM.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  4. #4
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    well i tested it, and i got an error with -> operators
    Code:
    level.c: In function `load_level':
    level.c:59: error: incompatible types in assignment
    level.c:69: error: invalid type argument of `->'
    level.c:70: error: invalid type argument of `->'
    level.c:72: error: invalid type argument of `->'
    level.c:73: error: invalid type argument of `->'
    level.c:75: error: invalid type argument of `->'
    level.c:76: error: invalid type argument of `->'
    level.c:157: error: invalid type argument of `->'
    level.c:159: error: invalid type argument of `->'
    level.c:161: error: invalid type argument of `->'
    level.c:163: error: invalid type argument of `->'
    and it's because:

    room_t *room_array;

    should be **room_array?

    what i have is actually this:

    struct room** rooms = (room_t **) malloc(num_rooms * sizeof(room_t *));

    which kind of works~

    (i sent u a pm)

  5. #5
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    wait wait wait!!

    room_array points to the first element of a data structure where that structure is an array of structures of (room_t)!

  6. #6
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    No need of pointer to pointer
    just instead of
    room_array[cur_room]->description
    use
    room_array[cur_room].description

    because [] already dereferences the pointer and gives you the struct
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  7. #7
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    exactly but this is what i found out later
    Code:
    int look(int argc, char **argv) {
        room_t *r = the_player.current_room;
        printf("&#37;s\n", r->description);
    which calls r->description (r is primarily room_array, the first element of the array of room structs) is this right?

  8. #8
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    r is pointer to the first element
    so r->description is equivalent to
    r[0].description

    as well as r[i].description
    you can substitute with
    (r+i)->description

    but the "array" notaition is more readable, I think
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by NoobieGecko View Post
    exactly but this is what i found out later
    Code:
    int look(int argc, char **argv) {
        room_t *r = the_player.current_room;
        printf("%s\n", r->description);
    which calls r->description (r is primarily room_array, the first element of the array of room structs) is this right?
    r is a pointer to a room_t: the declaration's right there in the function. So here you need the -> to get the description in the object pointed to by r. (And you need it that way 'cuz that's what the_player holds: not the room itself, but a pointer to the room that the player is in.)

    I think the problem xuf was pointing out was this:
    // Initialize room_array
    /*** YOUR CODE HERE ***/
    At no point, that I can see anyway, do you actually read data from the file and put it into this room_array of yours. (Maybe I just missed it.)

  10. #10
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    Quote Originally Posted by NoobieGecko View Post
    exactly but this is what i found out later
    Code:
    int look(int argc, char **argv) {
        room_t *r = the_player.current_room;
        printf("&#37;s\n", r->description);
    which calls r->description (r is primarily room_array, the first element of the array of room structs) is this right?
    Code:
     // the struct representing a player
    typedef struct {
         room_t *current_room;    // In the player is stored a pointer to a room_t
         unsigned experience;
         unsigned level;
         int hp;
         int max_hp;
    } player_t;
    Therefore, when accessing through the player_t, you need to use -> , also:
    In function calls that need a room_t it is usual to pass a pointer to a room_t because otherwise a copy of the entire struct would be passed which usually is not wanted.

    I managed to compile this, with the original data file of the game.
    Code:
        // allocate an array for all of the room structs to be stored
    	// store the pointer in the global room_array variable
    	/*** YOUR CODE HERE ***/
    	room_array = malloc(num_rooms * sizeof(*room_array));
        // Initialize room_array
    	/*** YOUR CODE HERE ***/
    	int room_idx = 0;  /* MOVE THESE 2 TO THE DECLARATIONS AT THE START*/
    	char *c;
        skip_characters(levelfile, whitespace);
    
    	// one line at a time, read in room description strings and set 
    	// the appropriate field in each string's corresponding room struct
        while(fgets(buf, 256, levelfile), buf[0] != '\n') {
    		/*** YOUR CODE HERE ***/
    		room_array[room_idx].room_id = atoi(buf);
    		c = buf;
    		assert(strchr(whitespace,*c)==NULL);
    		while(*c!=' ' && *c!='\n' && *c!='\t') c++;	// Skip the digits of the room id. This covers you even if more than 1...
    		if(c[strlen(c)-1] == '\n')
    			c[strlen(c)-1] = 0;						// Kill the newline
    		room_array[room_idx].description = malloc(strlen(c)+1);   // Make room for copying the description
    		strcpy(room_array[room_idx].description, c);   //Read the reference for strcpy. It copies 0 terminated strings. Memory handled by user.
    // Another way to copy: room_array[room_idx].description = strdup(c);
    //printf("Got id: %d, descr: %s\n", room_array[room_idx].room_id, room_array[room_idx].description);
    		room_idx++;
        }
    Last edited by xuftugulus; 02-17-2008 at 12:32 AM.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  11. #11
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    sorry, i'm am trying to be less confusing as i can, this is so far what i have written
    Code:
    #include "level.h"
    #include "common.h"
    #include "util.h"
    #include "string.h"
    
    // array of directio names. must be consistent with the order of the enum
    // in level.h
    char *direction_names[] = {
        "north",
        "south",
        "east",
        "west",
        "up",
            "down"
    };
    
    
    // loads a level from a config file and returns a pointer to the starting room
    room_t *load_level(char *filename) {
        char buf[2048];
        char *whitespace = " \t\n";
        FILE *levelfile = fopen(filename,"r");
    
        if(levelfile == NULL) {
    	printf("Could not open &#37;s\n", filename);
    	exit(1);
        }
    
        skip_characters(levelfile, whitespace);
    
        // get the total number of rooms
        fgets(buf,256,levelfile);
        num_rooms = atoi(buf);
    
        skip_characters(levelfile, whitespace);
    
        // allocate an array for all of the room structs to be stored
        // store the pointer in the global room_array variable
    
        struct room** rooms = (room_t **) malloc(num_rooms * sizeof(room_t *));
        room_array = &rooms;
        
        for (int j = 0; j < num_rooms; j++)
    	{
    	    rooms[j] = malloc(sizeof(room_t*));
    	}
    
        
        for (int i = 0; i < num_rooms-1; i++)
    
    	{
    	   
    	    rooms[i]->room_id = NULL;	    
    	    rooms[i]->description = NULL;
    	    for (int j = 0; j < 6; j++){
    		rooms[i]->exits[j].dest = NULL;
    		rooms[i]->exits[j].locked = 0;
    	    }
    	    rooms[i]->puzzle.description_fxn = NULL;
    	    rooms[i]->puzzle.interact_fxn = NULL;    
    	}
        skip_characters(levelfile, whitespace);
        
        // one line at a time, read in room description strings and set
        // the appropriate field in each string's corresponding room struct
    
     
        
        int t = 0; 
        
        while(fgets(buf, 256, levelfile), buf[0] != '\n') {
         	char *numptr = NULL;
    	char *newline = strchr(buf, '\n');
    	if (newline)
    	    {
    		*newline = '\0';
    	    }
    	
    	numptr = strtok(buf, whitespace);
          
    	if (numptr != NULL) {
    	    rooms[t]->room_id = atoi(&buf[0]);
    	    //	    char temp[] = malloc(sizeof(&buf[2]));
    	    //strcpy(NULL, &buf[2]);
    	    // printf("%s\n", &temp);
    	    rooms[t]->description = "I dont know how to do this";
    	    //printf("%s", rooms[t]->description);
    	    t++;
    	}
    	
    	    
        }
       
        skip_characters(levelfile, whitespace);
    	    
        // hook up rooms so that exits point to each other appropriately.
        // exits should also be set to locked or unlocked as necessary
        while(fgets(buf, 256, levelfile), buf[0] != '\n' && !feof(levelfile)) {
    	char *words[32];
    	tokenizer(buf, words, " \t\n");
           
    	assert(!strcmp("can-go", words[0]) || !strcmp("cant-go", words[0]));
    
    	direction dir;
    	switch(words[1][0]) {
    	case 'n':
    	    dir = NORTH;
    	    break;
    	case 's':
    	    dir = SOUTH;
    	    break;
    	case 'e':
    	    dir = EAST;
    	    break;
    	case 'w':
    	    dir = WEST;
    	    break;
    	case 'u':
    	    dir = UP;
    	    break;
    	case 'd':
    	    dir = DOWN;
    	    break;
    	default:
    	    printf("%s isn't a direction\n", words[1]);
    	     assert(false);
    	}
           
    	int FROM_ROOM;
    	int TO_ROOM;
    	FROM_ROOM = atoi(&words[2][0]);
    	TO_ROOM = atoi(&words[3][0]);
    	rooms[FROM_ROOM]->exits[TO_ROOM].dest = &rooms[TO_ROOM];
    	if (strcmp("cant-go", words[0])) {
    	    rooms[FROM_ROOM]->exits[TO_ROOM].locked = 1;
    	}
           	rooms[TO_ROOM]->exits[FROM_ROOM].dest = &rooms[FROM_ROOM];
    	if (strcmp("can-go", words[0])) {
    	    rooms[FROM_ROOM]->exits[TO_ROOM].locked = 0;
    	
    	}	
        }
        //    printf("%s", rooms[0]->description);
        return room_array; // equivalent to a pointer to the first element of the array
    }
    the problem i'm having is right hereeeeeee
    Code:
        while(fgets(buf, 256, levelfile), buf[0] != '\n') {
         	char *numptr = NULL;
    	char *newline = strchr(buf, '\n');
    	if (newline)
    	    {
    		*newline = '\0';
    	    }
    	
    	numptr = strtok(buf, whitespace);
          
    	if (numptr != NULL) {
    	    rooms[t]->room_id = atoi(&buf[0]);
    	    //	    char temp[] = malloc(sizeof(&buf[2]));
    	    //strcpy(NULL, &buf[2]);
    	    // printf("%s\n", &temp);
    	    rooms[t]->description = "I dont know how to do this";
    	    //printf("%s", rooms[t]->description);
    	    t++;
    	}
    	
    	    
        }
    how do u store the description inside rooms[t]->description?

  12. #12
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    oh so u don't necessarily need "**"?

    brb: as i try to compile this, there's the last part of the main code that gives me segmentation faults, fixin it atm...
    Last edited by NoobieGecko; 02-17-2008 at 12:19 AM.

  13. #13
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    You have confused the nested structures.
    Pleases look at the types.
    A room_t object has an exit_t object, which contains a pointer to a room_t and a boolean flag.
    You wake up.
    You are in a cold, concrete-floored room. There are no windows and almost no light. The only thing you can make out is the faint outline of a door to the south.
    There is an exit to the south.
    >
    That's on my machine.
    And here's the code i used.
    Code:
    		bool locked = strcmp("can-go",words[0]);   // Returns 0 when equal same as false for 'C'
    		int from,to;
    		from = atoi(words[2]);   // No need for & it's a nice string words[2] :)
    		to = atoi(words[3]);
    /* Not the check to avoid indexing out of bounds in our array */
    		if( from<0 || from>num_rooms || to<0 || to>num_rooms)
    		{
    			printf("Invalid number detected. Skipping line: From: &#37;d - To: %d\n",from,to);
    			continue;
    		}
    /* The trick is that the only place you need to use & is to store the pointer in the exit structure */
    		room_array[from].exits[dir].dest = &room_array[to];
    		room_array[from].exits[dir].locked = locked;
    I think i read the file just fine. The advice, have the header files always open at the definition of
    the types. When you see room_t *x, then x->description is the string. When you see room_t then x.description is the string. When you see room_array[i] this is a full struct, not a pointer to it.
    how do u store the description inside rooms[t]->description?
    Check my post it's modified.
    I had made a typo! It must be strlen(c)+1, i had written strlen(c)-1 which means two less bytes of memory. I didn't get any segmentation fault and missed it. My bad there. Sorry.
    Last edited by xuftugulus; 02-17-2008 at 12:34 AM.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  14. #14
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    thats the right output, thanks xuft, but the problem i'm having now is a segfault, and when i run gdb and i backtrace, i pick up this

    Code:
           room_array[room_idx].description = malloc(strlen(c)-1);

  15. #15
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    you should check the room_idx value - it should be in range 0,num_rooms -1

    If it is not - you access memory out of bound which can lead to crash
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. (Date dt)??? I'm lost...
    By patricio2626 in forum C++ Programming
    Replies: 3
    Last Post: 06-24-2006, 11:49 AM
  2. I lost my laptop, DVD and money
    By Sang-drax in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 10-01-2004, 07:13 PM
  3. lost disk
    By Benzakhar in forum Linux Programming
    Replies: 7
    Last Post: 01-11-2004, 05:18 PM
  4. Lost ID number
    By ripper079 in forum C++ Programming
    Replies: 13
    Last Post: 10-04-2002, 12:51 PM
  5. API, LOST... help
    By Unregistered in forum Windows Programming
    Replies: 5
    Last Post: 03-13-2002, 02:19 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21