Deck of Cards for Blackjack Algorithm

I am trying to make an algorithm that plays blackjack perfectly. My first step is to create the deck of cards. I was thinking something like this:

struct cards {
int value;
string suit;
};

int main()
{
cards deck[52] = {}

for (int i = 2; n < 15; n++)
{

I think using a class or struct would be ideal to be able to assign a value and suit to each card by an int and string, respectively. Then I want to make an array of type cards, but I am very confused on how I should initialize it to create the values.

Would greatly appreciate any help--in letting me know if I am headed in the right direction and how to properly initalizing by looping through and setting the values. Thanks!
Something along these lines, perhaps:

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
#include <iostream>
#include <array>
#include <algorithm>
#include <random>

struct card
{
    enum suit_t { SPADES, HEARTS, DIAMONDS, CLUBS };
    static constexpr int MIN_VALUE = 2 ;
    static constexpr int MAX_VALUE = 14 ;
    static constexpr int NCARDS = 52 ;

    suit_t suit = SPADES ;
    int value = MIN_VALUE ;

    bool valid() const { return value >= MIN_VALUE && value <= MAX_VALUE ; }

    friend std::ostream& operator<< ( std::ostream& stm, card c )
    {
        static const char suit_char[] = "SHDC" ;
        static const char value_char[] = "  23456789TJQKA" ;
        return stm << suit_char[c.suit] << ( c.valid() ? value_char[c.value] : '?' ) ;
    }

    using deck = std::array< card, card::NCARDS > ;
};

card::deck make_deck()
{
    card::deck deck ;

    int pos = 0 ;
    for( int s = card::SPADES ; s <= card::CLUBS ; ++s )
        for( int v = card::MIN_VALUE ; v <= card::MAX_VALUE ; ++v )
            deck[ pos++ ] = { card::suit_t(s), v } ;

    return deck ;
}

card::deck& shuffle_deck( card::deck& deck )
{
    static std::mt19937 rng( std::random_device{}() ) ;
    std::shuffle( std::begin(deck), std::end(deck), rng ) ;
    return deck ;
}

std::ostream& operator<< ( std::ostream& stm, const card::deck& deck )
{
    static const int LINE_SZ = 13 ;

    int cnt = 1 ;
    for( card c : deck )
    {
        stm << c << ' ' ;
        if( cnt++ % LINE_SZ == 0 ) stm << '\n' ;
    }

    return stm << '\n' ;
}

int main()
{
    card::deck deck = make_deck() ;
    std::cout << deck << '\n' ;

    for( int i = 0 ; i < 3 ; ++i ) std::cout << shuffle_deck(deck) << '\n' ;
}

http://coliru.stacked-crooked.com/a/1f878391b8551706
I am not the original person who posted this message, but I have a question. Please help me.

Why do we use friend std::ostream& operator<< ( std::ostream& stm, card c ).
Why do we use friend ? Couldn't we use it as regular function as below, without using
friend ?
std::ostream& operator<< ( std::ostream& stm, card c )
{
static const char suit_char[] = "SHDC" ;
static const char value_char[] = " 23456789TJQKA" ;
return stm << suit_char[c.suit] << ( c.valid() ? value_char[c.value] : '?' ) ;
}

Thank you.
> Couldn't we use it as regular function as below, without using friend?

Yes, we could.

The only differences are:

a. The non-member friend function defined within the body of the class is implicitly inline.

b. If a declaration of the function at the namespace scope is not provided (as in the above case),
the function can't be found via ordinary name look up (it can only be found via ADL).
This may be useful in large code bases (may reduce compilation times), where there are many other types for which the stream insertion operator has been overloaded.
Topic archived. No new replies allowed.