# Assignment 10

due at 6pm on Mon 21 Nov

For this assignment, you will implement the card game Blackjack using functions, and following a template I have created for you.

The template is available here: a10given.cpp. It contains extensive documentation that you should read, in addition to the descriptions and tasks below. (If it doesn’t show up correctly in the browser, right-click and “save target as.”)

## Description of the game

Note: This is not a complete or accurate implementation of the real game; for that, we’d need to learn a few more features of C.

A deck of cards has 52 cards. Each card has one of 13 ranks, which are the numbers 2 through 10, or Jack, Queen, King, Ace. Each card has one of 4 suits, which are Clubs, Hearts, Spades, and Diamonds. The suit is not used in this game, but we’ll still choose one and print it out for the sake of realism.

We can thus represent a card as a pair of integers: `rank` and `suit`. For rank, we’ll use an integer in the range 2 through 10, or these special constants for the other ranks:

``const int ACE = 1;const int JACK = 11;const int QUEEN = 12;const int KING = 13;``

For the suits, we’ll just use these arbitrary constants:

``const int CLUBS = 0;const int HEARTS = 1;const int SPADES = 2;const int DIAMONDS = 3;``

In the game, the player is initially dealt two cards, and the computer reports the score so far:

``````  ######################## starting game.
2 of hearts
``````

Scores are determined solely by the rank of the card. The numeric cards (2 through 10) are worth the amount indicated (2 through 10). Jack, Queen, and King (these are called face cards) are each worth 10 points. The Ace, for the purposes of this program, will be worth 11 points. (In the real game, you can choose to use it as just 1 point.) So, in the example above, 2 + King = 2 + 10 = 12 points.

Now, the player has a choice: he can choose to take another card (hit), or to stick with what he has (stay). We’ll ask the user to type in 1 or 0 to indicate the choice:

``````  Would you like to hit (1) or stay (0)? 1
7 of clubs
Would you like to hit (1) or stay (0)? 0
Thanks for playing.
``````

In this game, the user received a 7. Its score is added to the score from the first two cards, and he can choose again.

The goal of the game is to get as close as possible to 21 points, but not to exceed it. (In the real game, each player is competing with the dealer, and whoever gets closest to 21 wins.) We’ll use this constant to represent the target score:

``const int TARGET_SCORE = 21;``

If the player reaches 21 exactly, we don’t offer them the chance to hit again, and we announce Blackjack:

``````  King of hearts
4 of diamonds
Would you like to hit (1) or stay (0)? 1
7 of clubs
BLACKJACK!
Thanks for playing.
``````

If the player exceeds 21, them we announce Bust:

``````  King of hearts
2 of hearts
Would you like to hit (1) or stay (0)? 1
Would you like to hit (1) or stay (0)? 1
Ace of diamonds
BUST!
Thanks for playing.
``````

## Algorithm for game play

The given code is organized into functions with very specific tasks. The top-level game play algorithm is provided for you in the function `play_game`:

``void play_game(){    printf("######################## starting game.\n");    int rank, score;    // First two cards.    rank = deal_one_card();    score = rank_to_score(rank);    rank = deal_one_card();    score += rank_to_score(rank);    printf("Your score: %d\n", score);    // Loop as long as user wants (or until we hit 21).    while(score < TARGET_SCORE && ask_user_hit())    {        rank = deal_one_card();        score += rank_to_score(rank);        printf("Your score: %d\n", score);    }    // All done. Was it Blackjack or Bust?    maybe_announce_result(score);}``

Your task is to fill in the definitions of many of these functions. They are marked with `TODO` in the comments, and described as tasks below.

## Testing your program as you go

The `main` function, as given, calls two functions: `all_tests` and `play_game`. You may comment out one of these at a time, if you just want to focus on the tests or on the game itself.

Also, within `all_tests`, it may help if you comment out the tests that you’re not working on right now. So, when you are implementing `rank_to_score`, your `all_tests` might look like this:

``void all_tests(){    //test_print_card();    //test_deal_one_card();    test_rank_to_score();    //test_maybe_announce_result();}``

``void print_card(int rank, int suit){}``

This function should print out the card representing by the parameters `rank` and `suit`. Remember, these are just integers in the range 1–11 and 0–3, but you can use the constants like `ACE` and `SPADES` to distinguish them. You’ll probably use a couple of `switch` statements, and it’s fine to put a constant in a `case`, like this:

``    case SPADES:       // ... code here``

## Task 2: Choose a random card

We covered the use of `rand` in class. It returns an integer between 0 and `RAND_MAX`, which is a large number over 2 billion. You can shrink the range using the modulus operator (`%`) and then add to offset the range.

For example, if you want to model rolling a die, we’d want to produce numbers in the range 1–6. That can be done like this:

``      rand() % 6 + 1``

because the modulo 6 produces numbers between 0–5, and adding one brings the range up to 1–6.

Your function `deal_one_card` should also call `print_card`, and then it should return just the `rank`.

## Task 3: Determine score of a card

``int rank_to_score(int rank){    return 0; // temporary}``

This function takes a rank (1–13) and returns its score. In our game, the `ACE` is always worth 11 points; `JACK`, `QUEEN`, `KING` are worth 10 points, and the numeric cards have their face value (2–10).

``int ask_user_hit(){    return 0; // temporary}``