Conditional Execution Lab: If/Else Selection Control Structures Game Version: SpaceSmasher 1.0 Authors: Kelvin Sung, Mike Panitz, Rob Nash, and ET. AL. Summary The focus of this lab is to explore conditional execution (also called branching) in our C# programs. We’ll define a mechanism used for “asking a question” and “making a decision” in a program by using an “if” statement (or more formally, a selection control structure). Lab Outcomes We seek to understand the logic and syntax for the following set of Selection Control Structures in the context of simple, standalone C# programs as well as in the context of a real-world, industry-grade software simulation. The Single If if( <someBooleanExpression> ) {…} A Set of Sequential If Statements if( <someBooleanExpression> ) {…} if( <someBooleanExpression> ) {…} if( <someBooleanExpression> ) {…} Compound Boolean Conditions (using && and ||) if( <booleanExpressionA> && <booleanExpressionB> ) {..} if( <booleanExpressionA> || <booleanExpressionB> ) {..} The Single If/Else Structure (With Default Else) if( <someBooleanExpressionA> ) { //codeBodyA } else { //codeBodyB } Chained If/ElseIF Statements Without Default Else if( <queryA> ) { //codeBodyA } else if( <queryB> { //codeBodyB } Chained If/ElseIF Statements With Default Else if( <queryA> ) { //codeBodyA } else if( <queryB> { //codeBodyB } else { //defaultCodeBodyC } Nested If Statements if( <queryA> ) { if( <queryB> ) { } } Transforming Nested Ifs using && Nested If-Elses if( <queryA> ) { if( <queryB> ) { } else { } } else if(<queryC> ) { if( <queryD> ) { } else { } } Warmup With Single If Statements To get started, using a compiler OR pen and paper, write out the following bullet points as if statements. If the word “or” is in the sentence, use C#’s logical OR operator “||”. 1. A number is negative 2. A number is positive or zero 3. A number is even or odd 4. A grade is above a 90 5. The temperature is higher than 78 degrees 6. The class average was below a 65 7. The answer was true 8. The answer was not true Conditionals Lab Summary In this lab, we’ll look at examples of if statements that are used to add features and functionality (or just fun) to an existing software simulation. Examples will be presented for each type of IF structure you are asked to build; experiment by commenting out these examples to see what each IF actually does in our game. Introduction to IF Statements in SpaceSmasher In this section, we’ll continue to explore our understanding of conditional execution by looking at examples from a real-world simulation. We’ll see how including conditional execution in such a simulation can greatly expand the number of paths throughout the program, resulting in a broader and deeper piece of software. While we’ll enjoy the increased depth, complexity, and entertainment value of the simulation that uses conditional execution, we’ll see that we’ve also increased the number of paths through our program exponentially. Branching introduces mutually exclusive pathways into our software, and if errors can exist in any of these paths, it becomes a nontrivial exercise to test each and every pathway through this code. This tradeoff in complexity is well known and readily accepted when we consider the space of problems that could only be addressed by such decisionmaking structures. In fact, if your programming language does not offer such a construct, then it can’t be considered a fully-fledged (or Turing Complete) programming language. You can observe the increase in expressiveness in your software by analog: if we didn’t have the “if” structure in English/Greek/Romance languages, then we would not have been able to build this sentence, the previous sentence, and the next sentence. If you haven’t already completed the Setting Up SpaceSmasher exercises, you’ll need to do this before moving on to the next section. Also if you’re unfamiliar with how such block breaking games are played, be sure watch the introductory online video and be sure to compile, run and play the complete game found in the starter project. A Quick Warning About The Starter File: You’ll notice that this Visual Studio Solution actually contains several sub-projects. You’ll need to work with the one named “SpaceSmasherCSharp” – it’s the middle one in the picture below: (Remember you can open this window by opening the VIEW menu, then picking “Solution Explorer) SpaceSmasherCSharp must be in bold face (like it is in the above picture). If it’s not bold then trying to run the program will cause an error to occur, which will probably say something to the effect of “A project with output type of Class Library cannot be started directly.”. You can fix this by right-clicking on SpaceSmasherCSharp and selecting “Set As StartUp Project”. All the files that we’ll talk about in this document are inside that project, so open the project up by clicking on that triangle to the left of the name ( ) Single If Statement Flowchart Getting the code ready for this lab Open up the Program.cs file, and verify that the Main function looks like this: static void Main() { using (var game = new UserCodeIf()) game.Run(); } All the code that we discuss is located in the UserCodeIf.cs file, so it would be a good idea to open that file now. Single If Statements In SpaceSmasher Compile the SpaceSmasher project for this lab and run the software. Notice that, while this simulation accomplishes a great deal already (sprites, animation, sound, etc.), there are still gaps in the desired functionality of such a game. We’ll use our knowledge of single if statements to improve this software’s interactivity by enabling the ball to appear or “spawn” into existence, or bounce off of a surface or wall such as the paddle or the boundaries of the screen. Using this decision-making structure, we can ask questions about the current state of the world in our game, and respond accordingly. Example queries about the world state might include: Did the user press left on the keyboard? o If so, move left Did the user ask for a new ball to appear in the game? o If there are more lives left and the user wants to spawn a ball, do it Did the ball hit the paddle? o What should we do here, if so? Did the ball hit a wall like the left and right sides of the screen? o If so, change the velocity in the x by multiplying it by -1 Did the ball hit the ceiling? o If so, change the velocity of the y by multiplying it by -1 Did the ball hit the gutter area beneath the paddle? o If so, the ball becomes invisible and the player loses a life Did the ball hit a block? o Asked another way, did the ball have a collision with a block? If so, remove the block depending on certain conditions What type of block? {NORMAL, FIRE, ICE, UNBREAKABLE} What type of ball? {NORMAL, FIREBALL, ICEBALL} Variables, Objects, and Players in Our Game The variable “ball” is an Object reference, and although we don’t know much about objects yet, we have used objects before, and this will be much like that. We’ll just pick up and use this thing that we’ve never closely examined before, and parts of this experience will seem familiar – consider this analogy: You own and drive a diesel or gas internal combustion engine, but eventually move to a hydrogen fuel cell or electric car. You’re still able to drive the newer vehicle using the same old steering wheel and the accelerator pedal, regardless of the type of engine found under the hood. So let’s pick up this ball (an unfamiliar object) and play! Consider the following table, which indicates what Objects or functions are available to us in our game, and the variables or players we’ll need to manipulate to make our game experience even better. (For now don’t worry about memorizing this list – just skim the table to get an idea of what’s available, and refer back to this table as you work through this lab.) Variables & Players ball ball.Visible ball.spawn(paddle) paddle What type What does it do? of thing is it is? A Ball Manages the object. location and visual image of a ball onscreen. A primitive Boolean value. A void function. A Paddle object. ball.playBounceSound() A void function. Manages whether we see the ball on the screen. Tells the ball to become visible and positions the ball next to the provided Object (a paddle, here). Manages the paddle and collisions with the paddle ball.reflectTop() A void function. When called, this plays a ball sound. ball.yDelta = ball.yDelta * -1; playerWonGame A local Controls What can it be or return? Notes Null or pointing to a spawned ball. This is obtained from the ballSet. Can be true or false; if false, the ball is invisible. Returns void. Balls can be visible or invisible. Examine ballSet for multi-ball. Points to the usercontrolled paddle onscreen Returns void. Pass this to the spawn method called on our ball. Returns void. This changes the direction of the ball’s heading True or false; if Boolean primitive. whether we play the game or see the win screen. true, the game launches the code in gameWin() TODO 0: Single Ifs to Spawn Balls Near Paddles In this part of the lab, we’ll start by demonstrating a single if statement for you, and then have you craft your own. We’ll examine an “if” statement that has been designed to determine if the game has been won (and so we should stop the game), or if the game is still going on and there’s more work to do as far as updating the ball, paddle, and other onscreen sprites. Next to the first example in the code is another example of a compound if statement used to determine if the user is pressing on the space key (or left-clicking the mouse), which we’ll return to shortly. We’ll build our own if statement right into the simulation that will put a ball on the screen (next to the paddle), depending on certain conditions. Roughly speaking, we’ll spawn a ball if the user is asking for it and if no ball is currently bouncing around the board. Let’s dive into our first real application by wading through the following steps here, writing code as we go: 1. Before we look at any specific exercise it’s good for you to know that Visual Studio has an excellent “Find” feature. Use the EDIT Find and Replace Quick Find feature (keyboard shortcut: Control+F). Type in the text you want to search for and it’ll find it for you. VS 2013 Hint: Make sure that you’ve chosen “Current Document”, as pictured here, in order to search through the entire file. 2. Before we dive in writing our own if statements, examples have been provided for you to examine; find the comments marked as “EXAMPLE 0” and “EXAMPLE 1B” - read the comments and code. a. Optionally, draw a flowchart of a single if statement. (“TODO 0a”) b. Optionally, draw a flowchart of a single if/else statement. (“TODO 0b”) i. If you happen to know what a flowchart is, or if you look up what a flowchart is then you’re welcome to do the above two exercises. You are NOT expected to know what a flowchart is for this course, nor will you be graded on this knowledge (not here, not on exams, etc, etc) 3. Now, in the UserCodeIf.cs file, find the section marked “TODO 0”. This is where we’ll start writing if statements to add features to our game. 4. Uncomment the last few lines that look like an if statement at the end of the TODO 0 multi-line comment block. a. Replace <your question goes here> with a proper C# “question” or Boolean expression, chosen from one of the following examples: 1. Is x positive? if (x > 0 ) { 2. Is y negative or zero? if ( y <= 0 ) { 3. Is the number even? if( number % 2 == 0 ) 4. Is the Boolean true or false? if( someBoolean == true ){ b. Of the demonstrated if questions above, which do you think you should use here? i. You want to determine if a property of the ball holds a specific Boolean value: (the property is “ball.Visible”). 1. You’d like to ask (using ball.Visible): “Is this ball invisible?” a. You can restate this as: “Is the ball’s visible property false?” c. Inside the body of the if statement, put the tell the ball to spawn (ball.spawn()), but specifically near the paddle, as in: i. “ball.spawn(paddle);” 5. Now for some action: compile and run the code! To test our new section, we’ll have to fulfill the conditions of the if statement before the code in the if body will execute. a. Upon starting the game, observe that no ball is visible from the start i. So, we can assume ball.Visible is false, but we will test this assumption next. b. Press space on the keyboard and verify that the ball does appear in proximity to the paddle. i. If the ball appears, we know a few things about the state of our simulated world: 1. We know that either a button was pressed/tapped a. keyboard.isKeyTapped(Keys.Space) 2. OR, if the space button wasn’t pressed, we know that the mouse was left clicked a. (MouseDevice.MouseOnScreen() && MouseDevice.IsLeftTapped()) 3. AND, we know that ball.Visible is false. ii. So, the only way for a ball to spawn is if the ball itself is invisible, AND either the space was pressed or the left mouse button was clicked. c. Verify that your new single if statement accomplishes the desired outcome of ball spawning as outlined above before moving on. The Ball Below Was Spawned Using the Space Key TODO 1: Single Ifs for Paddle & Ball Collisions In this section, we’ll practice the single if statement again but in a new context. Notice how the ball travels right through the paddle currently, which is a logic error. The ball should “bounce off” or reflect about the paddle, and possibly play a sound. We’ll code up the single if statement responsible for handling the case where the ball collides with the paddle. First, let’s consider the moving parts – the variables – that we’ll need to work with to accomplish this task: Variables & Players ball, paddle paddle.collided(X) What type of thing is it is? What does it do? What can it be or return? Notes See previous table A Boolean function. Determines if the paddle overlaps with the ball. paddle.reflect(ball) A void function. ball.yDelta= ball.yDelta *-1; ball.playBounceSound() A void Plays a bounce Returns true if the ball and paddle collided on the screen, false otherwise. Returns void. Returns void. Similar to ball.reflectTop() , this function reflects the ball about an axis. function. sound associated with the ball. Find the code commented as “TODO 1” and read it After reading the comments, uncomment the pseudocode if statement at the bottom of the code block. The pseudocode needs to be transformed to actual C# code; using the variables and players above, transform the pseudocode into a single if statement that we can compile. We seek to ask “if the paddle collided with the ball, then reflect the ball relative to the paddle” o Note that we could ask a logically equivalent question: “If the ball collided with the paddle, then reflect the ball relative to the paddle” We choose not to use the second form of this question, however logically equivalent, for implementation reasons. The first statement above is carefully worded to indicate which methods (reflect(), playBounceSound()) belong to which variables (ball, paddle) //if the paddle collided with the ball { //using the paddle, reflect the ball Compile your code and test it. Once this section is complete, you should be able to spawn balls over and over until one bounces back to the paddle. o When the ball intersects the paddle’s surface area, the desired behavior is that ball should reflect (or “bounce off”) the paddle. Take a look at the pictorial outcome and compare it with your software before moving on; make sure your software behaves similarly. No Collision Detection With Paddle Single If Summary: Decisions are Powerful When you run the simulation and press space (or left-click), you should see a ball appear on the screen and start to move around. This logic was accomplished via the addition of a single if statement in our update() method in the UserCodeIf.cs file. By adding just two lines of code, we’ve increased what our game can do quite dramatically. Said another way, we’ve increased the complexity of the user interactions and the replayability of our software piece using just if statements. Using this same single if statement trick back-to-back (or in a sequential series), we can also add movement to our paddle and yet again increase our game’s feature set and overall fun. This is what we’ll do next in the section that describes serial, sequential if statements. Note that our update function is called many times a second and will continuously check (or poll) for the user input which can trigger these sequential if statements. To spawn a ball, we’ll need to either tap the space button or left-click on the mouse, but this is not sufficient in and of itself. The if statement we just wrote also requires that the ball not already be onscreen (i.e. the ball isn’t “live” or “spawned” yet); said more precisely, ball.Visible is not true. To rephrase in ambiguous English, “If the user asks to spawn a ball by hitting space (or later, left-clicking) and if there is no ball already onscreen, then spawn a ball near the paddle.” TODO 2: Sequential If Statements & Moving the Paddle with the Keyboard In this section, we’ll add more interactivity and responsiveness to our game by facilitating paddle movement in response to button presses (or mouse movements). To do this, we’d like to encode the following questions using C#’s Selection Control Structures, or if statements: If the left button is pressed, move the paddle left If the right button is pressed, move the paddle right If the up/down buttons are pressed, move the paddle in the y-axis. Note that, as the designers of this game, we could choose to implement any types of events that we want here, including unusual behaviors such as moving the paddle left when the user presses right! Also, we can differentiate our software from other such pong games by moving our paddle up and down – these decisions are up to us! They are all accomplished using if statements, and we’ll need more than one in this section, so we introduce the concept of asking multiple sequential questions here. Note that these questions could be related, but by definition of the sequential if statement are not required to be. Sequential If Statement Definition: Two ifs are related sequentially if they are positioned in linear order next to one another, but not conjoined by an “else” or “else if” clause. Such if statements are related only by proximity. They are not mutually exclusive with respect to their code bodies, as are if statements that use the “else” and “else if” keywords, introduced in a following section. In this code TODO, we’re going to ask a series of sequential questions to help move the paddle when the user requests it. First, we will demonstrate the pattern of a set of sequential if statements. if( <some boolean question, for example is x less than 90> ) { //ifBody1 code goes here, not mutually exclusive to any other code body } if( <some boolean question, for example is y odd> ) { //ifBody2 code goes here, not mutually exclusive to any other code body } … /* more single if statements could go here */ … if(<some boolean question, unrelated to the questions above> { //ifBodyX goes here, not mutually exclusive to any other code body } A few observations are in order regarding the above set of sequential, single if statements. First is that all internal code bodies could execute if all Boolean questions evaluate to true; that is, none of the code blocks are mutually exclusive. If we wanted to obtain this different logical behavior, we’d need to use the “else” or “else if” keywords. Secondly, note that just like in all other if statements (except those with a trailing else, discussed last), none of the code bodies are required to execute, so if all Boolean questions are false, not one code body runs. Finally, it’s worth noting that these if statements may or may not be related at all to one another. For example, consider the following two if statements that are unrelated to one another. if( rainingOutside == false) { ... } if( timeForAHaircut == true) { … } When logical conditions or questions are unrelated, the sequential set of if statements is the weapon of choice. We’ll practice using this technique below on a set of questions that are actually related, and we’ll return to this code to improve it when we learn to use “else” and “else if” later. Consider the players in this section of the game before digging into the code examples and exercises below. Variables & Players keyboard What type of thing is it is? An Object somewhat similar to a Scanner. keyboard.isKeyDown(Keys.Space) A Boolean function. keyboard.isKeyDown(Keys.Left) A Boolean function. paddle A Paddle Object. paddle.moveLeft() A void function. A void function. The Mouse object. paddle.moveRight() MouseDevice MouseDevice.MouseOnScreen() A Boolean function. What does it do? Use this to determine if certain keys are pressed. Determines if the provided key is pressed. Determines if the provided key is pressed. Use this to spawn balls and What can it be or return? This object is set up for you and not null. Returns true or false. Returns true or false. This is obtained from the paddleSet Moves the Returns paddle left. void. Moves the Returns paddle right. void. Use this to This get mouse object is information set up for you and not null. Use this to Returns determine if true or a mouse is false connected. based on mouse status. Notes This usage checks for the space button. This usage checks for the left button. Examine paddleSet for 2player. In the UserCodeIf.cs file, find the section marked “EXAMPLE 2” o Read the code and see an example of sequential if statements, back-toback. In the UserCodeIf.cs file, find the section marked “TODO 2” o You can search the file for this text string using CTRL-F or Command-F for PCs and Macs, respectively, in your text editor. Read the questions in the comments and transform each query in pseudocode to actual C# code, one at a time, starting with moving the paddle left o Uncomment out the last few lines of code that look like four sequential, single if statements o Transform the pseudocode into actual C# code by reading the comments and following the directions. o Once you’ve completed just one if statement, compile and run the code to make sure you can move your paddle left or right respectively. Notice how the last few pseudocode statements offer you even less details. o Can you convert these statements into C# code by following the pattern you used for moving left and right above? Once you’ve got the paddle moving left, right, up and down, then uncomment the single sequential if statement near “TODO 3:” for mouse support. o Recompile and run the game, experimenting with the mouse and ball spawning The Paddle Is Moved Left Using the Left Key on the Keyboard TODO 3: Single If Statements Revisited In this section, we’ll help complete a single if statement to enable mouse support. We need to check if the user has a mouse connected to our system and if so, we’ll execute some code to move the paddle accordingly. In this section, the body of the if statement is already written for you – you simply need to wrap those lines of code in the if statement you will build. We seek to ask the question: “is the mouse on the screen?”, so consider the two variables below before you build your single if statement. Variables & Players What type of thing is it is? What does it do? What can it be or return? MouseDevice MouseDevice.MouseOnScr een() A Boolean Determines if Returns true if a function. a mouse is mouse is found, connected to false otherwise. our system. Notes See previous table Use this in your if statement to determine if a mouse is usable. Find the section of code commented as “TODO 3” and read it. Uncomment the pseudocoded “if” statement at the bottom of the comments o Note that the lines inside the “if” statement are marked “leave as-is”, since these are actual instructions that need no modification but should be left in the body of your if block. Rewrite the “if” Boolean expression to use variables from the table above. Recompile and execute your code. If everything is awesome, you’ll be able to control the paddle using the mouse in addition to the keyboard o Note that enabling the mouse indicates to the game that the mouse has priority over the keystrokes. No one screenshot will easily convey mouse-to-paddle motion transfer, so use your imagination to envision a paddle that moves left when you move the mouse left, and moves right when the mouse moves right. o This is how your simulation should function when this section is complete. TODO 99: Transforming Sequential If Statements Into A Single If-Else Statement In this section, we’ll take two existing if statements that are mutually exclusive and combine them. Any set of if conditions that are related by mutual exclusion should be related explicitly in your code for clarity and performance. We’ll start with two if statements that are sequential and back-to-back, but should really be related and transform the code to what it should be. Since the code is already completely written, there are no new variables or players to consider here. Find the section of code commented as TODO 99 and read it. Follow the translation pattern presented in the comments for combining two sequential if statements into one if-else statement o To do this, move all of the comments in TODO 99 and EXAMPLE 2 out from in-between the two if statements. Starting with the second if statement (if(!playerWonGame)) and hit backspace until you are on the line with the closing “}” from the previous if(playerWonGame). o Delete the text “if(!playerWonGame)” from the second if and replace it with “else” As in: “} else {“ Recompile and execute your code; if everything works, you should notice no changes to the flow of the game, while at the same time noticing your code has improved internally o It’s faster and more readable, which are both big software engineering wins. TODO 4: Compound If Statements Using Logical AND (&&) with Mouse Support for Ball Spawning In this section, we’ll describe how to produce even more expressive and powerful if statements that ask increasingly detailed questions about the state of our world. Frequently one question isn’t enough to determine if the creature behind the curtain is a robot or a human, and so we’ll need the ability to ask a series of logically related questions, and if statements are perfect for this task. For example, we can logically relate questions using if conjunctions “else if” and “else”, but before exploring those we can observe relating questions using && and ||, C#’s logical AND and OR, respectively. By linking two questions, we can not only indicate an order for the questions to be asked but also what to do if all the questions return true (AND, like a circuit in series) or if even just one of the questions result in a true value (OR, like a circuit in parallel). We’ll start with a common programming task: making sure an object isn’t null before we try to use it. Remember what happens if we try to reference String[] args in our program? Or if we declared a Scanner foo = null; and then called foo.nextInt()? This results in the infamous NullPointerException, and we’re about to dance right around that common problem in our code by looking an example that determines if a ball exists first before using it. Find the topic ShortCircuit Evaluation in your textbook’s appendix and read about this useful construct that we’re about to observe in action. Logical AND (&&) Variables & Players ball, ball.Visible ball.collideWorldBound() ball.reflectLeft() MouseDevice, MouseDevice.MouseOnSc reen() What type of thing is it is? What does it do? An integer function. Checks for collisions with the edges of the screen. A void function. ball.xDelta= ball.xDelta *-1; What can it be or return? Notes See previous table Returns an int. A The return BoundCollidedSta values can be { tus indicates BoundCollidedS what side of the tatus.CollidedT screen was op,…CollidedBo collided with (if ttom, any). …CollidedLeft, …CollidedRight} Returns void. Changes direction of the ball in the xaxis. See previous table First check out the code section marked “EXAMPLE 4” o Read this code to see an example of using the logical AND operator to prevent a NullPointerException from being thrown. o Do you see how the AND is used in the code? What would the effect be if the AND was replaced with an OR? Would this still prevent the NullPointerException? Next, go to the section marked “TODO 4” and read the comments Your job here is to combine two single, nested (and thus not sequential) if statements into one larger, compound if statement joined by an AND o Note that any nested if statement can be refactored in this manner to produce one larger if statement Notice also that nesting if statements is effectively ANDing their conditions together Start by copying-and-pasting the original code so you always have a starting reference point. o Now, comment out the original and edit the copy o Remove the inner if statement completely by joining it’s boolean expression with the outer if statement using an AND (&&). When you’re done, you should have produced a single if statement that will spawn the ball near the paddle if you have a mouse and the left-button is being pressed. o Test your code for this behavior before moving on The Ball Below Was Spawned Using the Mouse and a Compound If with && Using TODO 4’s Code TODO 5: Compound If Statements Using Logical OR (||) & Spawning the Ball Revisited Next, we’ll experiment with the logical OR operator in C#. We can use logical OR in places we could use AND to produce a more expressive and longer Boolean expression for use in our if statements. In this next section, we observe some duplicate code in our software, which we’d like to remove in this lab just as we’ll do in our first few homework assignments. Logical OR (||) Variables & Players keyboard.isKeyTapped(KE YS) What What does it What can it be or type of do? return? thing is it is? A Boolean Determines if Returns true or function. the provided false. key has been typed. Notes Similar to isKeyDown(); use Keys.Space or Keys.Left, etc. Unlike isKeyDown this will only return true once, the very first instant that the key is pressed MouseDevice, MouseDevice.MouseOnScr een() MouseDevice.IsLeftTapped A Boolean Determines if () function. the indicated mouse button has been pressed. See previous table Returns true if the left mouse button has been clicked, in this case. Experiment with MouseDevice.IsR ightTapped() for right-clicks and power-ups. Find “TODO 5” in the code and read the comments Add to the if statement in this section so that it will spawn a new ball if the keyboard is pressed OR BOTH the mouse exists AND the mouse’s left button is pressed. ROB, this needs a rewrite! o To accomplish the BOTH above, use parenthesis around the mouse statements, as the following pseudocode demonstrates if( keyboard.isKeyDown() OR ( mouse exists && pressed)) Recompile and run your code; if it works, you should be able to spawn balls using the mouse’s left-click, just like before o To test this code, comment out the compound if statement with && you just did in the previous TODO4 You should still be able to spawn balls via the mouse and your new code in TODO5 This Ball Below Was Spawned Using the Mouse and a Compound If with || Using TODO 5’s Code TODO 6: Chained IF/ELSE Structures With No Default Else (A.k.a. Multi-way Ifs) In this section, we’ll build one IF/ELSE structure that handles three mutually exclusive cases in our game. The ball and paddle should remain in synch with respect to their status; if the paddle is on fire, the ball should also be a fireball, and if the paddle is icy, the ball should be an iceball respectively. As the game is currently, the paddle will change in accordance with the blocks that the ball has hit; however, the ball doesn’t change at all. We’ll introduce an IF/ELSE statement to fix this broken behavior. First, consider the variables and players we’ll need to use: Variables & Players What type of thing is it is? What does it do? What can it be or return? paddle See previous table Paddle.PaddleState An enumerated type. paddle.getState() A function that returns a PaddleState. ball Notes Differentiates paddle states. PaddleStates are {NORMAL, FIRE, ICE} Returns a PaddleState See previous table Ball.BallType An enumerated type. ball.setType() A void function. Differentiates ball types & states. This sets the current ball type. BallTypes are {NORMAL, FIRE, ICE} Returns nothing. Notice the similarities to paddle.getState() Indicates what ball to draw on the screen. Find the code comments associated with “TODO 6” and read the code After reading the comments, uncomment the pseudocode at the end of the block comment to get started Notice the compiler errors; change the pseudocode to actual code using the variables and players outlined above. o For example, “if( paddle is normal)” becomes “if(paddle.getState() == Paddle.PaddleState.NORMAL)” Replace the body of the IF statements with actual code to change the type/state of the ball o Based on the current state of the paddle, so something like: So if the paddle is in the FIRE state, so is the ball ELSE, if the paddle is in the ICE state, so is the ball ELSE the paddle is normal, and so is the ball Run the code and note that the ball should change when the paddle changes o Said another way, when the ball collides with a FIRE block, the paddle changes to a FIRE paddle (which it did previously) AND the ball changes to a FIRE ball respectively (which the game did not previously do). An Ice ball and an Ice Paddle in a Synchronized Visual State TODO 7: Nested If Statements In this section, we’ll experiment with putting if statements inside of if statements to find the smallest of three top scores. In our game, we’ll concern ourselves with only two top scores: the top score of the day and the overall top score. So, anytime a player plays a new game, she will generate a new score c. Now, given the three values a,b,c where a is the top score of the day, b is the overall top score, and c is the new score in question, we want to find the minimum score and toss it out. So lets build a function similar to Math.max(a,b) but that instead takes three variables for our game. Find the section of code marked as TODO 7 and read it. Uncomment out the first set of two pseudocoded if statements and change the pseudocode into actual code o Hint: consider using “<” and “=” Uncomment out the second set of two pseudocoded if statements and change the nonworking code into functional C# code. Note that we can wrap one if statement completely inside the other for a specific logical meaning; in this case, it’s to determine the smallest of three values. Test your code by adding a few calls to your new function in the initialize() function that look like: o Console.WriteLine( minimum(3,2,1) ); Add two more printlns like this and change the numbers inside the parenthesis to test your minimum function. When everything is complete, you should be able to determine the least of three numbers using ifs inside of ifs, using your console output as verification. The Console the Output for “minimum(3,2,1)” is 1 TODO 8: Nested If-Elses (A.k.a If-Elses Inside of If-Elses) In this section, we’ll write something similar to the last function, but this time using even more code to determine the maximum of three numbers. This too could be used to determine top scores, and we’ll seek to compare the solution we create here to the solution in TODO 7 and in TODO 9 to pick the best one. We want to experiment with if-else structures wrapped completely inside other if-else structures, to determine the largest of three integers a,b and c. Find the section of code with the comments “TODO 8” and read it Uncomment all of the if statements and convert the pseudocode in the boolean expressions to actual code. o Hint: consider using “>” and “=”. Comment out the “return -1;” statement at the bottom of the function. Recompile and run your code; when it’s complete, we’ll need to add a few lines in the initialize() function to test your maximum function. o Add the following code to your initialize() function: “Console.WriteLine( maximum(1,2,3) );” Copy this line 3 times and change the numbers to test your function more completely Run the code and observe the output in the console – is your maximum function reporting the largest number? The Console the Output for “maximum(3,2,1)” is 3 TODO 9: Transforming Nested Ifs Using && In this section, we’ll make the smallest minimum function possible using logical AND. In TODO 7 we made a shorter min function and in TODO 8 we made a longer max function; now we seek to reduce the min function truly to its minimum form, by replacing the nested ifs with &&. Find the section of code with the comments “TODO 9” and read it Following the pattern presented in the pseudocode, lets convert the first two if statements into one using && Put your cursor just before the innermost if statement and hit backspace until you’re on the previous line that contains an if statement. o Delete the “{ “and the “)” and the second “if” so your code looks like: “if( <questionA> if (<questionB>) {“ o Now change the second “if” to “&&” and delete the second “(“ so you have: “if(<questionA> && <questionB>) {“ Recompile and run your code; your tests should still call this function in the initialize() method. o Make sure your new minimum function actually returns the smallest value. Now, which do you think is the more efficient if code? The minimum function here or the maximum function built in TODO 8?