BACK TO THE ROCK, PAPER AND SCISSORS GAME


It's time to turn your attention back to the development of this chapter's game project, the Rock, Paper and Scissors game. You will create this game by following the five basic development steps that you've used to create all the previous chapter projects.

Designing the Game

The Rock, Paper and Scissors game is played on a single window and is made up of one form and the 22 controls listed in Table 9.1.

Table 9.1: Form Controls for the Rock, Paper and Scissors Game

Control Type

Control Name

Description

PictureBox

pcbLeft

Displays an image showing the computer's selection

PictureBox

pcbRight

Displays an image showing the player's selection

Label

lblComputer

Identifies the PictureBox control where the computer's selection is displayed

Label

lblPlayer

Identifies the PictureBox control where the player's selection is displayed

Label

lblCountDown

Identifies the function of the ProgressBar control

ProgressBar

pgbCountDown

Displays a graphical 1.5-second countdown

Button

btnPlay

Starts gameplay by enabling the Timer control

Button

btnRock

Allows the player to select Rock

Button

btnPaper

Allows the player to select Paper

Button

btnScissors

Allows the player to select Scissors

GroupBox

grpStatus

Contains Label and TextBox controls that identify and display game statistics

Label

lblWins

Identifies the TextBox control that displays the number of games won

Label

lblLosses

Identifies the TextBox control that displays the number of games lost

Label

lblTies

Identifies the TextBox control that displays the number of games tied

TextBox

txtWins

Displays the number of games the player has won

TextBox

txtLosses

Displays the number of games the player has lost

TextBox

txtTies

Displays the number of games the player has tied

Label

lblResults

Identifies the TextBox control where the results of each game are displayed

TextBox

lblOutput

Displays a test string detailing the results of each game

ToolTip

tltControl

Allows you to assign ToolTips to individual controls

Timer

tmrControl

Controls the 1.5-second countdown sequence and the half-second windows in which the player gets to make a selection

ImageList

imlHands

Stores the bitmap images that are displayed in the PictureBox controls during gameplay

Step 1: Creating a New Visual C++ Project

The first step in creating the Rock, Paper and Scissors game is to open Visual C++ and create a new project, as outlined here:

  1. If you have not already done so, start Visual C++ 2005 Express and then click on File, New Project. The New Project dialog box appears.

  2. Select Windows Application template.

  3. Type Rock Paper and Scissors as the name of your new application in the Name field located at the bottom of the New Project window. You need to type the name of the project without a comma, or Visual C++ might not recognize some of the project's file names during compiling.

  4. Click on OK to close the New Project dialog box.

Visual C++ now creates a new project and displays a new form upon which you will design the game's user interface.

Step 2: Creating the User Interface

Let's begin the development of the Rock, Paper and Scissors game by laying out and resizing all the controls that you need to set up the game's user interface. As you go about configuring the game's user interface, refer to Figure 9.6 so that you know where to place each control and when and how to resize it.

  1. Begin by clicking on the form and setting its Size property to 490, 460.

  2. Add two PictureBox controls, one in the upper-left corner of the form and the other in the upper-right corner. Set the Size property for both PictureBox controls to 150, 150.

  3. Next, add a pair of Label controls to the form. Place the first one under the first PictureBox control and the second one under the second PictureBox control.

  4. Add another Label control about an inch below the left side of the first PictureBox control, and then add a ProgressBar control beneath it, setting its Size property to 250, 40.

  5. Add four Button controls to the form.

  6. Add a GroupBox control to the lower-left corner of the form and set its Size property to 190, 100.

  7. Add three Label controls and three TextBox controls inside the GroupBox control.

  8. Add another Label control just to the right of the GroupBox control and then add a TextBox control beneath it. Set the Multiline property for the TextBox control to true and the Size property to 260, 80.

  9. Finally, add ToolTip, Timer, and ImageList controls.

image from book
Figure 9.6: Completing the interface design for the Rock, Paper and Scissors game.

At this point, you have added all the controls you will need to develop the Rock, Paper and Scissors game. In addition, you have completed the overall layout of the game's user interface and are ready to start making property modifications to the game's form and controls.

Step 3: Customizing Form and Control Properties

Okay, let's get to work on making the required changes to the game's form and control properties, as listed in Table 9.2.

Table 9.2: Property Changes for Form1

Property

Value

BackColor

LightYellow

FormBorderStyle

Fixed3D

MaximizeBox

False

MinimizeBox

False

Size

490, 460

StartPosition

CenterScreen

Text

Rock, Paper and Scissors

Make the property changes shown in Table 9.3 to the PictureBox controls.

Table 9.3: Property Changes for PictureBox Controls

Control

Property

Value

PictureBox1

Name

pcbleft

 

BorderStyle

Fixed3D

 

Size

150, 150

 

SizeMode

StretchImage

PictureBox2

Name

pcbRight

 

BorderStyle

Fixed3D

 

Size

150, 150

 

SizeMode

StretchImage

Make the property changes shown in Table 9.4 to the Label controls.

Table 9.4: Property Changes for Label Controls

Control

Property

Value

Label 1

Name

lblComputer

 

Font.Bold

True

 

Text

Computer's Pick

Label 2

Name

lblPlayer

 

Font.Bold

True

 

Text

Player's Pick

Label 3

Name

lblCountDown

 

Font.Bold

True

 

Text

Countdown

Label 4

Name

lblWins

 

Font.Bold

True

 

Text

Wins:

Label 5

Name

lblLosses

 

Font.Bold

True

 

Text

Losses:

Label 6

Name

lblTies

 

Font.Bold

True

 

Text

Ties:

Label 7

Name

lblResults

 

Font.Bold

True

 

Text

Game Results

Next, change the name of the ProgressBar control to pgbCountDown and set its Size property to 250, 40. Then make the property changes shown in Table 9.5 to the four Button controls.

Table 9.5: Property Changes for Button Controls

Control

Property

Value

Button1

Name

btnPlay

 

BackColor

ButtonFace

 

Font.Bold

True

 

Text

Play

 

ToolTip

Begin 1.5 second countdown

Button2

Name

btnRock

 

BackColor

ButtonFace

 

Enabled

False

 

Font.Bold

True

 

Text

Rock

 

ToolTip

Select Rock

Button3

Name

btnPaper

 

BackColor

ButtonFace

 

Enabled

False

 

Font.Bold

True

 

Text

Paper

 

ToolTip

Select Paper

Button4

Name

btnScissors

 

BackColor

ButtonFace

 

Enabled

False

 

Font.Bold

True

 

Text

Scissors

 

ToolTip

Select Scissors

Trick 

The ProgressBar control displays the status of a process. After you've added this control to a form, you can update its appearance by settings its Value property to 0 to represent a process that has not started. You can then set the Value property anywhere between 0 and 100 to represent the current status of a process. Finally, you can set the Value property to 100 to represent a process that has completed.

Make the property changes shown in Table 9.6 to the four TextBox controls.

Table 9.6: Property Changes for TextBox Controls

Control

Property

Value

TextBox 1

Name

txtWins

 

Font.Bold

True

 

ReadOnly

True

 

TextAlign

Right

TextBox2

Name

txtLosses

 

Font.Bold

True

 

ReadOnly

True

 

TextAlign

Right

TextBox3

Name

txtTies

 

Font.Bold

True

 

ReadOnly

True

 

TextAlign

Right

TextBox4

Name

txtoutput

 

Font.Bold

True

 

ReadOnly

True

 

Size

260, 80

Next, change the name of the ToolTip control to tltControl. Then make the property changes shown in Table 9.7 to the Timer control.

Table 9.7: Property Changes for Timer Control

Control

Property

Value

Timer1

Name

tmrControl

 

Interval

500

Finally, change the name of the Name property for the ImageList control to imlHands and add the following bitmap images to its Images property (col1ection) as shown in Table 9.8. You'll find copies of the bitmap images required to complete this project, along with the source code, on this book's companion Web site.

Table 9.8: Bitmap Images to Add to the ImageList Control's Images Collection

Property

File

Index No.

Name

Left-Paper.bmp

0

Name

Right-Paper.bmp

1

Name

Left-Rock.bmp

2

Name

Right-Rock.bmp

3

Name

Left-Scissors.bmp

4

Name

Right-Scissors.bmp

5

Name

Blank.bmp

6

That's it. The user interface for the Rock, Paper and Scissors game is now complete. Let's move on to the next step and begin adding program code.

Step 4: Adding a Little Programming Logic

To put together the code for the Rock, Paper and Scissors game, start by double-clicking on the game's form. This activates the Code Editor. In response, Visual C++ automatically defines a new class for you called frmMain (or whatever name you have assigned to Form1). This derived class inherits properties, methods, and events that are associated with the System.Windows.Forms base class.

Your class requires the following member variables:

 private:   /// <summary>   /// Required designer variable.   /// </summary>   Int32 intCounter;   Int32 intWins;   Int32 intLosses;   Int32 intTies;   enum class GameChoice : Int16 {     CHOICEROCK, CHOICEPAPER, CHOICESCISSORS   };   //Handle for random number generator   Random^ randNumGen; 

The first variable, intCounter, tracks the timer and implements the 1.5-second countdown. The next three variables—intWIns, intLosses, and intTies—keep track of whether the computer or the player is winning. Notice also the enum class GameChoice, which defines three possible game choices. GameChoice derives from the Int16 class and exists only to create meaningful state information for some functions to operate on. This section also includes a handle to a random number generator, randNumGen, which gives the computer the illusion of making a choice.

The Rock, Paper and Scissors game needs to execute a few tasks when it first loads. It must initialize its member variables. Then it needs to load a blank bitmap for each of the two PictureBox controls. Following that, the game's text boxes are initialized, and the random number generator is seeded with the current time:

 private: System::Void Form1_Load(System::Object^  sender, \ System::EventArgs^  e) {         intCounter = 0;         intWins = 0;         intLosses = 0;         intTies = 0;         //Load blank bitmap in picture boxes         pcbLeft->Image = imlHands->Images[6];         pcbRight->Image = imlHands->Images[6];         //Set game statistics         txtWins->Text = intWins.ToString();         txtLosses->Text = intLosses.ToString();         txtTies->Text = intTies.ToString();         //Seed random number generator with current time         DateTime moment = DateTime::Now;         randNumGen = gcnew Random( moment.Millisecond );  } 

The game starts when the player clicks the Play button. This begins the game's 1.5-second countdown by setting the Value property of the ProgressBar control to 0 and enabling the Timer control. Any leftover text in the text box is cleared, and the two picture boxes are again loaded with black images to clear out the pictures from the previous game:

 private: System::Void btnPlay_Click(System::Object^  sender, \ System::EventArgs^  e) {         //Set ProgressBar to show 0 percent progress         pgbCountdown->value = 0;         //Start countdown by enabling the Timer         tmrControl->Enabled = true;         //Clear out any test stored in the text box         txtOutput->Text = "";         //Load blank bitmap in picture boxes         pcbLeft->Image = imlHands->Images[6];         pcbRight->Image = imlHands->Images[6]; } 

The Timer control handles timing for the game. Because its Interval property is set to 500, the code in this function executes every 0.5 seconds. Each time it does, the counter is incremented by 1. When the counter exceeds 4, the game is over.

The Timer control also updates the progress bar each time it is called.

The tmrControl_Tick function, shown next, uses a switch block to control what happens at certain intervals. When the first half-second has passed, the value of intCounter is 1, and the ProgressBar control's Value property is set to 33 to give the player a visual indicator that a third of the countdown has elapsed. After the passage of a full second, the second case statement is triggered, and the ProgressBar control's Value property is updated to show that two-thirds of the countdown has elapsed:

 private: System::Void tmrControl_Tick(System::Object^ \ sender, System::EventArgs^  e) {         intCounter += 1;  //Increment counter         //Set progress bar based on counter         switch( intCounter )         {           case 1 : //At .5 seconds             //Set progress bar to show 33%             pgbCountdown->value = 33;             break;           case 2 : //At 1 second             //Set progress bar to show 66%             pgbCountdown->Value = 66;             break;           case 3 : //At 1.5 seconds             //Set progress bar to show 100%             pgbCountdown->Value = 100;             //Enable the 3 game choice buttons             btnRock->Enabled = true;             btnPaper->Enabled = true;             btnScissors->Enabled = true;             break;           case 4 : //At 2 seconds             intCounter = 0;  //Reset counter             //Disable the Timer control             tmrControl->Enabled = false;             //Disable the 3 game choice buttons             btnRock->Enabled = false;             btnPaper->Enabled = false;             btnScissors->Enabled = false;             //Set ProgressBar to show 0%             pgbCountdown->Value = 0;             break;         } } 

At 1.5 seconds, the ProgressBar control's Value property is updated to indicate that the countdown is complete. When this occurs, the buttons representing the rock, paper, and scissors options are enabled, and the player has a half-second to decide which button to click. But should the half-second interval elapse, execution reaches the final case statement. This causes the game's buttons to be disabled, the progress bar to be reset, and the timer to be disabled.

The next listing shows the code for the Rock Button control. When clicked, the right picture box, pcbRight, is loaded with the appropriate image. An instance of the GameChoice enum class is created and initialized with the player's choice. Notice that instead of a number, which might be hard to understand, or a string, which would be wasteful, the use of an enum makes the code clearer. It is easy to understand that the player's choice is rock because of how the assignment to GameChoice::CHOICEROCK reads.

After the player's choice is instantiated, another GameChoice object is created to represent the computer's choice. This is assigned the results of the GetComputerChoice function. When the computer's choice is known, both are used as parameters in the CheckGameResults function:

 private: System::Void btnRock_Click(System::Object^  sender,\ System::EventArgs^  e) {           //Load rock picture into right picture box           pcbRight->Image = imlHands->Images[3];           //Set the game choices for both players           GameChoice gmcPlayerPick = GameChoice::CHOICEROCK;           //Get computer choice           GameChoice gmcComputerPick;           gmcComputerPick = GetComputerChoice();           //Run function that determines who has won the game           CheckGameResults(gmcPlayerPick, gmcComputerPick); } 

The click event function for the Button control representing the paper option is shown next. The code is nearly identical, except all references reflect the player's choice of paper as his move instead of rock:

 private: System::Void btnPaper_Click(System::Object^  sender,\ System::EventArgs^  e) {           //Load paper picture into right picture box           pcbRight->Image = imlHands->Images[1];           //Set the game choices for both players           GameChoice gmcPlayerPick = GameChoice::CHOICEPAPER;           //Get computer choice           GameChoice gmcComputerPick;           gmcComputerPick = GetComputerChoice();           //Run function that determines who has won the game           CheckGameResults(gmcPlayerPick, gmcComputerPick);    } 

The code for the Button control representing the scissors choice is shown next. Again, it varies only slightly from the two previous functions:

 private: System::Void btnScissors_Click(System::Object^  sender,\ System::EventArgs^  e) {           //Load scissors picture into right picture box           pcbRight->Image = imlHands->Images[5];           //Set the game choices for both players           GameChoice gmcPlayerPick = GameChoice::CHOICESCISSORS;           //Get computer choice           GameChoice gmcComputerPick;           gmcComputerPick = GetComputerChoice();           //Run function that determines who has won the game           CheckGameResults(gmcPlayerPick, gmcComputerPick); } 

The GetComputerTurn() function, shown next, is a custom-developed function that you must type from scratch. Within the function, the randNumGen object serves as an argument to a switch statement. The Next() method of randNumGen generates a number between (but not including) the upper and lower bounds. If the number falls between 1 and 2, the value that the method returns matches one of the two case labels. Within each label, the appropriate graphic is set for the computer's choice, and the correct enumerated value is returned. If neither is met, the function assumes that the only logical choice is paper and performs the appropriate steps:

 private: GameChoice GetComputerChoice(System::Void) {           //Get the computer's random choice           switch( randNumGen->Next(0, 4) )           {             case 1 : //Computer chooses rock               //Load picture of rock into left box               pcbLeft->Image = imlHands->Images[2];               //Return computer's choice               return GameChoice::CHOICEROCK;               break;             case 2 : //Computer chooses scissors               //Load picture of scissors into left box               pcbLeft->Image = imlHands->Images[4];               //Return computer's choice               return GameChoice::CHOICESCISSORS;               break;           }           //Only possible remaining choice is paper           //Load picture of paper into left box           pcbLeft->Image = imlHands->Images[0];           //Return computer's choice           return GameChoice::CHOICEPAPER;   } 

The logic within the Check Game Results () function is responsible for arbitrating between the computer and player moves. Each player's choice is used as the basis of comparison and causes execution to seek the nearest matching case label. Within each case block, three if statements determine how the player's choice stacks up against the computer's choice. The result is assigned to the Text property of txtOutput, the appropriate variable tracking the player's score is updated, and the results are translated to a string so that they can be stored in the correct corresponding text box:

 private: System::Void CheckGameResults(GameChoice gmcPlayer,\                                     GameChoice gmcComputer ) {           //Check winner by comparing moves           switch( gmcPlayer )           {             case GameChoice::CHOICEROCK :               if( gmcComputer == GameChoice::CHOICEROCK )               {                 //Display results                 txtOutput->Text = \                 "Rock versus Rock is a Tie!";                 intTies++;                 txtTies->Text = intTies.ToString();               }               if( gmcComputer == GameChoice::CHOICEPAPER )               {                 //Display results                 txtOutput->Text = \                 "Paper covers Rock. You Lose!";                 intLosses++;                 txtLosses->Text = intLosses.ToString();               }               if( gmcComputer == GameChoice::CHOICESCISSORS )               {                 //Display results                 txtOutput->Text = \                 "Rock crushes Scissors. You Win!";                 intWins++;                 txtWins->Text = intLosses.ToString();               }               break;             case GameChoice::CHOICEPAPER :               if( gmcComputer == GameChoice::CHOICEROCK )               {                 //Display results                 txtOutput->Text = \                 "Paper covers Rock. You Win!";                 intWins++;                 txtWins->Text = intWins.ToString();               }               if( gmcComputer == GameChoice::CHOICEPAPER )               {                 //Display results                 txtOutput->Text = \                 "Paper versus Paper is a Tie!";                 intTies++;                 txtTies->Text = intTies.ToString();               }               if( gmcComputer == GameChoice::CHOICESCISSORS )               {                 //Display results                 txtOutput->Text = \                 "Scissors cuts Paper. You Lose!";                 intLosses++;                 txtLosses->Text = intLosses.ToString();               }               break;             case GameChoice::CHOICESCISSORS :               if( gmcComputer == GameChoice::CHOICEROCK )               {                 //Display results                 txtOutput->Text = \                 "Rock breaks Scissors. You Lose!";                 intLosses++;                 txtLosses->Text = intLosses.ToString();               }               if( gmcComputer == GameChoice::CHOICEPAPER )               {                 //Display results                 txtOutput->Text = \                 "Scissors cuts Paper. You Win!";                 intWins++;                 txtWins->Text = intWins.ToString();               }               if( gmcComputer == GameChoice::CHOICESCISSORS )               {                 //Display results                 txtOutput->Text = \                 "Scissors versus Scissors is a Tie!";                 intTies++;                 txtTies->Text = intTies.ToString();               }               break;           }    } 

Step 5: Testing the Execution of the Rock, Paper and Scissors Game

The Rock, Paper and Scissors game is ready to run. Start the game by pressing F5 and test the code to make certain it works as it should. If you run into problems, be sure to double-check your typing.




Microsoft Visual C++ 2005 Express Edition Programming for the Absolute Beginner 2006
Microsoft Visual C++ 2005 Express Edition Programming for the Absolute Beginner 2006
ISBN: 735615381
EAN: N/A
Year: 2005
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net