Solution - Mega Challenge Casino

Tutorial Series: Free C# Fundamentals via ASP.NET Web Apps

Previous Article  |  Next Article


Get GitHub Code

This is the solution to the challenge titled ChallengeMegaCasino. Because this is a relatively large project, the best way to approach it is in pieces by breaking the task up into smaller tasks, then completing those. This solution will detail that process, and the process of making the pieces work together.

Step 1: Create the Default.aspx Page

The first step is to create the Default.aspx page that the user will be interacting with. Create a project called MegaChallengeCasino, then add a new Default.aspx page as we've done this far in the series. Per the instructions, we'll need images, labels, a TextBox and a Button on our page:


webform_layout


The programmatic IDs for the Server Controls are as follows:

  1. Image1
  2. Image2
  3. Image3
  4. betTextBox
  5. pullButton
  6. resultLabel
  7. moneyLabel

Note: Make sure the three Image Server Controls are sized to 150px x 150px.

Next, add a new folder to your project and call it Images:


2016-08-14 (1)


Drag and drop the images provided in CS-ASP_034-Mega-Challenge_Code into this folder so we can later programmatically reference them.

Step 2: Displaying Random Images

The first task to complete is to create a method to display a random image in each of the three Image Server Controls. To begin, double-click the pullButton to generate a pullButton_Click EventHandler. Often times, a helpful way to start is by creating an outline for your code written in comments. These comments will dictate in general language what your program will do and lays out a plan for you to follow:


Outline


To accomplish this task, we'll add the names of each of the images in the Images folder to an array of strings. When retrieving a random image for the server control, we will access a random item in that array (Such as "Clover") that we append .png to in order to reference it for the ImageUrl property.

While this task will ultimately be accomplished by a helper method, we will first write the logic inside the pullButton_Click, test the functionality, and then create the method. To begin, create an array of string called images and populate it with the names of the images in the Images folder:


ImagesArray


Next, we'll create a new Random class called random, and create a string called image that is set to a random index from the images array:


Random


Finally, set the Image1.ImageUrl to the following string concatenation that references an image in the Images folder:


Image1Url


Step 3: Creating a spinReel() Helper Method

The code we've written creates the functionality needed for retrieving a random image, but clutters up the pullButton_Click in the process. What we can do is pull most of the code out and create a helper method to do this task. Create a new private string method called spinReel(), then copy and paste this code from the pullButton_Click:


spinReel


Notice that we're getting an error from the spinReel() method, though. This is because we're expected to return a string from the method. To accomplish this, instead of setting a string equal to the random index of images, we'll return that random index:


spinReelFinal


Now notice that the error warning is gone, and the method is satisfied. We'll call the method back in the pullButton_Click, setting it equal to a string called image. Save and run the code to see the results:


ImageTest


Step 4: Display Three Random Images

While spinReel() successfully performs the function necessary to get a random image, it only does it for one image. Since we need three different values, we'll need to call spinReel() three times, then save those values to be assigned to our images. Our goal is to have as little clutter as possible in the pullButton_Click, so we'll delegate this responsibility to yet another helper method called pullLever().

This will be a void method, it won't return a value. Inside of its code block, we'll create a new string array called reels that will hold the three different values from spinreel():


pullLever


This will work because spinReel() will return a string, and the array is of type string, so we are simply populating it with three different string values.

Now that we've retrieved the values, we need to display them on-screen. We'll do this by creating another helper method called displayImages(). We'll have an input parameter of string[] reels so that we can access the indexes in that array. Then, copy and paste the Image1.ImageUrl code into the method. Duplicate it for each image, then set the three ImageUrl's to the following:


displayImages


Call displayImages() in the pullLever() method, passing in the reel array. Finally, call pullLever() from the pullButton_Click. Save the application and run to see the result:


sameImages


Tip:

Notice that every time you press the button, you'll end up with the same three images. The reason for this has to do with the Random class. There's a .txt file in the CS-ASP-034-Mega-Challenge_Code folder that explains in-depth why this happens. In summary, every time you create an instance of the Random class, it is created using the DateTime stamp, down to the millisecond. The result is that, in our case, when we create three different instances of Random and call random.Next(), the next index is always the same as the last. Why? Because we are not actually going to the next index, but simply calling the next index on another instance of the class, which will be the same index as the previous instance.

Thankfully, the solution to this issue isn't very difficult: Copy and paste the line of code that creates the instance of Random to the top of the Default.aspx.cs file so that the same instance is accessible throughout all of the method calls:


realRandom


Now, save and run your project to see the result:


WorkingReelSpin


Step 5: Evaluating the Spin

The next thing step that we need to take is finding what the multiplier for the player's bet is based upon what reel images are present. The multiplier can be summarized as follows:

  • Default - 0x
  • 1 Cherry - 2x
  • 2 Cherries - 3x
  • 3 Cherries - 4x
  • 3 7's - 100x
  • 1+ BAR - 0x

The code logic we'll write to incorporate this will be in a method that will be called from the pullLever() method. However, this will require pullLever() to know what amount was bet, and return an integer for the winnings. We'll modify the method to look like this:


pullLeverInputParameter


Notice that IntelliSense is great for telling us that we're expected to return an integer value from this method, denoted by the red squiggly line. But now we also need to create a bet integer to pass in to the method.

In the pullButton_Click, we'll initialize an int bet that's equal to 0. Then, directly underneath, we'll setup a conditional to ensure that the value passed in to the betTextBox can be converted to an int and, if so, set bet equal to that value. To do that, we'll use int.TryParse(), passing in the TextBox and the bet variable. Then we'll modify the pullLever() call, passing in the bet variable:


betVariable


Returning to the pullLever() method, we'll now create the multiplier variable, setting it equal to an evaluateSpin() method which we've yet to create:


multiplier


The evaluateSpin() method needs the reel variable as an input so that it knows what the result of the spin was. Since we're referencing a method that we'll need to create, press Ctrl+. on your keyboard and generate a method stub from it. This will create a method template for evaluateSpin(), including the int return expectancy and reel input:


evaluateSpin


Step 6: Determining the Multiplier

The first step we'll take in determining the multiplier is to set up different methods for each scenario. If there are any BARs, we will immediately return out of the method with a value of 0 for the multiplier. If it's a jackpot, we'll return with 100. If there's Cherries, we'll return either 2, 3 or 4. Since there is a limit on the number of lines of code per method, we'll need to create a new method for each evaluation, passing in the reel array for each:


evaluateSpinMethods


Here's how this works: we create a boolean type method for the first two checks that, if true, return their values. The check for cherries is more difficult, however, because there are multiple possible return values. Because of this, we'll need an output parameter for the multiplier, and then we'll return that multiplier to the caller. If none of these evaluate true, we'll return 0 to the caller, and the bet amount will be lost.

We now need to flesh out each of the three method calls that we made, generating a stub for each. Start with isBar() by pressing Ctrl+. while your cursor is on the line, then generating the method stub. Inside of that method stub, we'll create a conditional check to see if any of the reels are a BAR, and if so we'll return true. Otherwise, we'll return false, since there is no BAR:


isBarMethod


Next, generate a method stub for the isJackpot() method. Inside of that code block, we'll create a conditional statement for the antithesis of isBar(), checking instead if all reels are equal to "Seven":


isJackpotMethod


The last condition we need to check is if there are cherries in the reel spin. Create a new private int method called determineCherryCount(), passing in reel. Inside its code block, write the following code:


determineCherryCount


This code block evaluates how many reels contain the string "Cherry" and sets the cherryCount variable accordingly.

Next, create another method that returns an int and call it determineMultiplier(), passing in yet again the reel. Inside, write the following code to set the multiplier based on the cherryCount:


determineMultiplier


This will take evaluate cherryCount, as passed in by determineCherryCount(), and return the appropriate value back to the caller, whether 0, 2, 3 or 4. Go back to the isWinner() method, and set the multiplier variable equal to determineMultiplier(), passing in reel. Underneath that, create a conditional statement to check if the multiplier is greater than 0. If it is, isWinner() will return true. Otherwise, it will return false:


isWinner


Finally, return back to the evaluateSpin() method and tidy it up so it looks like the following, keeping within the six-line limitation:


evaluateSpinFinal


Step 7: Calculate and Display Earnings

Now that we've determined the multiplier, as well as the bet, we can calculate the player's total earnings. Return to the pullLever() method, and underneath the call to evaluateSpin(), write the following code:


returnBet


This will satisfy the method's return, and give us the total amount that the player either won or lost. We'll use this value to display back to the user in the resultLabel.

Return to the pullButton_Click. What we need to do is use the bet returned from pullLever() and assign it to an integer variable called winnings. Then, call a new method named displayResult(), passing in the bet and winnings variables:


pullLeverResult


Use that call to displayResult() to create a method stub. Inside that method, we'll need to display one of two messages: either tell the user they won, and how much, or tell them they lost the value they bet. To do that, create an if statement to check if the winnings are greater than 0, and inside, write the following code to set the resultLabel:


winningsResultLabel


Underneath, write an else statement to display the other message. Note the use of ':C' within the brackets for currency formatting:


youLostMessage


Now, save and run your application to see the result:


youWonTest


youLostTest


Step 8: Setting the Page's Initial Reel Values

One of the requirements of this challenge is to display, at runtime, the player's current money, and show three reel values before the player pulls the lever. To do this, we'll need to go into the Page_Load event, and write a conditional statement to ensure that the page is not posting back. Inside, we'll create another string array called reels, and set it equal to spinReel():


pageLoad


Next, call the displayImages() method, passing in the array of reels we just created. Running the program will show the initial state of the application:


InitialReels


Step 9: Setting and Saving the Player's Money

What we need to do now is initialize the player's money value, which is given to us as $100. Since we know that the value of the player's money will need to be saved between posts to the server, we'll initialize the value using the ViewState. Within the same conditional code block for !Page.IsPostBack(), write the following code for the value and key:


playersMoney


When the application first loads, the player needs to be able to see their initial money value. This means that a helper method is needed in order to display the money value to the user. Create a method called displayPlayersMoney(), and inside set the moneyLabel's text to the following:


displayPlayersMoney


This method accesses the current money value of the player from ViewState and displays it in the challenge's specified format. This functionality is reusable for when we update the player's total money.

In order to update the amount of money available to the player, create a new method within pullButton_Click called adjustPlayersMoney(), passing in the bet and the winnings and generate a method stub for it:


adjustPlayersMoneyInitial


Inside the code block, create an integer called playersMoney, setting it equal to the ViewState's PlayersMoney value. Since this will return an object, it needs to be cast to an integer:


playersMoneyInt


Now that we've retrieved the player's money prior to the bet, we can calculate how much money the player has after they've played the game. To do this, we'll subtract the bet from the playersMoney variable, add the winnings and update the ViewState:


playersMoneyCalculat ion


Now, in the pullButton_Click, call the displayPlayersMoney() method underneath the call to adjustPlayersMoney. Save and run the application to see the result.

  • If the player won:

FinalApplicationTest


  • If the player lost:

FinalApplicationTestLose


Conclusion:

This completes the solution to MegaChallengeCasino. The purpose of this challenge was to test your knowledge of creating helper methods and delegating tasks to several methods in order to keep the separation of concerns principle in place. It comes down to a lot of thought and planning, but once you have a plan in place, the execution can prove to be more straightforward than it appears at first.

Hopefully you were able to solve most, if not all, of this challenge on your own. Again, if you met the requirements for the challenge but had a different implementation, that's fine! There are many different ways to solve this challenge, and you're encouraged to try several different methods. The more you test and practice, the more you'll learn and you'll become better at programming. Keep up the good work!


Related Articles in this Tutorial:

Lesson 1 - Series Introduction

Lesson 2 - Installing Visual Studio 2015

Lesson 3 - Building Your First Web App

Lesson 4 - Understanding What You Just Did

Lesson 5 - Working with Projects in Visual Studio

Lesson 6 - Simple Web Page Formatting in Visual Studio

Challenge 1

Solution 1

Lesson 7 - Variables and Data Types

Lesson 8 - Data Type Conversion

Lesson 9 - Arithmetic Operators

Lesson 10 - C# Syntax Basics

Challenge 2 - ChallengeSimpleCalculator

Solution - ChallengeSimpleCalculator

Lesson 11 - Conditional If Statements

Lesson 12 - The Conditional Ternary Operator

Challenge 3 - ChallengeConditionalRadioButton

Solution - Challenge Conditional RadioButton

Lesson 13 - Comparison and Logical Operators

Lesson 13 Challenge - First Papa Bob's Website

Solution - Challenge First Papa Bob's Website

Lesson 14 - Working with Dates and Times

Lesson 15 - Working With Spans of Time

Lesson 16 - Working with the Calendar Server Control

Challenge 4 - Challenge Days Between Dates

Solution - Challenge Days Between Dates

Lesson 17 - Page_Load and Page.IsPostBack

Lesson 18 - Setting a Break Point and Debugging

Lesson 19 - Formatting Strings

Challenge 5 - Challenge Epic Spies Assignment

Solution - Challenge Epic Spies Assignment

Lesson 20 - Maintaining State with ViewState

Lesson 21 - Storing Values in Arrays

Lesson 22 - Understanding Multidimensional Arrays

Lesson 23 - Changing the Length of an Array

Challenge 6 - Challenge Epic Spies Asset Tracker

Solution - Challenge Epic Spies Asset Tracker

Lesson 24 - Understanding Variable Scope

Lesson 25 - Code Blocks and Nested If Statements

Lesson 26 - Looping with the For Iteration Statement

Challenge 7 - Challenge For Xmen Battle Count

Solution - Challenge For Xmen Battle Count

Lesson 27 - Looping with the while() & do...while() Iteration Statements

Lesson 28 - Creating and Calling Simple Helper Methods

Lesson 29 - Creating Methods with Input Parameters

Lesson 30 - Returning Values from Methods

Lesson 31 - Creating Overloaded Methods

Lesson 32 - Creating Optional Parameters

Lesson 33 - Creating Names Parameters

Lesson 34 - Creating Methods with Output Parameters

Challenge 8 - Challenge Postal Calculator Helper Methods

Solution - Challenge Postal Calculator Helper Methods

Mega Challenge Casino

Solution - Mega Challenge Casino

Lesson 35 - Manipulating Strings

Challenge 9 - Phun With Strings

Solution - Challenge Phun With Strings

Lesson 36 - Introduction to Classes and Objects

Challenge - Hero Monster Classes Part 1

Solution - Hero Monster Classes Part 1

Challenge - Hero Monster Classes Part 2

Solution - Challenge Hero Monster Classes Part 2

Lesson 37 - Creating Class Files Creating Cohesive Classes and Code Navigation

Lesson 38 - Understanding Object References and Object Lifetime

Lesson 39 - Understanding the .NET Framework and Compilation

Lesson 40 - Namespaces and Using Directives

Lesson 41 - Creating Class Libraries and Adding References to Assemblies

Lesson 42 - Accessibility Modifiers, Fields and Properties

Lesson 43 - Creating Constructor Methods

Lesson 44 - Naming Conventions for Identifiers

Lesson 45 - Static vs Instance Members

Challenge 10 - Challenge Simple Darts

Solution - Challenge Simple Darts

Lesson 46 - Working with the List Collection

Lesson 47 - Object Initializers

Lesson 48 - Collection Initializers

Lesson 49 - Working with the Dictionary Collection

Lesson 50 - Looping with the foreach Iteration Statement

Lesson 51 - Implicitly-Typed Variables with the var Keyword

Challenge 11 - Challenge Student Courses

Solution - Challenge Student Courses

Mega Challenge War

Solution - Mega Challenge War

Lesson 52 - Creating GUIDs

Lesson 53 - Working with Enumerations

Lesson 54 - Understanding the switch() Statement

Lesson 55 - First Pass at the Separation of Concerns Principle

Lesson 56 - Understanding Exception Handling

Lesson 57 - Understanding Global Exception Handling

Lesson 58 - Understanding Custom Exceptions

Lesson 59 - Creating a Database in Visual Studio

Lesson 60 - Creating an Entity Data Model

Lesson 61 - Displaying the DbSet Result in an ASP.NET GridView

Lesson 62 - Implementing a Button Command in a GridView

Lesson 63 - Using a Tools-Centric Approach to Building a Database Application

Lesson 64 - Using a Maintenance-Driven Approach to Building a Database Application

Lesson 65 - Creating a New Instance of an Entity and Persisting it to the Database

Lesson 66 - Package Management with NuGet

Lesson 67 - NuGet No-Commit Workflow

Lesson 68 - Introduction the Twitter Bootstrap CSS Framework

Lesson 69 - Mapping Enum Types to Entity Properties in the Framework Designer

Lesson 70 - Deploying the App to Microsoft Azure Web Services Web Apps

Papa Bob's Mega Challenge

Papa Bob's Mega Solution Part 1 - Setting up the Solution

Papa Bob's Mega Solution Part 2 - Adding an Order to the Database

Papa Bob's Mega Solution Part 3 - Passing an Order from the Presentation Layer

Papa Bob's Mega Solution Part 4 - Creating the Order Form

Papa Bob's Mega Solution Part 5 - Adding Enums

Papa Bob's Mega Solution Part 6 - Creating an Order with Validation

Papa Bob's Mega Solution Part 7 - Calculating the Order Price

Papa Bob's Mega Solution Part 8 - Displaying the Price to the User

Papa Bob's Mega Solution Part 9 - Creating the Order Management Page


Comments

Please login or register to add a comment