Software Documentation – Blackjack

INTRODUCTION

One of the games the games that was created by the team is Blackjack. Using the current MATLAB software, the Simple Game Engine, and readily available graphics resources, the team was able to write and program the popular casino game complete with a smart AI component and real time graphics. The process involved several stages of development, including incremental code writing, group meetings and discussions, and testing at different points in the game’s creation. After several weeks of research and development, the game progressed through several stages and the team has come up with a final product of the game, entitled ‘Blackjack’. Several pieces of documentation for the game and its development have been included: a user manual to explain the rules of the game and how it is played, a program description for developers to explain how the code operates and how it is structured, a flowchart illustrating the general algorithm involved in the game of Blackjack itself, the entirety of the code itself, a brief discussion about the progression of the game and the results and setbacks encountered during testing, and various conclusions and recommendations following the completion of the game design process.

USER MANUAL

The Blackjack program begins by presenting the user with a main menu. The user will be asked whether or not they would like to review the rules of this version of the card game, Blackjack. If they would like to review the rules, a set of rules on how to play will be displayed. The game will then start.

The game starts by dealing the user two cards, both face up. The dealer also draws two cards, one face up and one face down. The goal of the game is to try to obtain a score as high as possible in order to have a higher value than the dealer without going over 21 Each card in the deck has a value: numerical cards are worth their respective number, face cards are worth 10, and aces are worth either 11 or 1 (11 if it would not put the user over 21, 1 if 11 would put the user over 21).

After the user is given their two cards, the value of their current hand is displayed to the screen. They will then be asked if they would like to draw another card. They may continue to draw cards as long as their hand value does not exceed 21. If they draw a card that puts their value over 21, they bust and lose the hand. After the player is done drawing cards, the dealer reveals his face down card. If the dealer’s cards equal less than 17, the dealer will continue to draw cards until their hand equates to at least 17. If the dealer draws a card that puts their value over 21, the player automatically wins. If not, the dealer’s cards and the player’s cards are compared. Whoever has the higher value wins the hand.

Following each hand, the player will be given the options to play again, review the rules, or quit the game.

PROGRAM DESCRIPTION FOR DEVELOPERS

This program is comprised of a main function, blackjack_start, and several helper function designed to make the code as efficient as possible. It also utilizes the Simple Game Engine in order to generate corresponding graphics as the game progresses.

The main function acts as a sort of start menu for the game. It creates a graphic scene called ‘start_screen’ using the Simple Game Engine. It then creates a matrix of letter sprites using an available sprite sheet and displays this scene using the drawScene function from Simple Game Engine. The program outputs a welcome message and then prompts for a character value for the variable x that holds this input value throughout the function. The program will ask if the player wants to review the rules. The program will take ‘y’ for yes and display the rules or ‘n’ for no and continue on. It will also complete input validation, assuring that the user inputted either ‘y’ or ‘n’ using a while loop. While the character value entered does not equal either of these two values, it will continue to prompt the user. Following this, the program will take another arbitrary input value for x, simply asking the user to “enter any key to begin.” At this point the main function, the program will call the actual game function: blackjack_game (see below). Following the conclusion of the game function, the main function will prompt the user for a character value for the variable x, asking for ‘y’ if they would like to play again, ‘n’ if they would like to exit the game, and ‘r’ if they would like to review the rules. Once again, the program will validate the input of the user: while the character value of x does not equal ‘y’, ‘n’, or ‘r’, the game will prompt again to enter one of these three values. If the user enters ‘r’, the program will display the rules and prompt again for one of the three values. If the user enters ‘n’, the program will display a ‘thank you’ message and end. If the user enters ‘y’, the game will call the game function, blackjack_game. At the conclusion of the game function, the main function will again prompt for either ‘y’, ‘n’, or ‘r’ and repeat the process for handling these inputs.

________________________________________________________________________________________________

The game function, blackjack_game, carries out the actual game itself. It takes no input parameters. The function begins by displaying a welcome message and utilizing a command to suppress an unnecessary warning message. It then creates an array called ‘userDraw’ that will hold the values of the cards drawn by the user throughout the game. The function draws a random card for the user by using the MATLAB function, randi(n), which generates a random number between 1 and n (in this case 52, the amount of cards in the deck). Using this random number, the function calls a helper function, FindCardVal (see below), to find the numerical value of this card that will later correspond to its position on a sprite sheet of cards. The user draws two cards, so this operation is carried out for the first two indices of the array userDraw. This version of Blackjack is played as if using a singular deck, so the function checks to see if the two randomly generated numbers are the same using a while loop. While the numerical value of the second card is the same as the first card, the function generates a new random number and checks the while loop condition again.

At this point one card will need to be drawn for the dealer, so the function obtains a random card using the FindCardVal helper function and an array for the dealer’s cards, DealerDraw().

The function then initializes a new scene entitled card_scene which will hold the ‘values’ of the created graphics containing an available sprite sheet and the RGB code of the background color of the scene. The graphics that are created are based on two layers of sprites, a  background matrix, called ‘bg’, and a card matrix, called ‘table’, which contains the current cards in play. The bg matrix is initialized with white sprites acting as backgrounds for card sprites (value of 2 on the sprite sheet) and open slots for cards that have not been played yet (value of 11 on the sprite sheet). It then initializes the table matrix as containing the two cards for the user, and the card drawn and one upside-down card for the dealer (based on the rules of Blackjack). Using the drawScene function provided by the Simple Game Engine, the function generates a figure containing the current graphic arrays. It also utilizes a built in MATLAB function, movegui(‘north’), that moves the figure to the top of part of the screen.

Using the helper function, FindInitialVal (see below), the function initializes the variable, ‘initialValue’, to determine the value of the user’s hand at the beginning of the game. This value is displayed to the screen and the user asked whether or not they would like to take another card, where they may enter ‘y’ for yes or ‘n’ for no. The variable, ‘hitOrStay’, holds the character value for this input. The function validates this input using a while loop. While this character value is not equal to either ‘y’ or ‘n’, it prompts again for one of these two values.

The function then sets a new variable, ‘currentValue’ equal to the initial value and, using a while loop, continues to draw new cards for user using the FindCardVal function and add this value to an the array userDraw at the index variable ‘i’. Additionally, it uses the checkIfSame function to determine if this card has already been drawn in the game. If it returns true, it draws another random card and repeats the process. Next, the function assigns new values of the bg matrix and the table matrix based on the the newest card that has been drawn and uses the drawTable function (see below) to output the graphical display. The ‘currentValue’ variable is set using the FindNewVal function (see below) and this value is then compared to 21. If this value exceeds 21, the function sets the logical variable ‘lose’ equal to true, outputs a ‘bust’ message, and breaks the loop. If the value is less than 21, the function prompts the user if they would like another card and takes an input value for the variable ‘hitOrStay’. The same process for determining the value of hitOrStay is repeated as it was before, the value of ‘i’, the index variable, is incremented, and the loop returns to the beginning and if hitOrStay is equal to the character value ‘y’, the loop runs.

A similar process must then be completed for the dealer. A card is drawn using the FindCardVal function and a randomly generated number and is stored in the DealerDraw array at index 2. The helper function checkIfSame is used to check if the newly drawn card is the same as the first card drawn by the dealer. If it returns true, another random card is drawn and the process is repeated. The bg and table matrices are updated based on the value of the newly drawn card and are displayed to the screen using the drawTable function.

The variable ‘currentDealerValue’ is initialized to the combined value of the dealer’s hand using the FindNewVal function. Using a while loop, the function continues to draw the cards as long as the value of currentDealerValue is less than 17. The same process of validating the newly drawn card and is repeated for each iteration of the while loop. Additionally, the function will pause and prompt the user to input an arbitrary value to continue the game each time the dealer draws a new card. With each iteration of the loop, the bg and table matrices are updated based on the newly drawn cards and are displayed using the Simple Game Engine. When the value of currentDealerValue is at least 17, the loop no longer runs.

If the value of the logical variable ‘lose’ is set as true at this point in the game, the player has already busted and the losing message was already displayed and there is no need to compare the player’s and dealer’s values. If the value of the logical variable ‘lose’ is still set to false, then the value of currentValue and currentDealerValue must be compared to determine the outcome of the game. If currentValue is greater than currentDealerValue or currentDealerValue is greater than 21, the player wins the game and a winning message is displayed. If currentValue is equal to currentDealerValue, the game is a draw and a draw message is displayed. If currentValue is less than currentDealerValue, the player loses the game and a losing message is displayed.

________________________________________________________________________________________________

The helper function checkIfSame is implemented to determine if a the numerical value of a newly generated number is equal to any other value in the passed array. It is passed an array of numerical values called Draw and the current index i at whatever point in the game function that this helper function is called. It returns the logical variable called ‘same’. It contains a for loop using an indexing variable ‘j’ that goes form 1 to i minus 1 in order to check every value in the array. If at any time in the for loop the value of the Draw at index i is equal to Draw at any index of j, the logical variable ‘same’ is set to true and the loop breaks. If the value of Draw at index i is never equal to any value of Draw at index j, the function returns the logical variable ‘same’ as false.

________________________________________________________________________________________________

The helper function FindCardVal is used to find the numerical value of a card that corresponds to its physical position on a sprite sheet used to generate graphics for the game. The function is passed a number x and returns the new value of the card, cardVal. The function uses an indexing variable ‘i’ and loops from 1 to 52. If the value of x equals i, carsVal is set equal to 20 plus x and returned to where it was called.

________________________________________________________________________________________________

The helper function FindInitialVal is implemented to find the initial value two cards using a passed array Draw. The variable ‘Draw1’ is set equal to the value of the Draw at its first index position and the variable ‘Draw2’ is set equal to the value of Draw at its second index position. Both of these values go through an algorithm to convert them to a numerical score. First, 20 is subtracted from each of these values in order to return them to their orginal randomly generated number. Then, using a while loop, while the initial value of Draw1 or Draw2 are greater than 13, 13 is subtracted from the value in order to convert it to a between 1 and 13. Then, if either value is greater than 10, it is set equal to 10, as all face cards have a score of 10. Addtionally, if either value is equal to 1, the score is set equal to 1, as ace cards have a score of 11 . The initial value of the 2 cards is the sum of the two final values of Draw1 and Draw2.

________________________________________________________________________________________________

The helper function FindNewVal is used to find the value of a hand after a new card is drawn. It uses the currentValue of the hand, the array of values of the hand, Draw, and the current index i at the current index at the point in the loop at which the index is called. The variable called ‘Draw’ is set equal to the value of the array draw at the array Draw at position i . The function uses the same algorithm to convert the value of Draw to a score as in the function FindInitialVal. Once the value of Draw is converted to a score, the variable ‘newVal’ is set equal to currentValue plus Draw and is returned to where it was called.

________________________________________________________________________________________________

The helper function drawTable outputs the graphical display using the Simple Game Engine and the layer matrices containing the current sprites. The function uses the backround matrix of sprites, bg and the top layer matrix containting sprites, table. The function creates a scene called card_scene and displays this scene using the Simple Game Engine function drawScene which uses card_scene, the bg matrix, and the table matrix.

FINAL FLOWCHART

Link to flowchart

FINAL PROGRAM WITH COMMENTS

 

Main Function: blackjack_start

Function: blackjack_game

Function: checkIfSame

Function: FindCardVal

Function: FindInitialVal

Function: FindNewVal

Function: drawTable

Sprite Sheet: retro_cards.png

BRIEF DISCUSSION

The design of the game began by creating Blackjack itself without any graphics. The initial decisions that needed to be made were how to go about drawing a random card from the deck and assigning it to the player. The original plan was to generate a random number between 1 and 52, assign a numerical ‘score’ value to each number, and determine the value of a player’s hand by adding their current cards together. However, team decided that it would be better to use an algorithm to convert the random number to a score and to use an array to store the values instead of assigning each to an individual variable. Eventually, after implementing various functions into the program designed to carry out these processes. At this point the program was successfully able to provide the player with two random cards and their respective values.

The next step was to determine how to proceed with asking the user if they want another card. This originally seemed simple, and a ‘while’ loop was implemented to prompt and add continue to increment the player’s hand and output “bust” and end the game if their value exceeded 21. However, in the game of Blackjack, the ace card can count for either 1 or 11. After discussion, the team determined that the value of this card at the current stage of the round was determined by whether or not 11 would put them over 21. A function to calculate the current value of the hand and an if statement to determine whether or not having the ace count for 11 were implemented to determine the value of the ace. Following these additions, the game was now able to continuously calculate the value of the user’s hand, prompt for more cards at the desire of the user, determine if the value of the player’s hand exceeds 21, and determine a value of the ace card.

Now, the program must be able to carry out the dealer’s actions. Most of the functions that were created to obtain and calculate the dealer’s hand could also be used for the dealer’s hand. Therefore, programming the dealer’s move was not extremely difficult. In this version of Blackjack, the dealer will draw 2 cards, and keep drawing until the value of their hand is at least 17. The functions to draw cards and to calculate the current value of the hand were implemented, thus completing the process of programming the dealer’s move. The user’s hand value and the dealer’s hand value were compared, thus completing the basic creation of the game.

The team then needed to implement graphics into the game. Based on the available sprite sheet of retro cards and the simple game engine, creating graphics that correspond to actions taking place in the game was not extremely difficult. Reading the available resources on how to use the simple game engine made it very straightforward. Each card on the sprite sheet corresponds to a particular card, so a function was created to make a “scene” of sprites corresponding to the correct card. The scene was updated and displayed to the screen after each card was drawn. However, during testing, when the graphic was displayed, it displayed an error message saying that the figure could not be displayed at 100% magnification and that it was going to be displayed at a lower magnification. So, a command to suppress this message was added into the code. Also, after the game was finished, it was noticed that every figure created by MATLAB was open on the screen and that the previous figures did not close when a new one opened. Several ‘close all’ commands were inserted into the code in order to resolve this. Additionally, the team noticed that the figures tended to appear in the middle of the screen, typically covering the command window. Therefore, a command to move the figures to the top part of the screen was added.

Lastly, the team realized that using a random number generator could result in the same card being drawn twice, so a function was made to check if the random number assigned to a card had already been generated and to generate another random number if this is the case. This addition was the final alteration to the basic game.

CONCLUSION AND RECOMMENDATIONS

The development of the Blackjack game progressed through several stages and faced a series of challenges during this process. It began with a simple version of the game and, through code improvement and rigorous testing, evolved into the current version that is being published. By researching the capabilities of the MATLAB language and implementing several helper functions, the group was able to make the program as efficient and user-friendly as possible. However, the program still has its flaws and has considerable room for improvement if it were to be produced on its full scale. If the team were to attempt to produce the game full scale, the program would be fitted with some sort of capability that would allow the player to bet virtual currency that would increase and decrease based on the result of the Blackjack game function. Additionally, the game could probably be written with even more functions in order to simplify the game and commit to making sure the entirety of the game conforms to appropriate programming practice.

REFERENCES

Music used in pitch video:

“Your Call” Kevin MacLeod (incompetech.com)
Licensed under Creative Commons: By Attribution 4.0 License
http://creativecommons.org/licenses/by/4.0/

 

MATLAB website used to research commands not taught in class:

https://www.mathworks.com/help/index.html