Header files and Global Variables

Hey,

I have the following classes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
char* Suits[4] = {"s", "c", "d", "h"};//references for enum types
char* Ranks[13] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

enum class SUIT{ Spades, Clubs, Diamonds, Hearts}; //enumerate card suits and ranks so they can be randomly assigned
enum class RANK{ Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King};

class CARD{
    public:
    SUIT Card_Suit; //suit and rank of card
    RANK Card_Rank;

    CARD(){} //default constructor

    CARD(int Card_Number) //constructor which takes a card number as an argument and assigns the corresponding suit and rank
    {
        Card_Suit = (SUIT) (Card_Number / 13);
        Card_Rank = (RANK) ((Card_Number % 13) + 1);
    }

    void Print_Card()
    {
        std::cout << Ranks[((int) Card_Rank) - 1] << Suits[(int) Card_Suit];
    }
};

class DECK{
    public:
    int Cards_Remaining;//indicates how many cards are left in the deck
    bool Cards_Dealt[52];//includes information about cards already dealt

    DECK();

    void Reshuffle(bool *Cards_Dealt);

    CARD Deal_Card();

    int RNG(int n); //random number generator
    int Select_Available_Card(int Card);
};

#define DECKS_USED 4
DECK Deck[DECKS_USED];

class BLACKJACK{
    public:
    int Cards_Received;
    int Current_Total;
    bool Bust;
    CARD Cards[11];

    int Get_Hand_Total(int Cards_Received);
    void Get_Player_Decision();
    void Get_Dealer_Decision();
    bool Decide_If_Winner(const BLACKJACK &Dealer);
};


I want to create Header files for CARD, DECK and BLACKJACK. My problem is that the global variables in between the classes are needed within that class, in the precise order above.

How would I create my header files? Is there an easier way to do this?

The ones above CARD are needed to print CARDS and save SUIT and RANK.

The one above BLACKJACK is required to deal cards to players.
Use extern... In the deck.c place aDECK variable; and in the deck.h place extern DECK variable; .. now just include deck.h and you can use the DECK variable inside the deck.c from every other place...

what i sometimes do:
create a globals.c and fill it with variables
create globals.h and fill it with the same variables... but add extern...
include globals.h in other files
Last edited on
What about the four items at the top of the code, where shall I put them?
I have never needed to use extern. What I do suggest though is to create Blackjack.cpp and Blackjack.h, and do the following for the other classes.
Blackjack.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Include these header files since they're required for your Blackjack class
#include "Card.h"
#include "Deck.h"
class BLACKJACK{
    public:
    int Cards_Received;
    int Current_Total;
    bool Bust;
    CARD Cards[11];

    int Get_Hand_Total(int Cards_Received);
    void Get_Player_Decision();
    void Get_Dealer_Decision();
    bool Decide_If_Winner(const BLACKJACK &Dealer);
};
// Include this file so you don't need to worry about linking it in your project
#include "Blackjack.cpp" 


Once you do that for all of your classes, all you need is the simple #include "Blackjack.h" in your main.cpp. I would highly suggest looking up header guards since they're more of a standard to prevent any serious issues later on.

I also noticed that you didn't have a default constructor in the BLACKJACK class but yet you created a new DECK, why? If you create a constructor class, you can have it initialize a DECK for your class to use and don't need to worry about sharing the DECK to things that don't need it.

Edit: As for the enums, since they pertain directly to your card class, I'd suggest they go into the card.h file.
Last edited on
Player and Dealer are BLACKJACK objects. So I couldn't create a deck in the constructor as it would mean having a deck for every player created.

To anyone who knows the rules of Blackjack:
I have the program set up to deal cards to a player and let him hit or stick. I have the dealer to play stick on 17 or higher (most casinos have this rule).

I can create the double down rule, but splitting a hand is quite a problem (in terms of coding). I can get the program to understand the situations where this move is legal, but how would allocate a new hand for a player. Especially if a player were to split, say 4 times (if someone was that lucky).

I had the same problem with storing the cards. I don't want to create pointless objects, like my Cards array in the BLACKJACK class. It is unlikely to ever be 11. Does this have a huge effect on performance?

Or should I simply create some more Card arrays, say 8, in case the player splits his hand? I have recently looked at dynamic memory, is this appropriate here? Any tips or advice are welcome

Thanks guys

The blackjack class should be set up to play the entire game within the class itself. At least, that's my suggestion. It should create the deck, or decks, to be used in the game, create as many players as you need, and whatever else you needed.

I can create the double down rule, but splitting a hand is quite a problem (in terms of coding). I can get the program to understand the situations where this move is legal, but how would allocate a new hand for a player. Especially if a player were to split, say 4 times (if someone was that lucky).


Create a "hand class" or create another "split" player. This way the player will be playing two people.

Performance issues with something like this will be negligible. If you notice performance issues, you've done something severely wrong.

As for how to handle the extra "hands", there is so many ways to do this. yes, you could just add another array to do this, you could also create more players to handle the splits, which I think is the best way since when you split, you can bid and play each hand as if you were another player, or create hand classes which is just a "make sense" thing.

I hope this points you into the right direction.
Thanks Volatile, only been on this forum a few days and you have already managed to help me out a lot. The DECK and CARD classes were your suggestion, if you remember.

The initial idea was to get BLACKJACK to play the game, but I think I got ahead of myself and just mixed everything into it.

Also, why should I put #include "BLACKJACK.cpp" and not just write the functions for BLACKJACK in the header file?

Thanks again, definitely gave me some idea of how to do this. I will try to implement it today


Also, why should I put #include "BLACKJACK.cpp" and not just write the functions for BLACKJACK in the header file?

I used to do it just like you asked. There really is nothing wrong with doing it that way, but I was told there is a reason behind separating the two. Until I learn more about it, I have accepted it as right. It also keeps the header file short and clean. ResidentBiscuit had mentioned in another post that separating them prevents the functions from being treated as inline, which I believe is more relevant for optimization. For simple programs, I don't believe you need to worry about that, but it's good practice.

And yes, I do remember suggesting different classes for you, and there is a reason for that. What happens when you want to create a basic poker game, or a game of I Declare War? You would need to recreate the two classes just for those functions. Here, you have a reusable class/classes.

Another reason to keep them separate is that once you have the declaration of the class done, you don't have to scroll through that code. Granted, it's short, but every time I modify .cpp files, I like going directly to where my class functions are and modifying that.

#include "BLACKJACK.cpp" also prevents having to have the .cpp file linked in your project. You can compile just you main.cpp file without getting any definition errors.

Also, if you haven't yet, look into header guards.
To clarify, I was thanking you for suggesting the classes. Not sure if you realised that or not.

Either way, I'll probably hear from you again.

Thanks for all the help so far, I really appreciate you taking the time to write detailed replies.

P.S I did read into header guards, and C::B sets it up automatically for me.
Not a problem, and I was drawing a blank on what compiler you were using and since I didn't see them, I was unaware you were actually using them. I'd also suggest putting the "header guards" into your BLACKJACK.cpp, DECK.cpp, and CARD.cpp files, similarly, they would be something like:
1
2
3
4
5
6
#ifndef _BLACKJACK_CPP_
#define _BLACKJACK_CPP_
// ...
// Code
// ...
#endif 


And I wasn't sure if you were thanking me or not, so sorry if it sounded like I was taking it as being hostile.
Topic archived. No new replies allowed.