# Thread: I need help with a Blackjack game.

1. Originally Posted by wipeout4wh
The index is just the part of an array that's in square brackets, right?

If I do that, it would still reuse the cards that are still in play when I reshuffle the deck. If I have a 5 in my hand, there should only be 3 5's in the deck when it gets reshuffled. That means I would need to remove the card from the deck and add it to a discard pile when it's out of play.
So reshuffle not when you reach the last card, but when you don't have enough cards to play a full hand. It would not be fair to reshuffle in the middle of a hand.

Edit: I decided to have it shuffle the deck first like you guys said. Here's drawCard() so far:

Code:
```int drawCard() {

static int deck[52] = {1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13};
static int cardToDraw = 0;
int drawnCard;

if (cardToDraw < 52) {
drawnCard = deck[cardToDraw];
deck[cardToDraw] = 0;
cardToDraw++;
}
else {
shuffleDeck();
cardToDraw = 0;
}

cout<< "cardToDraw = "<< cardToDraw<< ".\n";//Debugging line.
return drawnCard;
}```
I'll have to learn about passing variables between functions, and I haven't written shuffleDeck() yet, but does this look good so far?

Edit: Would it be better to just set deck[52] as a global variable? I don't really understand how to pass variables between functions. I wrote part of shuffleDeck(), but I can't continue until I figure this out.

Code:
```void shuffleDeck() {

int firstCard;
int secondCard;
int i;

for (i = 0; i < 100; i++){
firstCard = (rand() % 52);
secondCard = (rand() % 52);

}
}```
I wish you knew pointers, because then I could tell you about std::random_shuffle().

The first like of shuffleDeck should look like this. Because deck is an array, modifying it in shuffleDeck will modify it in the original.
Code:
`void shuffleDeck(int deck[52])`
To call it simply do:
Code:
`shuffleDeck(deck)`
Also, you don't need to make your first card random, as long as your second card is. then you can loop from 0 to 52 (i<52), and know that every card has been swapped at least once.

2. I've learned a little about pointers, but I still don't completely understand why they are useful. I'll change my shuffling function to loop 52 times instead of 500. The code I posted only loops 100 times, but I changed it to loop 500 times just to be sure. I guess that's a little overkill if 52 loops is enough.

3. In this case a pointer would function as a iterator for an array. Often you need to access a specific element in a container like an array, such as when you loop through each element. With arrays, this can be done using the array name, plus the index, but this is not efficient for all containers. Even for arrays, using pointers can be faster. So instead the standard template library, which provides containers and common algorithms like random_shuffle(), relies on iterators to access elements. And for primitive arrays, a pointer functions as an iterator.

Pointers also provide a null-able pass by reference capability. One result of this is that is that pointers and smart pointers are used to signify ownership of heap variables.

4. Yeah... I didn't really understand that.

Originally Posted by King Mir
The first like of shuffleDeck should look like this. Because deck is an array, modifying it in shuffleDeck will modify it in the original.
Code:
`void shuffleDeck(int deck[52])`
To call it simply do:
Code:
`shuffleDeck(deck)`
So shuffleDeck() should use deck as a parameter? I made deck a global variable, so shuffleDeck() can access it even if it's not a parameter. Do I still need to do that?

Edit: I've made quite a bit of progress, but I still haven't started writing the actual game.

Code:
```#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>

using namespace std;

int drawCard();
void shuffleDeck(int deck[54]);
void game();

static int deck[52] = {1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13};

//The main function includes pre-game stuff and instructions.
int main() {

time_t now;//Sets now to equal the current time.
time(&now);
srand(now);//Uses the current time as the seed for random numbers.

char viewInstructions;

cout<< "Welcome to Blackjack.\nWould you like to view the instructions? (Y/N)\n";

do {
cin>> viewInstructions;
cin.ignore();

switch(toupper(viewInstructions)) {
case 'Y':
cout<< "Select an option by typing its letter.\nPress enter when you are ready to play.\n";
cin.get();
game();
break;
case 'N':
game();
break;
default:
cout<< "Syntax error. Please type Y or N, then press enter.\n";
}
}while (viewInstructions != 'y' || 'Y' || 'n' || 'N');

return 0;
}

//This function starts the game.
void game() {
int playerHand[5];
int dealerHand[5];

cout<< "game is running";//DEBUG
}

//This function draws a new card.
int drawCard() {

static int cardToDraw = 0;
int drawnCard;

if (cardToDraw < 52) {//If there are cards left in the deck, draw one.
drawnCard = deck[cardToDraw];
deck[cardToDraw] = 0;//Removes the card from the deck.
cardToDraw++;//Next time the function is called, it will draw the next card.
}
else {//If there are no cards in the deck, shuffle the deck.
shuffleDeck(deck);
cardToDraw = 0;//Draw deck[0] next time the function is called.
}

cout<< "cardToDraw = "<< cardToDraw<< ".\n";//Debugging line.
return drawnCard;
}

//This function shuffles the deck.
void shuffleDeck(int deck[54]) {

int cardToSwap;//This is the card that will be swapped with the first card.
int temp;//This is used to temporarily store the value of deck[cardToSwap]
int i;

for (i = 0; i < 52; i++){//Loops through each card, swapping it with a random card from the deck.
cardToSwap = (rand() % 52);
temp = deck[cardToSwap];
deck[i] = deck[cardToSwap];
deck[cardToSwap] = temp;
}
}```
I'm having some trouble getting the instruction do/while loop in main to work. For one thing, it displays the instructions no matter what I type. It also doesn't end after it calls the game function. It just waits for input from the user, then keeps waiting for more input if any is given.

I do plan to expand the instructions. I just didn't feel like typing out a guide to Blackjack, so I used that as a placeholder.

Edit: Would it be better to use a switch for the instructions?

Edit: I changed it to a switch, and it's working good (it doesn't show the instructions if I type n or N). It still continues to wait for input instead of ending the program, though. Could that just be because I haven't written game() yet? I updated the code above to the version with the switch.

5. Explaining how pointers are used in one shorts post is limiting.

You should avoid global variables. You should avoid static variables too, for that matter, and instead declare deck in main.

"(viewInstructions != 'y' || 'Y' || 'n' || 'N')"

This doesn't do what you think it does. It checks viewInstructions != 'y', then if 'Y' !=0, then 'n' !=0, then 'N'!=0.

6. Originally Posted by King Mir
Explaining how pointers are used in one shorts post is limiting.

You should avoid global variables. You should avoid static variables too, for that matter, and instead declare deck in main.

"(viewInstructions != 'y' || 'Y' || 'n' || 'N')"

This doesn't do what you think it does. It checks viewInstructions != 'y', then if 'Y' !=0, then 'n' !=0, then 'N'!=0.
Why should I avoid static and global variables? Isn't it kind of necessary to use them sometimes?

I did manage to fix my do/while loop before you posted that, but I didn't mention it.

Code:
```do {
cin>> viewInstructions;
cin.ignore();

switch(toupper(viewInstructions)) {
case 'Y':
cout<< "Select an option by typing its letter.\nPress enter when you are ready to play.\n";
cin.get();
viewInstructions = 'N';//If this is not set to 'N', the do/while will continue to loop.
game();
break;
case 'N':
game();
break;
default:
cout<< "Syntax error. Please type Y or N, then press enter.\n";
}
}while ((toupper(viewInstructions)) != 'N');```
I kind of feel like setting viewInstructions to 'N' in case 'Y' is an awkward solution, but it does work.

7. There are times when global variables are the best solution, but usually they are not. One disadvantage here is the re-usability and versatility of the drawCard function. It can only draw cards from the global deck. Another is that it's harder to track what functions modify deck. This makes debugging harder.

You can use ||, you just have to put compare viewInstructions to every letter explicitly.

Code:
```    do {
cin>> viewInstructions;
cin.ignore();

switch(toupper(viewInstructions)) {
case 'Y':
cout<< "Select an option by typing its letter.\nPress enter when you are ready to play.\n";
cin.get();
game();
break;
case 'N':
game();
break;
default:
cout<< "Syntax error. Please type Y or N, then press enter.\n";
}
} while ((toupper(viewInstructions)) != 'N' && (toupper(viewInstructions)) != 'Y');```
If I used ||, it would loop no matter what because it's checking to see if it's unequal to 'Y' or 'N'. It can't be equal to both, so the loop condition will always be true.