Ensure "Shuffling" for Blackjack code

I have been giving an assignment to create a BlackJack program,and have been given some starter code to help us along, however I'm running into some problems trying to figure out how to ensure that when a player gets dealt a card after the initial two cards, the card given is checked to make sure it hasnt already been dealt. So far this is what I have, I'm not too sure how to approach the dealToPlayers function. Thanks!

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
#include <iostream>
#include <ctime>
#include <iomanip>
#include <windows.h>
using namespace std;
void gotoxy(int, int);
char suit(int);
int value(int);
char picture(int);
void calc_tot(int[], int, int);
void Deal_Two_Cards(int[], int[]);
void DealToPlayers(int[], int[]);

int main()
{
    int cards[52], picked[52] = { 0 }, i, Tot[8] = { 0 }, j;
    int moreCards[7] = { 1 }; 
    char hitStand = ' ';
    srand(time(NULL));
    for (i = 0; i < 52; i++)
    {
        do
        {
            cards[i] = rand() % 52;
        } while (picked[cards[i]] != 0);
        picked[cards[i]] = 1;
        cout << cards[i] << endl;
    }
    Deal_Two_Cards(cards, Tot);
    j = 15;
    // loop with a call to a function to deal cards to a player
    for (int i = 0; i < 7; i++) {
        gotoxy(0, 17);
        cout << "Would Player " << i + 1 << " like another card? (Please enter 'y' or 'n' ";
        cin >> hitStand;
        while (hitStand != 'y' && hitStand != 'n') {
            cout << "That is not a valid choice. Please enter 'y' or 'n'. ";
            cin >> hitStand;
        }

        if (hitStand == 'y') {
            moreCards[i] = 1;
        }
        else if(hitStand == 'n') {
            moreCards[i] = 0;
        }
        while (moreCards[i] == 1) {
            DealToPlayers(cards, Tot);
        }
    }
    
    // call a function to finish the dealer
    
    // call a function to determine win/lose/tie


    system("pause");
    return 0;
}
void gotoxy(int h, int w)
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    if (INVALID_HANDLE_VALUE != hConsole)
    {
        COORD pos = { h, w };
        SetConsoleCursorPosition(hConsole, pos);
    }
    return;
}
char suit(int i)
{
    char c;
    c = char(i / 13 + 3);
    return c;
}
int value(int i)
{
    int r;
    if (i % 13 == 0)
        r = 1;
    else if (i % 13 > 9)
        r = 10;
    else
        r = i % 13 + 1;
    return r;
}
char picture(int i)
{
    char c = ' ';
    if (i % 13 == 0)
        c = 'A';
    else if (i % 13 == 10)
        c = 'J';
    else if (i % 13 == 11)
        c = 'Q';
    else if (i % 13 == 12)
        c = 'K';

    return c;
}
void calc_tot(int T[], int v, int p)
{
    T[p] = T[p] + v;
    return;
}
void Deal_Two_Cards(int cards[], int Tot[])
{
    int i, row = 1, v, k = 1;
    char c, s;
    cout << right;
    system("cls");
    cout << setw(8) << "Dealer" << setw(8) << "P1" << setw(8) << "P2" << setw(8) <<
        "P3" << setw(8) << "P4" << setw(8) << "P5" << setw(8) << "P6" << setw(8) << "P7" <<
        endl;
    gotoxy(0, row);
    cout << setw(8) << "???";
    for (i = 0; i < 15; i++)
    {
        if (i == 7)
            row++;
        s = suit(cards[i]);
        v = value(cards[i]);
        c = picture(cards[i]);
        gotoxy(k % 8 * 8, row);
        if (c != ' ')
            cout << setw(7) << c << s;
        else
            cout << setw(7) << v << s;
        calc_tot(Tot, v, k % 8);
        gotoxy(k % 8 * 8, 17);
        cout << setw(8) << "Total";
        gotoxy(k % 8 * 8, 18);
        cout << setw(8) << Tot[k % 8];
        k++;
    }
}

void DealToPlayers(int cards[], int Tot[]) {
    
    
    return;
}
Last edited on
Well the general idea is you start with a 'deck' of 52 cards suitably initialised and shuffled.

Then you 'deal' from that 'deck' by removing each card in turn.

No need for complex checking to see if the card is unique or anything.
Are you allowed to use std::vector?
If so, the easiest way is:
1) Populate the vector with your 52 cards.
2) Shuffle the vector.
3) Remove card(s) from the front of the vector. i.e. erase the vector entry.

L20 - 28. First generate the card array with elements containing the numbers 0 - 51.

Then shuffle cards to get a random card order.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <random>
#include <iostream>
#include <numeric>
#include <array>
#include <algorithm>
#include <iterator>

std::mt19937 rng(std::random_device {}());

int main() {
	std::array<int, 52> cards;

	std::iota(cards.begin(), cards.end(), 0);
	std::shuffle(cards.begin(), cards.end(), rng);

	std::copy(cards.begin(), cards.end(), std::ostream_iterator<int>(std::cout, " "));
	std::cout << '\n';
}


This will generate a random cards array and display it.
Ignoring the Windows-specific coding here's one possible way to jumpstart doing a console-mode Blackjack game using C++ features:
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
#include <iostream>
#include <deque>
#include <vector>
#include <random>  // std::default_random_engine, std::random_device
#include <numeric> // std::iota

int main()
{
   // create & seed a C++ random engine
   // http://www.cplusplus.com/reference/random/
   std::default_random_engine prng(std::random_device {} ());

   // create an alias to represent a card
   using card = unsigned;

   // create a "standard" poker-style deck of 52 cards
   // http://www.cplusplus.com/reference/deque/deque/
   std::deque<card> deck(52);

   // populate the deck to represent all 52 cards
   // https://en.cppreference.com/w/cpp/algorithm/iota
   std::iota(deck.begin(), deck.end(), 0);

   // two lambdas to parse out suit and rank of a card
   // https://en.cppreference.com/w/cpp/language/lambda
   auto rank = [ ] (card c) { return "AKQJT98765432"[c % 13]; };
   auto suit = [ ] (card c) { return "SHDC"[c / 13]; };

   // casino black-jack uses more than a single deck
   // multiple decks combined are called a shoe
   std::deque<card> shoe;

   // 3 decks for the shoe
   for (size_t i { }; i < 3; ++i)
   {
      shoe.insert(shoe.begin(), deck.begin(), deck.end());
   }

   // display the original order of cards in the shoe
   std::cout << "Unshuffled shoe:\n";
   
   // range-based for loop
   // https://en.cppreference.com/w/cpp/language/range-for
   for (card ccount { }; const card & c : shoe)
   {
      std::cout << rank(c) << suit(c) << ' ';
      ccount++;

      // if 13 cards have been displayed in a line, start a new line
      if (0 == (ccount % 13)) { std::cout << '\n'; }
   }
   std::cout << '\n';

   // shuffle the shoe, using the random engine created earlier
   // https://en.cppreference.com/w/cpp/algorithm/random_shuffle
   std::shuffle(shoe.begin(), shoe.end(), prng);

   // display the shuffled shoe
   std::cout << "Shuffled shoe:\n";
   for (card ccount { }; const card & c : shoe)
   {
      std::cout << rank(c) << suit(c) << ' ';
      ccount++;

      if (0 == (ccount % 13)) { std::cout << '\n'; }
   }
   std::cout << '\n';

   // create 2 players and the dealer using vectors
   // http://www.cplusplus.com/reference/vector/vector/   
   std::vector<card> p1;
   std::vector<card> p2;
   std::vector<card> d;

   // deal two cards to each player/dealer
   for (size_t itr { }; itr < 2; ++itr)
   {
      // begin() returns an iterator to the first element, like a pointer
      // need to retrieve the stored value using operator*
      // and add that value to the player's hand
      p1.push_back(*shoe.begin());

      // remove the first element from the shoe
      shoe.pop_front();

      // can access the first element using operator[]
      p2.push_back(shoe[0]);
      shoe.pop_front();

      d.push_back(shoe[0]);
      shoe.pop_front();
   }

   // display players' and dealer's hands
   // the 'hole' card is displayed with parentheses
   std::cout << "Player 1: ";
   std::cout << '(' << rank(p1[0]) << suit(p1[0]) << ") ";
   std::cout << rank(p1[1]) << suit(p1[1]) << '\n';

   std::cout << "Player 2: ";
   std::cout << '(' << rank(p2[0]) << suit(p2[0]) << ") ";
   std::cout << rank(p2[1]) << suit(p2[1]) << '\n';

   std::cout << "Dealer:   ";
   std::cout << '(' << rank(d[0]) << suit(d[0]) << ") ";
   std::cout << rank(d[1]) << suit(d[1]) << '\n';
   std::cout << '\n';

   // display the shoe with already dealt cards
   std::cout << "Shoe after dealing cards to players:\n";
   for (card ccount { }; const card & c : shoe)
   {
      std::cout << rank(c) << suit(c) << ' ';
      ccount++;

      if (0 == (ccount % 13)) { std::cout << '\n'; }
   }
   std::cout << '\n';
}
Unshuffled shoe:
AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S
AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H
AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D
AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C
AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S
AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H
AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D
AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C
AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S
AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H
AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D
AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C

Shuffled shoe:
QD KD 9H KH 5S 6C 8C 3D KC 5D TD 6S 5S
KS 9H 6S 3D 9H 9C 2D TD TC 3C 9D 3S 6H
2C 2H 8D 4D 6C TH QH 6D 7C 2S 5C JD 7S
QD AH 5D JC AC 7C 4S QH 3D 8C JH 6S 2H
9S AD 2D TD KH 3S 7D AS 3H TS 6H 9S 7D
AD 2C 5H JD 9C 4H TH 8S KC 6C AC 5H 7S
TH 6H 2D 5H AC 5D 4C KD 7H 8D 5C QS 8S
KS QD JH JC 3C 8H JH 4C JC 7S 4C 6D AD
4S TC 9S 4H JS 2C QS 2S QC 9D TC JS QC
8D AS 3H 4H 8S 4D AH 7C 2S KC 7D QH QC
3S 9D 8H KH 7H 4S AH 8C 3C JD TS 9C AS
TS 5S JS 4D 6D 8H KS KD 2H 3H QS 5C 7H

Player 1: (QD) KH
Player 2: (KD) 5S
Dealer:   (9H) 6C

Shoe after dealing cards to players:
8C 3D KC 5D TD 6S 5S KS 9H 6S 3D 9H 9C
2D TD TC 3C 9D 3S 6H 2C 2H 8D 4D 6C TH
QH 6D 7C 2S 5C JD 7S QD AH 5D JC AC 7C
4S QH 3D 8C JH 6S 2H 9S AD 2D TD KH 3S
7D AS 3H TS 6H 9S 7D AD 2C 5H JD 9C 4H
TH 8S KC 6C AC 5H 7S TH 6H 2D 5H AC 5D
4C KD 7H 8D 5C QS 8S KS QD JH JC 3C 8H
JH 4C JC 7S 4C 6D AD 4S TC 9S 4H JS 2C
QS 2S QC 9D TC JS QC 8D AS 3H 4H 8S 4D
AH 7C 2S KC 7D QH QC 3S 9D 8H KH 7H 4S
AH 8C 3C JD TS 9C AS TS 5S JS 4D 6D 8H
KS KD 2H 3H QS 5C 7H

(Adapted from: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3551.pdf)

Coincidentally the C++ container deque is usually pronounced like 'deck." A deque of cards.

I chose a deque for its efficient deletion of elements at the front and end of the container.
Last edited on
Topic archived. No new replies allowed.