Welcome to the Builder Academy

Question Can anyone assist with an appendNode() problem?

More
20 Oct 2022 23:44 #10207 by Bodhi
In file "handler.c", we have this "obj_to_room" function. It takes any object dropped in the room and adds it to the linked list "world[room].contents". This creates a stack of objects, with the first object at the bottom (head) of the stack, the second object stacked on top the first, and so on. This is the default behavior for linked lists in C.

In file "act.informative.c" we have the "look_at_room" function. That calls the "list_obj_to_char" function. This uses a "for loop" to read the list/stack.

When using a "for loop" to read the list/stack/node, it does so from top (tail) to bottom (head). This, too is the default behavior in C. Therefore, objects dropped in the room are displayed with the most recently dropped object at the top of the list and the first object dropped at the bottom.

That's what causes this issue:
www.tbamud.com/forum/2-general/5530-has-anyone-else-noticed

I think the best solution is coding a function using "appendNode" to add objects at the tail (top) of the list instead of its head (bottom). 

Toward that end, I've changed this code:
Code:
/* put an object in a room */ void obj_to_room(struct obj_data *object, room_rnum room) {   if (!object || room == NOWHERE || room > top_of_world)     log("SYSERR: Illegal value(s) passed to obj_to_room. (Room #%d/%d, obj %p)",     room, top_of_world, (void *)object);   else {     object->next_content = world[room].contents;     world[room].contents = object;     IN_ROOM(object) = room;     object->carried_by = NULL;     if (ROOM_FLAGGED(room, ROOM_HOUSE))       SET_BIT_AR(ROOM_FLAGS(room), ROOM_HOUSE_CRASH);   } }

to this code:
Code:
/*put an object in a room */ void obj_to_room(struct obj_data *object, room_rnum room)  {     if (!object || room == NOWHERE || room > top_of_world)     {       log("SYSERR: Illegal value(s) passed to obj_to_room. (Room #%d/%d, obj %p)",         room, top_of_world, (void*) object);     }     else     {       /*function to add objects at the tail of the list instead of its head*/       /* everything hinges on this single line and I probably have it all kinds of wrong*/       /*struct node* appendNode(struct node** head, int key)*/       struct world[room].contents* appendNode(struct world[room].contents** object, room_rnum room)       {            /* special case for length 0         if (object == NULL)         {           *object = world[room].contents;         }         else         {          /* locate the last node           while (object->next_content != NULL)           {             object = object->next_content;           }           object->next_content = world[room].contents;           world[room].contents = object;           IN_ROOM(object) = room;           object->carried_by = NULL;           if (ROOM_FLAGGED(room, ROOM_HOUSE))             SET_BIT_AR(ROOM_FLAGS(room), ROOM_HOUSE_CRASH);         }       }     } }

When attempting to compile, I get:
Code:
handler.c: In function ‘obj_to_room’: handler.c:681:19: error: expected identifier or ‘(’ before ‘[’ token   681 |       struct world[room].contents* appendNode(struct world[room].contents** object, room_rnum room)       |                   ^ make[1]: *** [<builtin>: handler.o] Error 1 

Ok, I suspect there's all sorts of things wrong with thal line, but I don't know how to fix it.

Although I'm reasonably well versed in multiple programming languages, C is not one of them. When it comes to the idiosyncrasies and technical fine points of the language, I know nothing. So, please forgive my ignorance.

At any rate, I'm hoping that some brilliant coder will be kind enough to help out.
 

Please Log in or Create an account to join the conversation.

More
21 Oct 2022 21:29 #10208 by thomas
Yes, you're going the wrong way there :)

Try this:
Code:
else { - object->next_content = world[room].contents; - world[room].contents = object; + if (world[room].contents == NULL) // here, we have an empty list. + world[room].contents = object; // Just add it. + else { + struct obj_data *i = world[room].contents; // define a temporary pointer + while (i->next_content != NULL) i = i->next_content; // find the first without a next_content + i->next_content = object; // add it at the end + } + object->next_content = NULL; // mostly for sanity. Should do nothing. IN_ROOM(object) = room;
The following user(s) said Thank You: Bodhi

Please Log in or Create an account to join the conversation.

More
21 Oct 2022 21:30 #10209 by thomas
btw - this is browser code, so typos may exist.
The following user(s) said Thank You: Bodhi

Please Log in or Create an account to join the conversation.

More
22 Oct 2022 10:38 #10210 by Bodhi
Yeah, there's so many things wrong with my code up there, nested functions, no calll to the function, etc. Anyway, here's the code I have now:
Code:
/* put an object in a room */ void obj_to_room(struct obj_data *object, room_rnum room) {   if (!object || room == NOWHERE || room > top_of_world){     log("SYSERR: Illegal value(s) passed to obj_to_room. (Room #%d/%d, obj %p)",     room, top_of_world, (void *)object);   }     else {       if (world[room].contents == NULL){  /// here, we have an empty list.           world[room].contents = object; /// Just add it.     }         else {             struct obj_data *i = world[room].contents; /// define a temporary pointer             while (i->next_content != NULL) i = i->next_content; /// find the first without a next_content             i->next_content = object; /// add it at the end         }     object->next_content = NULL; /// mostly for sanity. Should do nothing.     IN_ROOM(object) = room;     object->carried_by = NULL;     if (ROOM_FLAGGED(room, ROOM_HOUSE))       SET_BIT_AR(ROOM_FLAGS(room), ROOM_HOUSE_CRASH);     } }
 
This works perfectly! Thank you so very much. Your assistance is sincerely appreciated.

Please Log in or Create an account to join the conversation.

Time to create page: 0.289 seconds