Structures instead of Globals
Hello. I'm writing a Chess engine and I have a lot of global variables, such as the board array, an array of moves available, an array of pieces owned by each player, and array of directions in which the King is attacked... and so on. It is important that these variables can be written as well as read by various parts of the program (so passing local variables down through functions is out).
I was thinking of replacing them with pointers, for speed reasons and I've heard that global variables are considered bad design. I was thinking of create a few structures and passing pointers to them through functions in order to emulate the capability of the globals, whilst being faster and better organised.
So is this a good idea, and is there anything special I need to do? For example is it okay to just send through a pointer to the whole structure? I'm not very experianced with pointers.
Thanks.
I suggest you read up on pointers, and make sure you are using OOP programming to make everything easier on you (unless you're not having any problems with straightforward programming). I'd suggest you pick up a book on C++, and make sure to learn the STL and Boost libraries. That should get you going in the right direction.
As I said above, OOP will help you get away from global variables, and make your programs much more organized.
And yes, you heard correctly, pointers would be faster for most operations, as they are just "pointers" to the addresses of the variables value. For instance: (pseudo code)
INTEGER G = 42;
POINTER TO INTEGER = 0x759841; (value of the address in memory)
SEND INTEGER TO A FUNCTION(42); (value of 42 will be copied to a new address that the function will refer too, causing the number 42 to be held in the memory in two different places. Takes time for the computer to copy the number 42)
SENT POINTER TO A FUNCTION(42); (address of the integer G is sent to the function, the function has direct access to the value of G. No copy is needed)
That's basically the main benefit of using a pointer... speed and memory cost... what else would you use :)?
Haha, hope this helps.
As I said above, OOP will help you get away from global variables, and make your programs much more organized.
And yes, you heard correctly, pointers would be faster for most operations, as they are just "pointers" to the addresses of the variables value. For instance: (pseudo code)
INTEGER G = 42;
POINTER TO INTEGER = 0x759841; (value of the address in memory)
SEND INTEGER TO A FUNCTION(42); (value of 42 will be copied to a new address that the function will refer too, causing the number 42 to be held in the memory in two different places. Takes time for the computer to copy the number 42)
SENT POINTER TO A FUNCTION(42); (address of the integer G is sent to the function, the function has direct access to the value of G. No copy is needed)
That's basically the main benefit of using a pointer... speed and memory cost... what else would you use :)?
Haha, hope this helps.
Quote:Original post by F1N1TYWhat else would you use? A reference :) To echo the refrain from another currently active thread in this forum, "Use references when you can, pointers when you have to."
That's basically the main benefit of using a pointer... speed and memory cost... what else would you use :)?
Personally, I have nothing against globals... ...as long as they're not exported between modules. It's only then that they become a manageability nightmare.
Food for thought: Are you aware that the singleton design pattern is nothing but a glorified global variable?
Food for thought: Are you aware that the singleton design pattern is nothing but a glorified global variable?
Quote:
It is important that these variables can be written as well as read by various parts of the program (so passing local variables down through functions is out).
Generally, this just indicates that your overall design is flawed.
Quote:
I was thinking of replacing them with pointers, for speed reasons and I've heard that global variables are considered bad design. I was thinking of create a few structures and passing pointers to them through functions in order to emulate the capability of the globals, whilst being faster and better organised.
But taking a bunch of globals, putting them into a structure, and making an instance of that structure globally accessable doesn't make the variables any less global.
You're not solving the problem, you're only pretending to; nothing is better organized. Unless you want to stop and rethink the larger design issue that is "requiring" you to have a bunch of globals, don't bother wasting time with this "solution."
Furthermore, passing around a pointer to a bunch of globals versus just accessing the globals directly won't be appreciably faster or slower. There are minor differences with respect to addressing, cache locality, and all that kind of stuff but they will not be causing a signifigant performance impact on your program.
Quote:
Are you aware that the singleton design pattern is nothing but a glorified global variable?
While this is true, the OP just wants to wrap up his globals into a single structure and pass around pointers to that structure to the appropriate functions that need access to those globals. This isn't a singleton (which enforces one instance), this is just a case of a circumstantial single instance, and the clients of that instance don't actually rely on the assumption that only one exists. In that respect, it's better than a singleton.
But it still does not provide any real benefit.
Ok, so you have a chess board, the pieces, the moves etc. all stored in global variables. What I would do now is create a new class and call it "Game" or something similer. Move the chess board, pieces etc. into the "Game" class and write methods for interacting with them.
So lets say the main game logic is controlled by this game class. The game class calls the other classes/whatever to do what needs doing. If the class/method being called needs the chessboard variable, then just pass it in as pointer (or reference) to the function/class.
Passing data around is not as bad as you seem to think it is. It makes more sense, is safer and is easier to finds bugs (you know which classes use the pointer for example, so you know the problem is there. If the pointer was global, you would have to check everywhere to see where it is messing up).
PS. Sorry about bad spelling, grammer, and/or advice [smile] I'm in a hurry.
class Game{ public: Game(); ~Game(); // Some example methods. bool SetupGame(); void ClearUpGame(); ChessBoard* GetChessboard(); private: // Some members. ChessBoard m_Chessboard; PieceList m_Pieces;};
So lets say the main game logic is controlled by this game class. The game class calls the other classes/whatever to do what needs doing. If the class/method being called needs the chessboard variable, then just pass it in as pointer (or reference) to the function/class.
Passing data around is not as bad as you seem to think it is. It makes more sense, is safer and is easier to finds bugs (you know which classes use the pointer for example, so you know the problem is there. If the pointer was global, you would have to check everywhere to see where it is messing up).
PS. Sorry about bad spelling, grammer, and/or advice [smile] I'm in a hurry.
Quote:Original post by F1N1TY
And yes, you heard correctly, pointers would be faster for most operations, as they are just "pointers" to the addresses of the variables value. For instance: (pseudo code)
INTEGER G = 42;
POINTER TO INTEGER = 0x759841; (value of the address in memory)
SEND INTEGER TO A FUNCTION(42); (value of 42 will be copied to a new address that the function will refer too, causing the number 42 to be held in the memory in two different places. Takes time for the computer to copy the number 42)
SENT POINTER TO A FUNCTION(42); (address of the integer G is sent to the function, the function has direct access to the value of G. No copy is needed)
That's basically the main benefit of using a pointer... speed and memory cost... what else would you use :)?
Actually, in this example there is no benefit of passing a pointer. When you pass a pointer to a function, the pointer is copied instead of the value. This is only more efficient when the size of the pointer is larger than the size of what it points to. On most architectures, an int and a pointer are the same size, so you gain nothing here.
Anyway, as jyk said, you should generally use references instead of pointers for function parameters.
To the OP, if you don't sufficiently understand pointers, you will likely not gain anything by using them. Indeed you will probably end up with a whole slew of new problems [smile].
Just thought:
for chess game you need game state as a object because of AI algorithms, where you need to store *future* game states. It may be chessboard with figure ids or list of pieces with positions. This is also useful for load/save. So this is your candidate number one for a class and all the functions which does something with chessboard (moving pieces, ...) must have its chessboard instance as a parameter and not accesing the global one!
Btw having Game class is optional, but preffered. Depends how complicated your whole application should be, if you dont know do the class (because you may change your mind later and want to do something more complicated, like simultaneous play or whatever).
MaR
for chess game you need game state as a object because of AI algorithms, where you need to store *future* game states. It may be chessboard with figure ids or list of pieces with positions. This is also useful for load/save. So this is your candidate number one for a class and all the functions which does something with chessboard (moving pieces, ...) must have its chessboard instance as a parameter and not accesing the global one!
Btw having Game class is optional, but preffered. Depends how complicated your whole application should be, if you dont know do the class (because you may change your mind later and want to do something more complicated, like simultaneous play or whatever).
MaR
Thanks for the replies! Let me explain a few things.
I have already made a somewhat functional chess game engine, but because I'm a novice the code is quite ugly and messy and so I've decided to start again, correcting many of the mistakes I made first time round. So to the guy who said my design must have been flawed, yes I understand that ;)
I got pointers and references mixed up sorry, which is why I am going to practice them more before I start on my game again.
Speed is everything for a chess game. If my engine cannot process hundreds of thousands of nodes per seconds it will not be competative in the tournaments. (The engine I am watching now is using million+ nodes per second). That is why I wanted to use pointers/references rather than global varaibles, because I heard they were faster.
As for classes and objects, there are two problems. Firstly, I've been speaking to some experianced Chess programmers: some say they are too slow for the program, others say it doesn't make a difference if they are not used too much. The other problem is, I have never used them before (not once! long live c! lol) so it could cause more problems to try to use them. (I was brought up on various BASIC languages so I've learnt to think without these wierd "objects" you speak of :P)
Anyway back to the problem. I cannot simply just pass the variables as parameters to functions because the whole point is that the functions might want to change them. So I either use global variables, or pass pointers/references of variables and/or structures. My question was, which would be the best method, and is there any special advice you could give me? Please no more lectures on classes and globals are evil! At this stage I'm more interested in something that works, rather than something which conforms to some arbitary standard of what makes or does not make a good program. A finished C program with globals will give me a better chance in the tournaments than an unfinished C++ program ;)
I have already made a somewhat functional chess game engine, but because I'm a novice the code is quite ugly and messy and so I've decided to start again, correcting many of the mistakes I made first time round. So to the guy who said my design must have been flawed, yes I understand that ;)
I got pointers and references mixed up sorry, which is why I am going to practice them more before I start on my game again.
Speed is everything for a chess game. If my engine cannot process hundreds of thousands of nodes per seconds it will not be competative in the tournaments. (The engine I am watching now is using million+ nodes per second). That is why I wanted to use pointers/references rather than global varaibles, because I heard they were faster.
As for classes and objects, there are two problems. Firstly, I've been speaking to some experianced Chess programmers: some say they are too slow for the program, others say it doesn't make a difference if they are not used too much. The other problem is, I have never used them before (not once! long live c! lol) so it could cause more problems to try to use them. (I was brought up on various BASIC languages so I've learnt to think without these wierd "objects" you speak of :P)
Anyway back to the problem. I cannot simply just pass the variables as parameters to functions because the whole point is that the functions might want to change them. So I either use global variables, or pass pointers/references of variables and/or structures. My question was, which would be the best method, and is there any special advice you could give me? Please no more lectures on classes and globals are evil! At this stage I'm more interested in something that works, rather than something which conforms to some arbitary standard of what makes or does not make a good program. A finished C program with globals will give me a better chance in the tournaments than an unfinished C++ program ;)
Quote:
That is why I wanted to use pointers/references rather than global varaibles, because I heard they were faster.
Alas, that's not true. Whether globals are faster than stack parameters or stack parameters are faster then globals basically depends on the context. That context includes the physical hardware running the machine, that's how micro-level we're talking here. Even in a chess program, you are not going to see an appreciable difference.
Quote:
As for classes and objects, there are two problems. Firstly, I've been speaking to some experianced Chess programmers: some say they are too slow for the program, others say it doesn't make a difference if they are not used too much.
Yeah, that's not really true either. A class causes exactly as much performance impact as a struct in C would (if don't use virtual functions, which I don't imagine you'll need here). Which is to say, appreciably none.
Quote:
At this stage I'm more interested in something that works, rather than something which conforms to some arbitary standard of what makes or does not make a good program. A finished C program with globals will give me a better chance in the tournaments than an unfinished C++ program ;)
But an unmaintainable mess is harder to optimize.
Write the program the way you know how. If your concern is speed, you need to familiar enough with the way it works to be able to optimize it. If you're not familiar with certain kinds of design principals, or certain kinds of language features (structs / classes, pointers or references, et cetera), now is probably not the time to try and learn them.
Even if you could use a profiler and determine that the pathetically miniscule differences in speed using stack pointers versus globals (or the other way around) were somehow actually meaningful, you're overall lack of experience in the area would preclude you from being able to make the neccessarily deep level optimization. Furthermore you might end up making something orders of magnitude slower without noticing!
Write the program using the design and development methodologies you are comfortable with; it's the only way you'll be able to get the performance you want.
Learn about better design and become more familiar with language constructs for your next project.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement