1. Code
  2. Corona SDK

Making a Blackjack Game in Corona - Implementing Gameplay


In the previous part of this series, we put our interface together for a Blackjack game and created the deck of cards. In this part of the tutorial, we'll add the necessary Blackjack game logic. Let's get started!

17. CreateDataFile()

We need a way to store the player's money between game sessions, and to do this we'll use a simple text file. Add the following code beneath the createDeck() function.

Here we are creating a file named "data.txt" and writing 500 to it. The player will start the game with $500.00. It's important to make sure you always call io.close() when you're finished with your operations.

You can learn more about creating this data file in the documentation on the Corona site.

18. ReadFile()

Now that we have a way to create our data file, we need a method to read its contents. Enter the following beneath the createDataFile() function you entered in the step above.

We open the file using the same method, then we use read("*n") to get the value out of the text file. The "*n" means read as a number.

19. SaveMoney()

To complete our file handling operations, we need a way to save. Enter the following beneath the code you entered in the step above.

Here we open the file for writing as denoted by the "w" in the open() method. We then write money to the file that was passed in as a parameter.

20. Setting the Initial Balance

We now need to create the initial balance when the game first starts. Add the following to the top of Setup().

If you open the Corona terminal and run the app twice you should see "DataFile Exists Already" printed out to the terminal. I left the print() messages in the file handling code so you could see the steps and any errors. If all is working well, feel free to remove them.

21. Showing Initial Balance

So now that we have the balance set, let's show it in our app. Change the following code within the setupTextFields() function.

Note that we are appending the balance onto "Your Bank:$" by calling the readMoney() function.

22. Betting

Now that we have the money in place we can add the code to our betHandler() function. We created this function in the previous part of the tutorial, so make sure you add to it instead of redefining it!

Here we first read how much money the player has. If they are trying to bet more than they have, the function simply returns. I've left the print() statements in the code to help with debugging. We set a dynamic key, betAmount, when we set up the money. If they are not trying to bet too much, we add the amount to the bet variable.

Next we create a tempImage, generate two random numbers, set the images x and y to the random numbers, and finally add the image to the coin container. You'll notice that we are using "money"..t.betAmount..".png" for the image URL. Our images for the money are named "money10.png", "money25.png" and "money50.png", so all we are doing here is concatenating them together to form the image string.

Lastly, we set the dealBtn to be visible, clear out the instructionsText and set the betText equal to the bet.

Now we need to add the addListeners() function to our Setup() code. Add the following code at the bottom.

If you test the app now, you should be able to bet some money.

23. Getting Hand Values

We need a way to get the hand value of the player's hand and the dealer's hand. Enter the following beneath the createDeck() function.

We set up a handValue variable and a hasAceInHand variable. Next, we loop through theHand which will either be the playerHand or the dealerHand. We create a variable cardsValue, casting it to a number by getting a substring of the current card. If cardsValue is greater than 10 we set it to 10. Jacks, Queens, and Kings are represented by 11, 12, and 13. We then add the value to handValue. If the card's value is equal to 1 then we know they have an ace in their hand. If they have an ace and their handValue is less than or equal to 11 we add 10 to it.

24. Deal()

We now have everything in place for a deal, so now we'll animate the cards to make the game more interesting. This function is quite large because it's where all of the game's logic takes place. We'll divide it into several steps. Add the following code within the deal() function you created in the first part of this series.

Here we set our money to be invisible, and our deal button to visible. Next we generate a randIndex from the deck table. We then generate a new image tempCard, and insert the tempCard into the allImages table. We set up three local variables, whichPosition, whichArray, and whichGroup. We check who is currently being dealt to initialize these variables as appropriate.

We then insert deck[randIndex] into whichArray, which is either the playerHand or the dealerHand table. Remember that our deck is composed of strings, so deck[randIndex] would be something like "h5","d10".

We set a local variable xPos equal to 20+#whichArray*35, which sets it to 20 plus the table's length + 35. The first time through the table length would be 1, so 20+1*35. The next time through the table length would be 2 so it would be 20+2*35. All of this is to allow us to space our cards evenly along the X axis.

We use coronas method to move the tempCard. When the card completes its transition, we check whether we are dealing to the dealer and if his hand length is 1. If so, we set firstDealerCard equal to deck[randIndex], and insert the card into the dealerGroup. We need a reference to the dealer's first card so that we can show it later.

If this was not the dealer's first card, then we remove the tempCard, generate a new image by using deck[randIndex], and insert it into the appropriate group (player or dealer). The reason we subtract 45 and 60 respectively is because Corona sets the reference point of images to the center by default, and our images are 90 x 120. Consequently, we take half of that.

Lastly we remove the card at position randIndex from the deck table and check whether dealerHand length is less than 2. If it is, we change dealTo to its opposite (player or dealer) and then deal again.

Finally, you can test the app, bet some money and get the first two cards dealt.

25. Deal() Continued...

Add the following code beneath where we called deal() in the step above.

Here we are checking if both dealerHand and playerHand's length are equal to 2. If they are, we'll check to see if either of their hands are equal to 21. If either of their hands are equal to 21, the game is over. We call doGameOver(true) which will award winnings and start a new game. The true parameter is true for blackjack. Otherwise, it will be false.

26. DoGameOver()

The doGameOver() function awards the winnings and starts a new game. We'll also be coding this function in several steps. For now we can use it to test the blackjack part. Enter the following code beneath the deal function.

Here we get the player's and the dealer's hand value. We get a reference to allCards[2], x, and y, which is the dealer's first card, and then we remove it from the display. We then generate a tempCard by using the firstDealerCard variable we setup earlier. Once again we subtract 45 and 60. We then insert this new card into the dealerGroup. When we do this, it's on top of the second card, so we send it to the back by calling toBack().

We check to see if hasBlackJack is true, and if it is we then check whether the player's hand is greater than the dealer's hand. If it is, we award some money, set the instructionsText accordingly, and change winner to "player".

27. Initializing the Money

We need to remember to initialize the money variable before we do anything with it. Add the following within the Setup() function.

28. Testing for Blackjack

We are at the point where we can test to see if the player or dealer has blackjack. We'll temporarily change some code to test, but we'll change it back. First, in the deal function, change the following.

Then within the doGameOver() function change the first two line like so.

Now go ahead and test the app. You should see that the player gets blackjack.

Now change the first two lines inside the doGameOver to the following

Now if you test, you should see the dealer has gotten blackjack.

29. Resetting From Testing

Now that we've tested, we should set our variables back. Inside the deal function change the following.

Then within the doGameOver() function, change the first two lines back to their previous state.

If you test once more, and neither you nor the dealer gets blackjack, the deal button should become invisible and the hit and stand buttons should become visible.

30. Hit()

We need to allow the player to hit or stand once the first two cards have been dealt. Enter the following within the hit() function you entered in the previous part of this series.

If you test now, you should be able to hit.

After some quality control testing, you might have noticed that the player can rapidly press the hit button over and over, dealing many cards at once. This isn't how the game should work. To fix it, we need to add a condition to make sure that they can only hit at the appropriate time. Add the following to the bottom of your variable declarations.

Now, change the hit() function to the following.

Within the deal() function, add the following line of code.

Now the player can only hit once, the card has finished being dealt.

31. Stand()

Next we need to allow the player to stand. Add the following within the stand() function you entered during the previous part of this series.

Here we indicate that the player is "holding." Set the standBtn and hitBtn to invisible. We check to see if the dealer's hand is less than 17, and if it is we change dealTo to the dealer and deal. If his hand is not less than 17, then we call doGameOver(). The dealer has to stand on 17 or greater.

If you test now, the player can get the hand they want and then press stand. There are a couple of problems, however. If the player busts, he can continue drawing cards and the dealing pauses at the dealer. We need the dealer to continue drawing cards until he gets over 17 or over, or until he busts. We will fix these issues when we finish off our deal() function in the next two steps.

32. Deal() Continued...

Add the following within the deal() function.

Here we check to see if the dealerHand's length is greater than or equal to 3 and that the dealer's hand is less than 17. If his hand is less than 17 he has to draw a card. Otherwise, we check to see if the player has yielded and if the dealer's hand is greater than or equal to 17. If so, the game is over. It's possible for dealer to have 17 or greater with the first two cards.

33. Finishing the Deal() Function

Enter the following code within the deal() function.

If the player hits and draws a card that puts him over 21, the game is over.

34. GameOver() Continued...

In this step we'll continue coding the gameOver() function. As of now, the deal function only determines who wins when either the player or dealer has blackjack. We need to handle all of the other possible outcomes. Enter the following within the doGameOver() function.

If you test the code now, you should be able to play a full game. The instruction text will show the outcome. Play a few rounds and make sure everything seems correct. If you really want to test the game throughly by entering different hand values, you can use the same technique we used earlier in this tutorial to test for blackjack.

35. GameOver() Continued...

Enter the following at the bottom of the doGameOver() function

After each round we should save the player's money. If their money is less than 10 we'll consider that bankrupt and reset their money to 500. As an exercise, see if you can get an alert to pop up saying something like "You've gone bankrupt, the dealer is awarding you $500.00."

36. Finishing GameOver()

After each round we move the coins to the winner and then start a new game. Enter the following beneath the code you entered in the step above.

Here we see who won the round, and then we animate the coins to them. When the animation completes we remove all the coins from the coinContainer, and set them to nil since we are done with them. Lastly, we call newGame() after two seconds, we also reset our coinContainer position.

37. NewGame()

Enter the following beneath the doGameOver() function.

Here we set the money to visible, remove the cards from both the player and the dealer groups, and reset all of our variables.


We've coded a fun and interesting blackjack game using the Corona SDK. Thanks for reading, I hope you found this tutorial helpful!

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.