User Tools

Site Tools


Sidebar

projects

wcp1 (due 20240828)
btt0 (due 20240904)
wcp2 (due 20240904)
pct0 (bonus; due 20240905)
pct1 (bonus; due 20240905)
pct2 (due 20240905)
abc0 (due 20240906)
msi0 (due 20240911)
pct3 (bonus; due 20240911)
wcp3 (due 20240911)
msi1 (due 20240918)
pct4 (due 20240918)
wcp4 (due 20240918)
dsr0 (due 20240926)
pct5 (bonus; due 20240926)
wcp5 (due 20240926)
gfo0 (due 20241002)
pct6 (due 20241002)
pnc0 (due 20241002)
wcp6 (due 20241002)
dsr1 (due 20241009)
pct7 (bonus; due 20241009)
wcp7 (due 20241009)
bwp1 (bonus; due 20241016)
pct8 (due 20241016)
pnc1 (due 20241016)
wcp8 (due 20241016)
pct9 (bonus; due 20241023)
pnc2 (due 20241023)
wcp9 (due 20241023)
gfo1 (due 20241030)
mag0 (due 20241030)
pctA (due 20241030)
wcpA (due 20241030)
mag1 (due 20241106)
pctB (bonus; due 20241106)
wcpB (due 20241106)
mag2 (due 20241113)
pctC (due 20241113)
wcpC (due 20241113)
pctD (bonus; due 20241120)
wcpD (bonus; due 20241120)
bwp2 (bonus; due 20241204)
gfo2 (due 20241204)
pctE (bonus; due 20241204)
wcpE (bonus; due 20241204)
EoCE (due 20241216)
haas:fall2024:discrete:projects:bjm0

Corning Community College

CSCS2330 Discrete Structures

PROJECT: Black Jack Math (BJM0)

OBJECTIVE

Using your card game infrastructure from an earlier project, retool it into a blackjack game that provides some probability stats during gameplay (you vs house, chances of getting 21 based on current deal, etc.)

EDIT

You will want to go here to edit and fill in the various sections of the document:

BJM0

RULES

The primary objective of blackjack is to beat the dealer by having a hand value closer to 21 without exceeding it. If your hand goes over 21, you “bust” and lose the game. If the dealer busts and you don't, you win.

  • Number cards (2-10) are worth their face value.
  • Face cards (Jack, Queen, King) are worth 10 points each.
  • Aces can be worth 1 or 11 points, if an 11 would cause your hand to bust; it is counted as a 1, if not it is counted as a 11.

Here is how the game is played:

  1. Each player, including the dealer, is initially dealt two cards. (the dealer has one faced down and the other up)
  2. Players can choose to “hit” (take another card) or “stand” (keep their current hand).
  3. Players can continue to hit until they decide to stand, or until they bust by exceeding 21.
  4. After all players have finished their turns, the dealer reveals their facedown card.
  5. The dealer must hit until their hand reaches at least 17 points.
  6. If the dealer busts, all remaining players win.
  7. If the dealer doesn't bust, then the hands of all remaining players are compared to the dealer's hand, and the players with a hand larger than the dealer but lower than 22 wins.

GAMEPLAY

Shuffle Cards and Values

In past documentation pages we implemented a way to shuffle cards but that way made it hard/impossible to assign values to your cards. This way fixes that. We are still using the same logic but are calling more arrays in the Fisher-Yates shuffle algorithm.

The following 2 arrays are needed:

// Values to be assigned to each card
int[52] cardValues = {2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
                      2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
                      2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11,
                      2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11};
 
 
// All cards before they are randomized
int[52] cardOrder = {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};

Once you have created your arrays you will want to make the following for loop:

// Fisher-Yates shuffle algorithm
for (int i = 51; i > 0; i--)
{
    // Generate a random index between 0 and i
    int j = rand() % (i + 1);
 
    // Swaps cardOrder[i] and cardOrder[j], cardValues[i] and cardValues[j]
    int temp = cardOrder[i];
    int temp2 = cardValues[i];
    cardOrder[i] = cardOrder[j];
    cardValues[i] = cardValues[j];
    cardOrder[j] = temp;
    cardValues[j] = temp2;
}

In this version of the shuffle, we also shuffle the card values making it so they still line up and are assigned correctly. This version does not include suits but you can also do the same thing. Create an array of numbers 0-3. the numbers represent a suit so heart could be 0, diamond as 1, spade as 2, and clubs as 3.

Ace Logic

One of the unique aspects of Black Jack is that an Ace can either be 11 or 1 depending on what the player decides. Here is an example of a hand involving an Ace.

Example 1: The player is dealt a 5 and an Ace. they then draw and get a King. If the player decided to keep the Ace an 11 then they would bust and the dealer would win but you can switch the Ace to 1 and not bust.

The challenging aspect of this is how would you implement this so the game automatically handles this for the player.

To start you need to create two int variables, one to keep track of the current score of the player and one to keep track of how many aces are dealt to the player. Note: Ace is originally set to 11 because starting with the highest value the ace can be is easier and requires less testing.

int PlayerScore = 0;
int NumberOfAces = 0;

Next, inside your button logic for asking for another card from the dealer use the following if statements:

        // If X is pressed than next card is shown and the value of that card is added to PlayerScore
        if (hit) {
            PlayerScore+= card->value; // Random card that is displayed is added to PlayerScore
 
            // Logic for handling what value ace should be. if it should be 1 or 11
            if (card->value == 11)
            {
                 NumberOfAces++;
            }
 
            if (PlayerScore > 21 && NumberOfAces > 0)
            {
                 PlayerScore -= 10;
                 NumberOfAces--;
            }
        }
Dealer Strategy

The dealer in blackjack always hits until hitting at least 17, and goes after the player does. A simple way of doing this is to out a check for if the player stands or busts towards the end of the loop, and set a flag if they do.

  if(stand == true || playerbust == true){}

Next you need a check to see if the dealer's cards already add up to 17 or greater, and if not then have them draw a card. You repeat this until the dealer has the correct value of cards, check if they bust or not, and if not then compare it to the player.

CHANCES

In a standard 52 card deck, there are

  • 4 aces
  • 16 cards with the value of 10
  • 32 cards with values from 2-9.

The probability of getting Blackjack for the first 2 cards dealt accounts for all the possible combinations of 2 cards and the cases which the 2 cards add to 21.

Calculating Bust Probabilities:

To calculate probabilities for a bust, between both the player and the house, you'll need a way to compare against all possible outcomes. You'll need a way to store these potential outcomes that isn't the deck itself. Either an array or list should work, but for this example we'll use an array.

Each slot in the array will represent a drawn card's potential point value. Since Aces can be either 1 or 11, but we're calculating the probability of a bust, we only need to count Aces as 1s. So in total we'll have 10 array slots, and the number stored in each slot is the number of cards with that point value theoretically stored in the deck.

int[ 10 ] deckProbabilities

When dealing cards, make sure to decrement its point value from the probabilities array. (i.e. you draw the 5 of Spades, decrement deckProbabilities[4].) In the case of the house's face down card, do NOT decrement its probability! Since the player doesn't know what it is specifically, that card's value could still theoretically be pulled from the deck from the perspective of the player.

To calculate the player's bust chance, we'll need three more variables alongside the array:

int playerScore; // The current score of the player.
int bust;        // Counting number for the number of bust outcomes.
int total;       // Counting number for the number of total outcomes.

You'll need to loop through for each possible value stored in the deckProbabilities[] array. If the number stored added to the player's score is higher than 21, increment both bust and total. If the sum is still 21 or lower, only increment total. After every value has been checked, divide bust by total to get your percentage chance in decimal form.

 

SUBMISSION

To be successful in this project, the following criteria (or their equivalent) must be met:

  • Project must be submit on time, by the deadline.
    • Late submissions will lose 33% credit per day, with the submission window closing on the 3rd day following the deadline.
  • Executed programs must display in a manner similar to provided output
    • output formatted, where applicable, must match that of project requirements
  • Processing must be correct based on input given and output requested
  • Output, if applicable, must be correct based on values input
  • Code must be nicely and consistently indented
  • Code must be consistently written, to strive for readability from having a consistent style throughout
  • Code must be commented
    • Any “to be implemented” comments MUST be removed
      • these “to be implemented” comments, if still present at evaluation time, will result in points being deducted.
      • Sufficient comments explaining the point of provided logic MUST be present
  • No global variables (without instructor approval), no goto statements, no calling of main()!
  • Track/version the source code in your lab46 semester repository
  • Submit a copy of your source code to me using the submit tool by the deadline.

Submit Tool Usage

Let's say you have completed work on the project, and are ready to submit, you would do the following:

lab46:~/src/SEMESTER/DESIG/PROJECT$ submit DESIG PROJECT file1 file2 file3 ... fileN

You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.

RUBRIC

I'll be evaluating the project based on the following criteria:

208:bjm0:final tally of results (208/208)
*:bjm0:work towards a blackjack game [104/104]
*:bjm0:work towards chances info being displayed [104/104]

Pertaining to the collaborative authoring of project documentation

  • each class member is to participate in the contribution of relevant information and formatting of the documentation
    • minimal member contributions consist of:
      • near the class average edits (a value of at least four productive edits)
      • near the average class content change average (a value of at least 1024 bytes (absolute value of data content change))
      • near the class content contribution average (a value of at least 1kiB)
      • no zero-sum commits (adding in one commit then later removing in its entirety for the sake of satisfying edit requirements)
    • adding and formatting data in an organized fashion, aiming to create an informative and readable document that anyone in the class can reference
    • content contributions will be factored into a documentation coefficient, a value multiplied against your actual project submission to influence the end result:
      • no contributions, co-efficient is 0.50
      • less than minimum contributions is 0.75
      • met minimum contribution threshold is 1.00

Additionally

  • Solutions not abiding by spirit of project will be subject to a 50% overall deduction
  • Solutions not utilizing descriptive why and how comments will be subject to a 25% overall deduction
  • Solutions not utilizing indentation to promote scope and clarity or otherwise maintaining consistency in code style and presentation will be subject to a 25% overall deduction
  • Solutions not organized and easy to read (assume a terminal at least 90 characters wide, 40 characters tall) are subject to a 25% overall deduction
haas/fall2024/discrete/projects/bjm0.txt · Last modified: 2023/10/21 16:41 by 127.0.0.1