Blackjack: Issues with repeating integers in array

Pages: 12
Dynamically allocated arrays are not used that much in C++. std::vector is preferred. The performance penalty is not as bad as jonnin alluded to earlier. It can be avoided by using reserve( <estimated-size> ) if you have a good idea in advance what the maximum size of the vector will be. Even if you're wrong, most implementation will double the capacity of the vector when needed. Yes, that involves a copy operation, but it doesn't happen all that frequently.

There's nothing magic happening under the covers with vectors. If you need to resize your array, you can reallocate it yourself.
1
2
3
4
5
6
7
8
9
10
11
12
    int newsize;
    int oldsize = 52;
    card* deck = new card[oldsize];
    card* temp;

    cout << "How big would you like your deck to be? " << endl;
    cin >> newsize;
    temp = new card[newsize];
    //  It's only necessary to copy it if you want the contents of the old deck in the new game.
    memcpy(temp, deck, sizeof(deck) * oldsize);
    delete[] deck;
    deck = temp;
Last edited on
right, vector is doing the memory management that I mentioned on a small scale, internally and just for itself (per vector). You can do that too... instead of newsize, you can use newsize * 2 or 10 or whatnot and track used size vs real size. C++ vectors are really well crafted to avoid excessive copying, agreed. They are one of the best designed and implemented features of all time.
A std::deque might be better suited for a deck of cards than a std::vector. Growth and reallocation is less burdensome since the container's elements are not necessarily contiguous.

For gits and shiggles I mashed together a very rudimentary start to a casino setup for Blackjack. Multiple decks (3) in "the shoe" and the players (2) and the dealer being dealt two starting cards consecutively.
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
#include <iostream>
#include <deque>
#include <vector>
#include <random>
#include <numeric>

int main()
{
   std::default_random_engine prng(std::random_device {} ());

   using card = unsigned;

   std::deque<card> deck(52);

   std::iota(deck.begin(), deck.end(), 0);

   auto rank = [] (card c) { return "AKQJT98765432"[c % 13]; };
   auto suit = [] (card c) { return "SHDC"[c / 13]; };

   std::deque<card> shoe;

   for (size_t i { }; i < 3; ++i)
   {
      for (const auto& itr : deck)
      {
         shoe.push_back(itr);
      }
   }

   std::shuffle(shoe.begin(), shoe.end(), prng);

   for (card ccount { }; const card & c : shoe)
   {
      std::cout << rank(c) << suit(c) << ' ';
      ccount++;

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

   std::vector<card> p1;
   std::vector<card> p2;
   std::vector<card> d;

   for (size_t itr { }; itr < 2; ++itr)
   {
      p1.push_back(*shoe.begin());
      shoe.pop_front();

      p2.push_back(*shoe.begin());
      shoe.pop_front();

      d.push_back(*shoe.begin());
      shoe.pop_front();
   }

   // display players' and dealer's hands
   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';

   for (card ccount { }; const card & c : shoe)
   {
      std::cout << rank(c) << suit(c) << ' ';
      ccount++;

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

Player 1: 4S 2S
Player 2: 6S TH
Dealer:   (5C) 2S

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


Quick and dirty, as well as sloppy design. Making the shoe out of 3 decks definitely could have been done more efficiently. Same for handling the players' and dealer's hand.
Topic archived. No new replies allowed.
Pages: 12