Code works first time but not in repetition

Hello everyone, I've been working on a blackjack game. The premise is simple enough, an array holding values 1-52 is randomized to simulate a shuffle, and the Card function translates values 1-52 into suits 1-13. Face cards are assigned values of 10 automatically, and aces (represented by 1's) add ten to the sum of cards when the sum is under 12. The code works perfectly the first time through, but upon repeated hands always mistotals values despite variable re-initialization. Any help in pinpointing this issue would be appreciated.
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#include "basic.h"
#include <stdio.h>
//function prototypes
int hit(int array[],int deck, int &q);
int H_hit(int array[],int deck,int &q2, int q);
void shuffle(int array[],int startPoint,int endPoint);

int main()
{
    int array[52]={0};//array of cards
    int deck=0;//tracks position of draw
    int psum=0,csum=0,rounds=0,play=1,q=2,total=0,q2=2,total2=0;
    int cash=1000,bet=0;
    srand(time(NULL));//set random # seed

    //fill deck with values 1-52

    for (int i=0;i<52;i++)
        array[i]=i+1;

    shuffle(array,0,51);//randomized shuffle of whole deck
    round:
    while (bet<10 || bet>200)
    {
    cout<<"How much would you like to bet($10-$200)?: ";
    cin>>bet;
    if (bet<10||bet>200)
        cout<<"Your bet must be between $10 and $200!\n";
    }
    clear();
    cash=cash-bet;

    //output initial cards and assign values
    cout<<"Your cards\tTotal\n";
    int temp=Card(array,deck),temp2=Card(array,deck+2);

    //alters ace's value to reflect blackjack rules
    //aces to 11 when sum is under 12
    temp=((temp==1 && temp+temp2<12) ? 11 : temp);
    temp2=((temp2==1 && temp+temp2<12) ? 11 : temp2);
    //output sum of card values
    cout<<"\t "<<temp+temp2<<endl;
    //output house's first card
    cout<<"House cards\n";
    int temp3=Card(array,deck+1);
    cout<<" ?\t\t ?\n";

    if (temp+temp2==21)
    {
        cout<<"\nBlackjack!";
    }
    else
    {
        while (temp+temp2<21 && total<21)
        {
            //clear character buffer prior to recieving input
        fseek(stdin,0,SEEK_END);
        cout<<"Would you like to hit, or stand? (H/S)";
        int c=getchar();
        if (c=='h' || c=='H')
        {
            total=hit(array,deck,q);
        }
        else if (c=='s' || c=='S')
            break;
            else
            {
                cout<<"That's not a valid command...\n";
            }
        }
        //return cursor to house's line
        COORD cursor={0,2};
        HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(console,cursor);
        //output house's intial cards
        cout<<"House cards\n";
            int temp3=Card(array,deck+1);
            int temp0=Card(array,deck+3);

            //alters ace's value to reflect blackjack rules
            //aces to 11 when sum is under 12
           temp3=((temp3==1 && temp3+temp0<12) ? 11 : temp3);
           temp0=((temp0==1 && temp3+temp0<12) ? 11 : temp0);
            cout<<"\t "<<temp0+temp3<<endl;
            //clear previous input prompts
            for (int i=4;i<q+3;i++)
            {
            cursor={0,i};
            SetConsoleCursorPosition(console,cursor);
            cout<<"                                        ";
            }
            //add logic for the house hitting when applicable
            if (temp0+temp3<17 && temp+temp2<21 && total<21)
            {
                while (total2<17 && temp+temp2<21 && total<21)
                {
                    total2=H_hit(array,deck,q2,q);
                }
            }
            //return to area previous prompts were
            cursor={0,4};
            SetConsoleCursorPosition(console,cursor);
            //set basic win/loss rules
            //initial total and total2 when not used
            if (total==0 || total2==0)
            {
                if (total==0)
                {
                    total=temp+temp2;
                    total=((temp==1 && total<12) ? total+10 : total);
                    total=((temp2==1&& total<12) ? total+10 : total);
                }
                if (total2==0)
                {
                    total2=temp0+temp3;
                    total2=((temp0==1 && total2<12)? total2+10:total2);
                    total2-((temp3==1 && total2<12)? total2+10:total2);
                }
            }

            if (total==total2)
            {
                cout<<"Push!\n";
                cash=cash+bet;//get bet back
            }
            else if (total>21)
            {
               cout<<"You busted, I win.\n";
               bet=0;//lose your bet
            }
             else if (total<21 && total>total2)
             {
                 cout<<"You win.\n";
                 bet=bet*2;//get your bet plus matching funds back
                 cash=cash+bet;
             }
            else if (total==21)
            {
                cout<<"You got Blackjack!";
                cash=cash+bet;//get bet back
                bet=bet*1.5;
                cash=cash+bet;//get addition funds with 50% bonus
            }
            else if (total2>21)
            {
                cout<<"I busted, You win.\n";
                bet=bet*2;//get bet back plus matching funds
                cash=cash+bet;
            }
            else if (total2<21 && total2>total)
            {
                cout<<"I win.\n";
                bet=0;//lose your bet
            }
            else if (total2==21)
            {
                cout<<"I got blackjack!";
                bet=0;//lose your bet
            }

    }//complete house cards if player gets blackjack
            if (temp+temp2==21)
            {
            COORD cursor={5,3};
            HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(console,cursor);
            int temp0=Card(array,deck+3);
            cout<<"\t "<<temp0+temp3<<endl;
            cout<<"You got blackjack!\n";
            cash=cash+bet+(bet*1.5);
            }
            cout<<"\nYou now have "<<cash<<".\n";
            cout<<"Would you like to play another round? (Y/N)";
            //clear character buffer prior to recieving input
            fseek(stdin,0,SEEK_END);
            int c=getchar();
            if (c=='Y' || c=='y')
            {

                deck+=q+q2+1;
                int total=0,q2=2,total2=0,bet=0,q=2;
                goto round;
            }
}//end of main



void shuffle(int array[],int startPoint,int endPoint)
{
    for (int i=startPoint;i<endPoint+1;i++)
    {
      int temp=array[i];//use temp to hold i's value
      int temp2=rand()%(endPoint+1);//use temp2 to randomize where to swap with
      array[i]=array[temp2];//copy from randomized position to i's position
      array[temp2]=temp;//replace randomized position with temp's value
    }//repeat loop until cards between start and endpoint are shuffled
}

int hit (int array[],int deck, int &q)
{
q++;//increment card count
//return to beginning of console window but one line lower
COORD cursor={0,1};
HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(console,cursor);
//set initial sum and output intial hand
int sum=Card(array,deck);
sum+=Card(array,deck+2);
//add any additional cards
for (int i=3+deck;i<deck+q+1;i++)
sum+=Card(array,deck+i+q);

//apply logic for aces to initial hand
sum=((array[deck]==1 && sum<12) ? sum+10 : sum);
sum=((array[deck+2]==1 && sum<12) ? sum+10:sum);
//apply logic for aces to additional cards
for (int i=4+deck;i<deck+q+2;i++)
sum=((array[i]==1 && sum<12) ? sum+10:sum);

//output sum
cout<<"     "<<sum<<"    "<<endl;
//return cursor to below
cursor={0,2+q};
SetConsoleCursorPosition(console,cursor);
//return sum's value
return sum;
}

int H_hit (int array[],int deck, int &q2, int q)
{
q2++;//increment card count
//return to beginning of console window but one line lower
COORD cursor={0,3};
HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(console,cursor);
//set initial sum and output intial hand
int sum=Card(array,deck+1);
sum+=Card(array,deck+3);
//add any additional cards
for (int i=q2+q+deck-2;i<deck+q+q2+1-2;i++)
sum+=Card(array,deck+i+1);

//apply logic for aces to initial hand
sum=((array[deck+1]==1 && sum<12) ? sum+10 : sum);
sum=((array[deck+3]==1 && sum<12) ? sum+10:sum);
//apply logic for aces to additional cards
for (int i=q2+q+deck-2;i<deck+q2+1;i++)
sum=((array[i]==1 && sum<12) ? sum+10:sum);

//output sum
cout<<"     "<<sum;
//return cursor to below
cursor={0,2+q2};
SetConsoleCursorPosition(console,cursor);
//return sum's value
return sum;
}


Also, because of the stupid 8000 character limit, here is the header file.
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
#ifndef BASIC_H_INCLUDED
#define BASIC_H_INCLUDED
#endif // BASIC_H_INCLUDED

#include<iostream>//required for cout
#include<windows.h>//required for rand
#include<time.h>//required for time
#include<conio.h>
using namespace std;
void Color(int color)
{
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hCon,color);
}

void clear()
{
    COORD topLeft={0,0};
    HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    DWORD written;

    GetConsoleScreenBufferInfo(console,&screen);
    FillConsoleOutputCharacterA(console,' ',screen.dwSize.X * screen.dwSize.Y, topLeft, &written);
    FillConsoleOutputAttribute(console, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
                               screen.dwSize.X * screen.dwSize.Y, topLeft,&written);
    SetConsoleCursorPosition(console,topLeft);
}

int Card(int array[],int x)
{
    //change color and output card values based on numeric value pulled from deck
    if (array[x]<27)
        Color(12);
    else
        Color(8);
    int temp=x;//use temp to translate values 1-52 into 1-13 for each suit
    cout<<((array[x]<14) ? "\3" : (array[x]>13 && array[x]<27) ? "\4" : 
                 (array[x]>26 && array[x]<40) ? "\5" : "\6");
    temp=((array[x]>39) ? array[x]-39 : (array[x]>26 && array[x]<40) ? 
                 array[x]-26 : (array[x]<27 && array[x]>13) ? array[x]-13 : array[x]);
    if (temp<11 && temp!=1)
        cout<<temp<<" ";//just print the value unless it is 1 or above 10
    else//output A,J,Q, or K based on value
        cout<<((temp==11) ? "J" : (temp==12) ? "Q" : (temp==13) ? "K" : "A")<<" ";
    cout<<((temp==10) ? "" : " ");//add additional space for single digit values
    Color(7);
    //apply blackjack rules to card value
    //deal with face cards
    if (temp>10)
        temp=10;
    //deal with aces in main to get total card run
    //returns cards value when desired as well as outputting
    return temp;
}

You may notice the use of goto in the main function. This was to see if I could get different results from when I tried enclosing the round within a loop, but the results were the same. In both cases, repeated playing leads to invalid totals, but the first hand always works flawlessly.
Last edited on
closed account (S6k9GNh0)
This looks like a job for a debugger! :D
Step through the code and figure out where it goes wrong. Might take awhile but a surefire method of solving the issue.
I'm using code:blocks, and have not yet had experience with it's debugger or how it works. I've also noticed that when playing additional hands, sometimes it neglects to ask the size of the bet, despite the fact that the value has been re-initialized and should trigger the loop which asks for it. The code is starting to get more complicated, so any advice on how to use the debugger would be helpful.

NOTE: I cannot edit my original post. Apparently it pushed the limits on post length, and any changes other than major deletions triggers an error when attempting to post. Therefore, I cannot make any corrections or updates to the code. The changes to the value of the deck variable should read deck+=q+q2 and not deck+=q+q2+1 (line 180). Also, the variables in line 12 of my first code sample included unnecessary variables left over from another project, making the code more confusing. Instead, it should have read int q=2,total=0,q2=2,total2=0;, which are used to track hand totals(total for player,total2 for house), and the number of cards the player(q) and house (q2) has in play.
Last edited on
closed account (S6k9GNh0)
I really hate giving straight answers as people don't learn from that...

1. Your input code is wrong. cin >> doesn't remove whatever is used to delimit input and is still their next time you ask for input. You have to either deal with that yourself or use a different method of grabbing input.

2. Using a debugger with Code::Blocks is meh. I prefer using a standalone debugger as it's more straightforward but their really aren't many that are that great for gdb. Either way, there are a ton of tutorials to provide the basics which is seriously all you need. It isn't as complicated as some make it out to be (although it can be in complicated environments).
Last edited on
Your input code is wrong. cin >> doesn't remove whatever is used to delimit input and is still their next time you ask for input.

I solved this problem by placing the "round:" label within the while loop instead of preceding it, and it only repeats the loop if the input provided is not within the valid betting range. Later I will add logic to ensure one cannot bet more than one has, and that running out of money means to stop playing because the minimum bet cannot be made.
prefer using a standalone debugger as it's more straightforward...

Can you recommend a specific standalone debugger? I know the issue has something to do with the loops to calculate totals and account for aces and the way they are structured, yet in the form above it works the first round before going haywire. Further experimentation only seems to make it worse, though. I've simplified the existing code somewhat by creating a function that alters cursor position with x and y parameters, allowing a single line of code to set the position instead of 3 in combination. The loops within the hit and H_hit functions are what I am questioning, and I suspect they are to blame for the problem. Somehow they work yet fail to work properly once the value of deck is changed. The way it is supposed to work is that the initial player hand is always array[deck] and array[deck+2], and any subsequent values are array[deck+4] and beyond. For the house, the initial hand is array[deck+1] and array[deck+3], with any subsequent values being array[deck+q+2], with q being the quantity of cards the player used, meaning if the player hit once, any subsequent values for the house hitting begin at array[deck+5]. Somehow, my loops are mis-structured, resulting in it working the first time around only, but further experimentation seems to make it worse.
Last edited on
Topic archived. No new replies allowed.