Not a real problem

i have been learning about classes and decided to create a blackjack game. It's not quite finished but everything works up to now. I was just wondering if there are any problems with my code.Such as things that could be written better, if i have done something in way that may cause me problems later on or maybe i could shorten part of it etc.
i have only used online tutorials so i just wanted to know if i'm on the right track.
Sorry if you're not allowed to post things that aren't real problems.
I have included one class but there are more.

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
 #ifndef HAND_H_INCLUDED
#define HAND_H_INCLUDED
#include "MONEY.h"
#include <cstdlib>
#include <ctime>
class Hand
{
private:
    int HUserTotal;
    int HDealerTotal;
    bool HUserDouble;

public:
    Money HMoney;


    Hand():HUserTotal(0),HDealerTotal(0),HUserDouble(false){}
    int GenerateCard()
    {
        int x = (rand() % 13) + 2;
        if(x<=11)
        return x;
        else
        return(10);
    }

    void Deal()
    {
        int x = GenerateCard();
        int y = GenerateCard();
        int z = GenerateCard();
        HUserTotal = (x+y);
        HDealerTotal = z;
        cout << "You have drawn: "  << x << ", " << y << endl
        << "The dealer has drawn: " << z << "\n\n";
        HitStickDouble();
    }

    void HitStickDouble()
    {
         cout << "What do you wish to do:\nH:Hit, S:Stick, D:Double:  ";
        char HSD(0);
        cin >>HSD;
        cout << endl;
        switch (HSD)
        {
            case 'S':
            case 's':
            DealerHit();
            break;
            case 'H':
            case 'h':
            UserHit();
            break;
            case 'D':
            case 'd':
            HUserDouble = true;
            UserHit();
            break;
            default:
            cout << "Please input valid selection!\n";
            HitStickDouble();
        }
    }

    void DealerHit()
    {
        int x(0);
        if (HDealerTotal < 17)
        {
            while (HDealerTotal < 17)
            {
                x = GenerateCard();
                HDealerTotal = (HDealerTotal + x);
                cout << "The dealer has drawn: " << x << endl
                << "Bringing the dealers total to: " <<HDealerTotal << endl << endl;

                if(HDealerTotal > 21)
                cout << "The dealer has gone bust!\n";

            }
            CalculateWinner();
        }

    }

    void UserHit()
    {
        int x = GenerateCard();
        HUserTotal = (HUserTotal + x);
        cout << "You have drawn: " << x << endl
        << "Bringing you total to: " << HUserTotal << endl << endl;
        if(HUserTotal > 21)
        {
            cout << "You have gone bust!\n";
            CalculateWinner();
        }
        else if (HUserDouble == true)
        {DealerHit();}
        else
        {HitStickDouble();}
    }

    void CalculateWinner()
    {

        if(((HUserTotal > HDealerTotal) && (HUserTotal <= 21)) || HDealerTotal > 21 )
        {
            cout << "You Win!\n\n";
            HMoney.payment(HUserDouble);
        }
        else
        {
           cout << "You Lose!\n\n";
           if (HMoney.GetBank() == 0)
           {
               cout << "You have no money left!\nDo you want to start again ?\n Y:Yes, N:No: ";
               char YESNO;
               cin >> YESNO;
               switch(YESNO)
               {
                   case 'Y':
                   case 'y':
                   cout << "You get a suprise loan of $500\n";
                   HMoney.SetBank();
                   break;
                   case 'N':
                   case 'n':
                   cout << "GOODBYE!";
                   exit(0);
               }

           }

        }


    }
};


#endif // HAND_H_INCLUDED 
Just a bit of style thing:

Put your class declaration into a .h header file, and put the function definitions into a .cpp file.



I actually though about doing that. Didn't know how to though.
Would i have to make all the functions friends ?
No need for friends or anything.

The class declaration would look like this:

hand.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef HAND_H_INCLUDED
#define HAND_H_INCLUDED
#include "MONEY.h"
#include <cstdlib>
#include <ctime>
class Hand
{
private:
    int HUserTotal;
    int HDealerTotal;
    bool HUserDouble;

public:
    Money HMoney;


    Hand();
    int GenerateCard();
    void Deal();
    void HitStickDouble();

//etc

};


hand.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "hand.h"
//any other needed includes

Hand::Hand():HUserTotal(0),HDealerTotal(0),HUserDouble(false){}

int Hand::GenerateCard() {

        int x = (rand() % 13) + 2;
        if(x<=11)
        return x;
        else
        return(10);
}

//similar for the other functions


Hope all goes well :)
Thanks.
Thats far easier than i though it would be.
Would it not require a friend to access the private member variables though ?
Sorry if these are stupid questions.
Also if not what is the point of friend ?
Would it not require a friend to access the private member variables though ?

Not from inside member methods, such as Hand::GenerateCard() or the constructor. That's the whole point of private members - they can be accessed by the methods of the same class, but not by any other code.
Remember that class functions have direct access to member variables, to provide access otherwise write a public get function which returns the value.

Having said that don't be tempted to write get /set functions for every private variable - only write them if you need them. Setting values initially should be done with constructors. Changing the value of several of them afterwards can often be combined into 1 function, same with outputting.

Friend functions are often frowned upon because the reduce encapsulation.

Some other things:

You can make use of the toupper or tolower functions so you don't have to test the value twice (or include both in your switch cases)

I made a copy / paste mistake - one shouldn't create objects in header files - do this outside the class, in main() say.

The CalculateWinner shouldn't be in the Hand class, because it involves money. What other classes do you have?

Maybe you can have these classes as well : Player & Bank. That way you can transfer money from the bank to a player.

HTH
Hey
i only had two classes, Hand and Money.
I was asking if i had done it properly before making more to make sure i didn't have to redo them.
i haven't come across toupper or tolower functions so ill probably look them up next as well.

Thanks for the advice, its actually helped a lot :)

Hi jidder,

I was asking if i had done it properly before making more to make sure i didn't have to redo them.


I don't know how much of this you know already, but here goes.

I mentioned having the extra classes because it is important to try & get the concepts of class design right - which isn't always easy.

I try to think of things as real world objects - decide what duties & info each object needs to have.

In my mind, the contents of a Hand can be used to determine if the player wins or not, but the responsibility of the transfer of money doesn't belong with it.

You could have a Game class which controls the playing of the game, with the duties of dealing, deciding the winner, and transferring money. All the other classes just hold only the info & functions they need, so that everything is modularised & reusable, like this:

CPlayer & CDealer have FundsAvailable & the ScoreCurrentHand & Hit, Stick & Double functions;
CBank has FundsAvailable;
CGame has the functions Deal3Cards, Deal1Card, IsWinner, TransferMoney;
CBetPool has the BetTotal for the current hand.

The GenerateCard function is simple at this stage, & will need some modification especially for multi-player. You will probably need a proper CDeck class as well.

Hope all goes well :)

Topic archived. No new replies allowed.