Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

This game will make use of a server to join two clients together for a modified

ID: 3687416 • Letter: T

Question

This game will make use of a server to join two clients together for a modified game of Blackjack. I’ll explain how this modified game works below. Here’s your task: You’re going to create exactly two classes. One class will act as the functional server. The main method of this server will setup the connection on a localhost, find the two clients, let them know which one is Player 1 and which one is Player 2 (depending on the order they connect), and then manage the game as it’s being played.

This is important: For each player’s turn they should start by displaying their current score to the user. Then, the user should be prompted to select whether they want to “Hit” or “Stand”. This option selection can be done any way you choose, but invalid entries must be accounted for*. If the player chooses to “Hit”, the server should deal a “card” to the player, which will consist of choosing a random number between 1 and 13. The server sends this “card” to the player, and the player receives the card and adds it to their score. If the card is above a 10, then add a 10 to the player’s score instead of the original value (In a standard Blackjack game, Jacks, Queens, and Kings still count as 10). After they receive the card or if they choose to “Stand”, the next player should take their turn. If either player takes a “Hit”, and the card they’re dealt raises their score total above 21, then the game should immediately end and the other player is the winner (this is known as a “Bust”). Likewise, if both players choose to “Stand”, then both players should be shown the final scores and the game is then over. *for example, if you choose to say “Enter (1) For a Hit or enter (2) to Stand”, then any entry other than 1 or 2 should be counted as invalid and should loop to allow the player another entry. If you choose something like “Enter (H)it or (S)tand”, then valid entries should be “H”, “S”, and ideally “h” and “s”.

You May: Get user input in any way you choose, though you must check for invalid entries and prompt a re-entry if invalid data is entered; you may choose to implement an additional feature that allows a 1 (Ace) to be worth either 1 or 11, however this is not necessary; you may choose to deal two cards to each player to begin the game, however this is not necessary; you may choose to display the first card drawn to each player to both players, however this is not necessary; you may use driver classes and additional methods other than the main method in each class, however this is not necessary to complete this program.

You May Not: Exceed the scope of a console-based application – this means no GUIs, etc; you may not allow for more than two players by any means; you may not use two different client classes – one client must function as either player; you may not use or copy code from any source, including but not limited to other students, textbooks, online sources, activities from this class or any other class, or any other source. Copying code will result in a 0 grade on this assignment and possible other consequences.

Explanation / Answer

main.c
#include <stdio.h> /* printf, scanf */
#include <stdlib.h>
#include <ctype.h> /* toupper */
#include "cards.h" /* card functions */

int main()
{
    int bet, stake;
    int num_decks;
    shoe_t shoe;
    hand_t dealer_hand;
    hand_t user_hand;
    char response;

    /* print greeting */
    printf("Welcome to Blackjack! ");

    /* initialize the stake */
    stake = 1000;

    num_decks = 1;

    do
    {
        /* ask for number of decks to be used and validate response */
        if (num_decks <= 0)
            printf("Invalid number. Enter a positive integer: ");

        else
            printf("How many decks do you wish to play with (1-10)? ");

        scanf("%d", &num_decks);
    }
    while (num_decks <= 0);

    /* create shoe */
    shoe = create_shoe(num_decks);

    /* empty the dealer's and user's hands */
    dealer_hand = empty_hand();
    user_hand = empty_hand();

    /* initialize bet to 1 */
    bet = 1;

    /* play while the player has money left */
    while (stake > 0)
    {
        /* print remaining stake and number of cards left in the shoe */
        printf("Your stake: $%d ", stake);
        printf("Cards left in shoe: %d ", cards_left(shoe));

        do
        {
            /* ask user for bet and validate response */
            if (bet > stake || bet == 0)
                printf("Invalid bet. Enter a positive integer less than your stake (negative to quit): ");

            /* ask user for bet and validate response */
            else
                printf("Enter your bet (negative to quit): ");

            scanf("%d", &bet);

            /* if the bet is negative, then end the program */
            if (bet < 0)
            {
                printf("You ended the night with $%d. ", stake);
                free_shoe(&shoe);
                exit(1);
            }

        }while (bet > stake || bet == 0);

        /* draw the dealer's and player's hands */
        add_card_to_hand(&dealer_hand, draw_card(&shoe));
        add_card_to_hand(&user_hand, draw_card(&shoe));
        add_card_to_hand(&dealer_hand, draw_card(&shoe));
        add_card_to_hand(&user_hand, draw_card(&shoe));

        /* display only the first card in the dealer's hand */
        printf("The dealer is showing ");
        print_card(dealer_hand.cards[0]);
        printf(" ");


        response = 'H';

        /* play this hand while user has not busted or stood */
        while (blackjack_points(user_hand) < 21 && response == 'H')
        {

            /* display the entire player's hand */
            printf("Your cards: ");
            print_hand(user_hand);
            printf("Score: %d ", blackjack_points(user_hand));

            /* ask player to hit or stand and validate response */
            do
            {
                if (response != 'H' && response != 'S')
                    printf("Invalid response. Enter H or S: ");
                else
                    printf("Do you want to (H)it or (S)tand? ");

                scanf(" %c", &response);
                response = toupper(response);
            }
            while (response != 'H' && response != 'S');

                /* if player hits, then draw a card */
                if (response == 'H')
                    add_card_to_hand(&user_hand, draw_card(&shoe));
        }

        /* if the player stands, then dealer plays */
        if (response == 'S')
        {
            /* draw cards until score is at least 17 */
            while (blackjack_points(dealer_hand) < 17)
                add_card_to_hand(&dealer_hand, draw_card(&shoe));

            /* if the dealer busts, then the player wins */
            if (blackjack_points(dealer_hand) > 21)
            {
                printf("Dealer cards: ");
                print_hand(dealer_hand);
                printf("Score: %d ", blackjack_points(dealer_hand));
                printf("Dealer busts! You win $%d! ", bet);
                stake +=bet;
                bet = 1;
            }
        }

        /* if the player busts, then they loose */
        else if (blackjack_points(user_hand) > 21)
        {
            printf("Your cards: ");
            print_hand(user_hand);
            printf("Score: %d ", blackjack_points(user_hand));
            printf("You busted. You lose $%d! ", bet);
            stake -= bet;
            bet = 1;
        }

        /* if neither bust and the dealer has a better score, then the dealer wins */
        if (blackjack_points(dealer_hand) > blackjack_points(user_hand) && blackjack_points(dealer_hand) <= 21)
        {
            printf("Dealer cards: ");
            print_hand(dealer_hand);
            printf("Dealer wins with score of %d. You lost! ", blackjack_points(dealer_hand));
            stake -= bet;
        }

        /* if neither bust and the player has a better score, then the player wins */
        else if (blackjack_points(user_hand) > blackjack_points(dealer_hand) && blackjack_points(user_hand) <= 21)
        {
            printf("Your cards: ");
            print_hand(user_hand);
            printf("Dealer cards: ");
            print_hand(dealer_hand);
            printf("You win with a score of %d ", blackjack_points(user_hand));

            /* add the bet to player's stake */
            stake += bet;
            bet = 1;
        }

        /* if neither bust and their scores are equal, then it is a tie */
        else if (blackjack_points(user_hand) == blackjack_points(dealer_hand))
        {
            printf("Dealer cards: ");
            print_hand(dealer_hand);
            printf("Score: %d ", blackjack_points(dealer_hand));
            printf("Tie! ");
            bet = 1;
        }

        /* empty player and dealer's hands */
        dealer_hand = empty_hand();
        user_hand = empty_hand();

    } /* keep playing if there is money left in the stake */

    /* free the shoe from memory */
    free_shoe(&shoe);

    /* tell user they lost the entire stake */
    printf("You've lost your entire stake! ");

    return 0;
}

cards.c

#include <stdio.h>      /* printf, scanf */
#include <stdlib.h>     /* calloc */
#include <ctype.h>      /* toupper */
#include <string.h>     /* strcpy */
#include <time.h>       /* time */
#include "cards.h"

#define MAX_SUIT 8        /* define max suit string length */
#define CARDS_PER_DECK 52 /* define cards in a deck as 52 */

/* Function: create_card
    creates a card given a suit and value
*/
card_t create_card (char suit, /* Rec'd: (S)pades, (H)earts, (D)iamonds, or (C)lubs. */
                    int value) /* Rec'd: value of the card (1-13) */
                                /* Returned: the created card */
{
    /* declare card to be created */
    card_t card;

    /* make sure suit is upper case */
    suit = toupper(suit);

    /* if the suit isn't valid, then create a (C)lubs card */
    if (suit != 'S' && suit != 'H' && suit != 'D')
        card.suit = 'C';
    else
        card.suit = suit;

    /* if the card value is invalid, then make it a 2 */
    if (value > 13)
        card.value = 2;
    else
        card.value = value;

    /* return the created card */
    return card;
}

/* Function: print_card
    prints a card in plain english.
*/
void print_card (card_t card) /* Rec'd: a card */
{
    /* declare string for storing the suit */
    char suit_string[MAX_SUIT];

    /* convert suit character to a string */
    if (card.suit == 'S')
        strcpy(suit_string, "Spades");
    else if (card.suit == 'H')
        strcpy(suit_string, "Hearts");
    else if (card.suit == 'D')
        strcpy(suit_string, "Diamonds");
    else
        strcpy(suit_string, "Clubs");

    /* print the card value and suit */
    if (card.value == 1)
        printf("Ace of %s", suit_string);
    else if (card.value == 11)
        printf("Jack of %s", suit_string);
    else if (card.value == 12)
        printf("Queen of %s", suit_string);
    else if (card.value == 13)
        printf("King of %s", suit_string);
    else
        printf("%d of %s", card.value, suit_string);
}

/* Function: points
    finds the blackjack value of a card
*/
int points (card_t card)    /* Rec'd: a card */
                            /* Returned: blackjack value of the card */
{
    /* return 10 for jack, queen, or king */
    if (card.value > 10)
        return 10;

    /* return the value of other cards */
    else
        return card.value;
}

/* Function: create_shoe
    creates a shoe of the specified number of decks then shuffles the shoe.
*/
shoe_t create_shoe (int num_of_decks) /* Rec'd: number of decks to put in the shoe */
                                      /* Returned: the created shoe */
{
    shoe_t result_shoe;
    int i, j, k;

    /* allocate memory for the array */
    result_shoe.shoe = (card_t *) calloc(CARDS_PER_DECK * num_of_decks, sizeof(card_t));
    result_shoe.num_decks = num_of_decks;

    /* fill the shoe array with cards */
    for (i = 0; i < num_of_decks; i++)
        for (j = 0; j < 4; j++)
            for (k = 1; k <= 13; k++)
            {
                if(j == 0)
                    result_shoe.shoe[i*CARDS_PER_DECK + j*13 + k-1] = create_card('S', k);
                else if (j == 1)
                    result_shoe.shoe[i*CARDS_PER_DECK + j*13 + k-1] = create_card('H', k);
                else if (j == 2)
                    result_shoe.shoe[i*CARDS_PER_DECK + j*13 + k-1] = create_card('D', k);
                else
                    result_shoe.shoe[i*CARDS_PER_DECK + j*13 + k-1] = create_card('C', k);
            }

    /* shuffle the shoe */
    reshuffle(&result_shoe);

    /* return the created shoe */
    return result_shoe;
}

/* Function: draw_card
    draws the next card in a shoe.
*/
card_t draw_card (shoe_t *a_shoe) /* Rec'd/P'back: a shoe of cards */
                                  /* Returned: a card */
{
    /* reshuffle the deck if no cards are left */
    if (cards_left(*a_shoe) == 0)
        reshuffle(a_shoe);

    /* draw and return the next card */
        a_shoe->next++;
        return a_shoe->shoe[a_shoe->next - 1];
}

/* Function: cards_left
    returns however many cards are left in the shoe.
*/
int cards_left (shoe_t a_shoe) /* Rec'd: a shoe of cards */
                               /* Returned: number of cards left */
{
    /* calculate and return the number of cards left */
    return (a_shoe.num_decks*CARDS_PER_DECK - a_shoe.next);
}

/* Function: reshuffle
    randomly switches the positions of the cards in a shoe.
*/
void reshuffle (shoe_t *a_shoe) /* Rec'd/P'back: a shoe of cards */
{
    /* declare variables for indexes of cards to be switched */
    int i, n, random_position;

    /* declare a temporary card variable */
    card_t temp;

    /* seed the random number generator */
    srand(time(0));

    /* tell the player that the deck is being shuffled */
    printf(" SHUFFLING! ");

    /* set n to total number of cards */
    n = a_shoe->num_decks * CARDS_PER_DECK;

    /* randomly swap cards' positions */
    for (i=0; i < n; i++)
    {
        random_position = i + rand() % (n-i);
        temp = a_shoe->shoe[random_position];
        a_shoe->shoe[random_position] = a_shoe->shoe[i];
        a_shoe->shoe[i] = temp;
    }

    /* set the next card to 0 */
    a_shoe->next = 0;
}

/* Function: free_shoe
    frees a shoe from memory.
*/
void free_shoe (shoe_t *a_shoe) /* Rec'd/P'back: a shoe */
{
    /* free the shoe */
    free (a_shoe->shoe);
}

/* Function: empty_hand
    sets the number of cards in a hand to 0.
*/
hand_t empty_hand ()
                     /* Returned: an empty hand */
{
    /* create the hand to be be returned */
    hand_t hand;
    /* set number of cards to 0 */
    hand.num_cards = 0;
    /* return the empty hand */
    return hand;
}

/* Function: print_hand
    prints all the cards in a hand.
*/
void print_hand (hand_t a_hand) /* Rec'd: a hand of cards */
{
    /* initialize lcv */
    int i;

    /* print all the cards */
    for (i = 0; i < a_hand.num_cards; i++)
    {
        print_card(a_hand.cards[i]);
        printf(" ");
    }
}

/* Function: add_card_to_hand
    adds a card to a player's hand.
*/
void add_card_to_hand (hand_t *a_hand, /* Rec'd/P'back: a hand */
                       card_t card)    /* Rec'd: a card */
{
    /* put the card in the shoe's array of cards */
    a_hand->cards[a_hand->num_cards] = card;

    /* add 1 the number of cards in the hand */
    a_hand->num_cards++;
}

/* Function: blackjack_points
    calculates the total points for a hand.
*/
int blackjack_points (hand_t a_hand) /* Rec'd: a hand */
                                     /* Returned: total points */
{
    /* initialize lcv and the sum of card points */
    int i, sum = 0;

    /* add the points of each card to the total */
    for(i = 0; i < a_hand.num_cards; i++)
    {
        sum += points(a_hand.cards[i]);
        /* add 11 if the card is an ace it wont bust the player */
        if (sum <= 11 && points(a_hand.cards[i]) == 1)
            sum += 10;
    }

    /* return the sum of the points */
    return sum;
}

cards.h

#ifndef CARDS_H_INCLUDED
#define CARDS_H_INCLUDED

#define MAX_HAND 21

/* declare structs */
typedef struct {
    char suit;
    int value;
}card_t;

typedef struct {
    card_t *shoe;
    int num_decks;
    int next;
}shoe_t;

typedef struct {
    card_t cards[MAX_HAND];
    int num_cards;
}hand_t;

/* function headers: */
extern card_t create_card (char suit, int value);
extern void print_card (card_t card);
extern int points (card_t card);
extern shoe_t create_shoe (int num_of_decks);
extern card_t draw_card (shoe_t *a_shoe);
extern int cards_left (shoe_t a_shoe);
extern void reshuffle (shoe_t *a_shoe);
extern void free_shoe (shoe_t *a_shoe);
extern hand_t empty_hand ();
extern void print_hand (hand_t a_hand);
extern void add_card_to_hand (hand_t *a_hand, card_t card);
extern int blackjack_points (hand_t a_hand);

#endif // CARDS_H_INCLUDED

sample output

Welcome to Blackjack!                                                                                                                                       
                                                                                                                                                            
How many decks do you wish to play with (1-10)? 2                                                                                                           
                                                                                                                                                            
SHUFFLING!                                                                                                                                                  
Your stake: $1000                                                                                                                                           
Cards left in shoe: 104                                                                                                                                     
                                                                                                                                                            
Enter your bet (negative to quit): 500                                                                                                                      
The dealer is showing Ace of Clubs                                                                                                                          
                                                                                                                                                            
Your cards:                                                                                                                                                 
3 of Spades                                                                                                                                                 
7 of Diamonds                                                                                                                                               
Score: 10                                                                                                                                                   
Enter your bet (negative to quit): -1                                                                                                                       
You ended the night with $500.                                                                                                                              
Your cards:                                                                                                                                                 
3 of Spades                                                                                                                                                 
7 of Diamonds                                                                                                                                               
10 of Diamonds                                                                                                                                              
Score: 20                                                                                                                                                   
Do you want to (H)it or (S)tand? S                                                                                                                          
Dealer cards:                                                                                                                                               
Ace of Clubs                                                                                                                                                
10 of Diamonds                                                                                                                                              
Dealer wins with score of 21. You lost!                                                                                                                     
Your stake: $500                                                                                                                                            
Cards left in shoe: 99                                                                                                                                      
                                                                                                                                                            
Enter your bet (negative to quit): -1                                                                                                                       
You ended the night with $500.                                                                                                                              

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote