This is another lab exercise involving cards. There is a fair amount of code writing involved in this lab, but I've tried to lay out a step-by-step plan of attack in the "Your Assignment" section below. Be sure to test each piece of code as you proceed, as easy-to-fix errors in the early stages of coding can ripen into puzzling, hard-to-fix errors as the code gets more complex.
What follows is an unavoidable discussion of pseudorandomness, because you simply won't be able to do this week's lab (as well as a plethora of other interesting things) without understanding it at least from a programmer's standpoint.
This week you will write a program which, among other things, is able to shuffle a deck of cards. In order to accomplish this, your program will repeatedly choose "random" pairs of cards in a given deck and exchange them.
This process is complicated a bit by the fact that computers can't actually do anything random, since they are incapable of following inexact instructions. In other words, you can tell a computer to compute the square root of 1000, but you can't tell it to give you any number it feels like giving, because a computer doesn't feel like doing anything.
There are, however, algorithms that give you numbers that are seemingly random: these are called "pseudorandom" numbers. In c++, you can procure a pseudorandom number with the function rand(), which returns an integer between 0 and 32767 inclusive. Of course, there are only 52 cards in a deck, and as such you won't be able to swap cards 6 and 2006 in you shuffle program. Your program will need to choose "random" numbers on the interval 0 to 51 inclusive. You can do so using our old friend the mod operator (%), which once again proves a great convenience. To choose a random number in the interval [0,51], simply use rand() % 52. (Why does this work?)
A further note about pseudorandomness. One of the problems with pseudorandom number generators is they will choose the same sequences of random numbers on repeated invocations. Thus if you write a program to shuffle a deck by swapping pairs of cards in a deck, say, 1000 times, using rand() to generate the numbers, you will in fact end up with the very same shuffle every time you run the program. This, as you can imagine, is a huge shortcoming in a card game program!
You can work around this issue by providing the random number with a "seed" which will help determine the sequence of random numbers to be generated for, say, a given shuffle. There are fancy ways to do this, such as using the system time as a seed for the pseudorandom number generator, but we will not see any fancy techniques this week. Instead, the user him/herself will provide a random seed, and the computer will take it from there. You provide a seed to the pseudorandom number generator with the function srand(n), where n is an integer.
Here's the bottom line: In your main program, declare some int s. Ask your user for a random integer. Use cin to read their choice into s. Seed the pseudorandom generator by executing srand(s);. Then, and only then, shuffle the deck.
Be mindful of the fact that all this is done in the name of not shuffling the deck of cards the same way every time you run the program.
One last note: you need to include <cstdlib> at the top of your program in order to use srand and rand.
Create a new c++ file for this week.
The first step is to include all the functions, excluding main(), from lab 3 (the first poker lab).
Then, in your new main program, create an array deck of 52 integers, and populate it with 0 to 51 inclusive.
Then write the following utility functions, to simplify your
presentation to the user. Recall that you will need to type
Next write a function to exchange a pair of cards in the given deck.
Now we come to the heart of the matter. Write a shuffle function that swaps randomly selected pairs of cards, using your function swapcards.
It seems that there are some technical obstacles in declaring a dynamic array of two dimensions. If you get this far in lab, please implement the function deal so it returns a one dimensional array rather than two. The gray paragraphs below are the ones affected.
The function deal should return a two-dimensional array. It should be an array of hands, where each hand is an array of cards. I suggest you try to emulate the way in which real cards are dealt: one for the first player, one for the second, and so on around the circle until everyone has five cards.
To ease testing, try dealing hands from an unshuffled deck to see if you have achieved the desired behavior.
The function hand should return a hand (an array of five cards) from an array of arrays of the sort returned by the previous function. Note that this function can be implemented in one line.
Please note that, if your deal function has a return type of int*, the argument hands in the function hand should also have type int*.
(Optional) If you have time, implement a cut function, which cuts the deck at a given position.
Finally, implement another utility to simplify presentation.
Here is a sample interaction between a user and your program.
For the time being, never mind the fact that no layperson would have any clue what the first instruction meant. Furthermore, never mind the silliness of having a "Player 0": it's easier to program, and in the artificial context of the lab, you don't have to bother about it.Please enter a seed for the pseudorandom number generator: 123 Please enter the number of players: 3 Here are 3 hands: player 0: [3 of H, 5 of D, 8 of H, J of H, A of H] player 1: [Q of D, T of S, 4 of D, 6 of C, T of H] player 2: [9 of S, 8 of D, 2 of S, 7 of D, T of C]
Note that you now know enough to jazz up you card2string function so that it produces nicer representations like "King of Diamonds". I recommend against your spending lab time on that improvement, however, because there are more interesting challenges to attack (see below).
This following certainly cannot be finished in a lab period, but you may enjoy trying.
Implement as many of all the possible poker hand functions as possible. You may discover that because hands are now represented by arrays, certain programming tasks have become easier.
Here are the different flavors of poker hands in descending order:
If a given hand is none of these, then it is ranked according to its highest card. Thus you will need a function HighCard (returning int) to find the high card in a hand.
Note that these functions can build on one another. Consider the function isStraightFlush, which is presented here in full:
That is, you may find these functions easier to write as you go along.bool isStraightFlush(int* hand) { return (isStraight(hand) && isFlush(hand)); }
The ultimate goal of all of this work would be a function that, given an array of hands (an array of array of ints, that is), could identify which hand is best--who won, that is--and demonstrate why.