Pages: [1]
  Print  
Author Topic: A data structure for everything?  (Read 3046 times)
jonoerik
Champion
***
Posts: 196



View Profile
« on: November 18, 2009, 07:36:49 AM »

Just a brief question about general roguelike coding.  I've been writing my own roguelike, and I've had to pass lots of parameters to each function;
Code:
int player_move(struct player_t *player, struct map_t *map, TCOD_list_t *other actors, dx, dy);
I was wondering if it's a good idea to simply combine all the game variables into a single data structure;
Code:
int player_move(struct game_t *game, dx, dy);
to cut down the number of parameters passed to each function.
I'm using C, not C++, so OOP stuff doesn't really apply here.

Are there other ways of managing this?
Should I be declaring the game data as a global variable instead?

On a completely unrelated note, a question for all you C coding experts
should I use
Code:
struct abc {};
or
Code:
typedef struct {} abc;
for structures

Thanks in advance for the help!
Logged
jice
Administrator
Master
*****
Posts: 1456


View Profile WWW
« Reply #1 on: November 18, 2009, 10:08:39 AM »

Technically, if there's only one game_t structure, you'd better have it as global variable rather than putting it in every function. There's nothing wrong with global vars as long as you don't use hundreds of them even if some fundamentalist software architects try to eradicate them.

Concerning structs, I personally prefer the typedef version because you don't have to put struct keywords everywhere, but there's nothing wrong with both usage...
Logged
jonoerik
Champion
***
Posts: 196



View Profile
« Reply #2 on: November 18, 2009, 12:28:18 PM »

Thanks for the advice.
My main problem with typedef'ing structs is that I've had trouble with the prototypes for them.
Code:
typedef struct abc;
doesn't seem to work
Logged
jice
Administrator
Master
*****
Posts: 1456


View Profile WWW
« Reply #3 on: November 18, 2009, 03:06:02 PM »

You should use :
Code:
typedef struct { ... fields declaration... } mystruct_t ;
mystruct_t my_var;

If you need recursion ( a struct containing a field which is a pointer to the same struct ), use this :
Code:
typedef struct _mystruct_t { struct _mystruct_t *ptr; } mystruct_t ;
mystruct_t my_var;

You can also separate the typedef and the struct declaration :
Code:
struct _mystruct_t { ... fields declaration... };
typedef struct _mystruct_t mystruct_t;
mystruct_t my_var;
Logged
jonoerik
Champion
***
Posts: 196



View Profile
« Reply #4 on: November 25, 2009, 09:49:54 AM »

I've been having some problems with the following setup:

Code:
file1.h
#include "file2.h"
typedef struct data_s {
    otherdata_t *a;
} data_t;

Code:
file2.h
typedef struct otherdata_s {
    //Variables, etc
} otherdata_t;

void do_stuff()
{
    data_t *b;
}

The problem is with the placement of the include statement in the first file.  If its before the structure declaration, then the function do_stuff in the second file doesn't compile because the definition of the structure data_t hasn't been reached.  If I place the include statement after the structure declaration, then the structure data_t doesn't compile because the compiler hasn't reached the definition of otherdata_t.

Sorry if this example isn't very clear, but hopefully this conveys the problem I'm having.  I think the answer lies in using something like this:
Code:
file1.h
struct data_s; //struct prototype
#include "file2.h"
typedef struct data_s {
    otherdata_t *a;
} data_t
But this wouldn't allow the typedef'd data_t to be used in file2.h, only 'struct data_s'.  Is there a way of getting the compiler to recognize that I want data_t to be typedef'd to data_s, without actually giving the fields declaration until later?  Or should I just forget about typedefing by structs?
Logged
jice
Administrator
Master
*****
Posts: 1456


View Profile WWW
« Reply #5 on: November 25, 2009, 01:42:11 PM »

The code below should compile, but I don't see why you want to use a data structure in a function before declaring it... Also you shouldn't put code in header files. Only in .c files. headers are just here to declare things (data structures and function prototypes).

file1.h :
Code:
typedef struct data_s data_t;
typedef struct otherdata_s otherdata_t;
struct data_s {
    otherdata_t *a;
};

file2.h :
Code:
struct otherdata_s {
    //Variables, etc
};

void do_stuff()
{
    data_t *b;
}
Logged
jonoerik
Champion
***
Posts: 196



View Profile
« Reply #6 on: November 25, 2009, 11:57:35 PM »

Thanks.  I think I may have to have another look at how to set out C programs properly.  I'll probably look into downloading the sources for some other C roguelikes, and learn from the layout of those.
Logged
jonoerik
Champion
***
Posts: 196



View Profile
« Reply #7 on: November 26, 2009, 06:37:27 AM »

Yep, it seems I've been abusing header structure.  How embarrassing!  I'm struggling to find any decent and clear resources about how this stuff really works, but I've downloaded some of the games from the libtcod projects page, so they should provide the necessary information.

I've also been thinking about leaving C for C++.  As much as I prefer the former, I'm really wishing I had OOP to work with.  The thing that originally made me dislike C++ was that, when learning it as my first ever decent programming language, the way iostream overrides >> and << confused the heck out of me.  At least I now understand how that particular concept works.  Smiley
Logged
jice
Administrator
Master
*****
Posts: 1456


View Profile WWW
« Reply #8 on: November 26, 2009, 11:27:42 AM »

Surely C is cleaner than C++ but if you're using only basic OOP features of C++ as I do, it's worth switching to it because the code is lighter, easier to read.
For a good project template in C++, with the proper header structure and so on, I would suggest you read this canceled tutorial :
http://code.google.com/p/thecave/wiki/toc
It's my conception of clean C++ coding but it might not be everyone's. Also you might want to use Code::Blocks instead of hand made makefiles but be aware that the header structure I'm using (every headers included in a root main.hpp header) is not adapted to IDE because every single change in a header triggers the recompilation of the whole project. That's where makefiles without header dependencies are supperior because you can recompile only when you know it's required (only when you change a data structure).
Logged
jonoerik
Champion
***
Posts: 196



View Profile
« Reply #9 on: November 26, 2009, 11:28:37 PM »

For a good project template in C++, with the proper header structure and so on, I would suggest you read this canceled tutorial...
Ah, thanks.  Thats pretty much what I was looking for.  I haven't tried any of it out yet, but it's definitely going in my to-read list.

As for IDE vs Editor, I'm thinking of switching to PSPad.  As much as I've enjoyed using an IDE, I think I'd learn more, and have more control, with a more traditional editor.
Logged
Pages: [1]
  Print  
 
Jump to: