GROUPING DATA IN ONE-DIMENSIONAL ARRAYS - LEARN TO PROGRAM WITH SMALL BASIC: An Introduction to Programming with Games, Art, Science, and Math (2016)

LEARN TO PROGRAM WITH SMALL BASIC: An Introduction to Programming with Games, Art, Science, and Math (2016)

15. GROUPING DATA IN ONE-DIMENSIONAL ARRAYS

So far you’ve worked with variables to store single pieces of information, and you’ve created some pretty awesome programs. But you can create even more amazing programs by storing lots of information in a single variable! In Small Basic, you do that by using an array.

An array is a built-in data type that lets you work with groups of data. For example, you wouldn’t build a separate closet for every pair of shoes you own (unless you’re a giant who loves shoe shopping); you’d put them all in one closet. Well, arrays let you store many pieces of data together to make it easier to work with them all at once. You can think of the closet as a one-dimensional array that contains a row of shoe boxes.

Small Basic has two types of arrays: indexed arrays and associative arrays. The pieces of data in an indexed array are referenced using an integer index, such as score[1], name[3], and so on. This is like putting a numbered label on each shoe box in your closet. But the elements of anassociative array are referenced using a string index, such as price["apple"] or address["John"]. This chapter explores indexed arrays. We’ll cover associative arrays, also called hashes or maps, in the next chapter.

Getting Started with Indexed Arrays

Let’s say you want to write a program that takes four test scores from a user and then displays them along with their average value. Based on what you’ve learned so far, you might write a program like the one in Listing 15-1.

1 ' Average1.sb
2 TextWindow.Write("Enter 4 scores. ")
3 TextWindow.WriteLine("Press <Enter> after each score.")
4 s1 = TextWindow.ReadNumber() ' Reads the 1st score
5 s2 = TextWindow.ReadNumber() ' Reads the 2nd score
6 s3 = TextWindow.ReadNumber() ' Reads the 3rd score
7 s4 = TextWindow.ReadNumber() ' Reads the 4th score
8 avg = (s1 + s2 + s3 + s4) / 4 ' Calculates the average
9 TextWindow.Write("Numbers: " + s1 + ", " + s2 + ", ")
10 TextWindow.WriteLine(s3 + ", " + s4)
11 TextWindow.WriteLine("Average: " + avg)

Listing 15-1: Storing scores in separate variables

This program prompts the user to enter four scores (lines 2–3). It reads these scores and saves them in the four variables s1, s2, s3, and s4 (lines 4–7). Then it computes the average (line 8), displays the four numbers on a single line (lines 9–10), and displays the computed average (line 11).

Now imagine that you want a user to input 100 scores instead of 4. Defining 100 variables and copying almost the same statement 100 times would take a long time. Well, Small Basic’s array stores a collection of values. Using an array, you don’t have to create each variable separately. You can put all the values into one array variable. For example, you can read 10 scores a user enters and store them in one array using this loop:

For N = 1 To 10
score[N] = TextWindow.ReadNumber()
EndFor
TextWindow.WriteLine(score)

Instead of creating 10 variables, like s1, s2, and so on to s10, you create one array variable called score. To refer to each piece of data in the score array, you use the syntax score[N], where N is a variable that will take on the values 1 through 10. Writing score[N] is like writing score[1],score[2], ..., score[10], and the For loop increments N for you.

Run this code. After you enter 10 different numbers, Small Basic displays the score array, and you can see all 10 values stored in it (we’ll show you a better way to display an array later in this chapter).

One way to think of an array is as a collection of variables that share the same name. For example, the average rainfall in the 10 largest US cities could be saved in rainLevel[1] through rainLevel[10], and the daily sales for the 100 McDonalds in your area could be saved in sales[1]through sales[100]. Think of all the Happy Meals!

Arrays can help you organize your data in a way that makes the data much easier to change and use. The name of an array follows the same rules and guidelines you use for naming variables.

Array Basics

Each piece of information in an array is called an element. To access an element in an array, you use this syntax:

arrayName[index]

The arrayName variable is the array’s name, and index is an identifier, either a number or a string, that identifies an element in the array (see Figure 15-1). This syntax is known as an indexed variable, or a subscripted variable. The index, which is placed between square brackets, uniquely identifies one element in the array.

image

Figure 15-1: Graphical representation of a one-dimensional array

You can treat an indexed variable just like a regular variable by using the proper syntax. For example, the following statements initialize and display the first three elements of the score array in Figure 15-1:

score[1] = 80
score[2] = 85
score[3] = 90
TextWindow.WriteLine(score[1] + ", " + score[2] + ", " + score[3])

If you run this code, you’ll see this output:

80, 85, 90

If you wanted to change the first score, you could write this statement:

score[1] = score[1] + 5

This line of code adds five to the first score at index 1. If you displayed the value of score now, you’d see that score[1] = 85. You could use the next statement to multiply the two elements at indices 1 and 2:

score[1] = score[1] * score[2]

If score[1] is 80 and score[2] is 85, they are multiplied to get 6,800, which is saved back into score[1]. High score!

Initializing Arrays

Before using an array in your program, you need to fill it up (or initialize it) with some data. In Small Basic, you can do this in two ways: by direct (element-by-element) initialization or string initialization.

Let’s say you want to create an array that holds four scores (not the Abe Lincoln type). Here’s the direct way to do this:

score[1] = 80
score[2] = 85
score[3] = 90
score[4] = 95

You can also use a string initializer, which allows you to set the four values in just one line like this:

score = "1=80;2=85;3=90;4=95;"

This string initializer has four tokens (or fields), which are terminated by semicolons. Each token is in this form (and no, you can’t exchange these tokens for prizes):

index=value;

In this example, the first token is 1=80, the second is 2=85, the third is 3=90, and the fourth is 4=95. The number before the equal sign is the element’s index, and the value after the equal sign is the value stored in that element. Note that there are no spaces before or after the equal sign.Figure 15-2 shows you how this string initializer works.

image

Figure 15-2: The syntax of an array’s string initializer

The string initializer lets you fill an array in one statement, but its syntax is a bit complex, and you could accidentally introduce errors in your code. Until you become more comfortable with arrays, we recommend that you stick to the basic element-by-element initialization technique in your programs. But if you do use the string initializer and run into problems, try reinitializing your array one element at a time. We’ll use both initialization types in this book, to save space and to get you more familiar with them.

NOTE

Small Basic lets you choose any numbers you want for indices. It even lets you use negative and decimal numbers, and it doesn’t require the indices to be consecutive. But in this book we’ll always use integer indices starting from 1 for the first array element.

Arrays and For loops are often used together. When the size of an array is known, you can use a For loop to cycle through and perform operations on every element in that array. The next examples show you how to use For loops to perform operations on arrays.

TRY IT OUT 15-1

Suppose that the elements in array S and variables A and B have the values in Figure 15-3. What is S[A], S[B], S[A * B - 2], S[A + B], and S[A] - 2 * S[B]?

image

Figure 15-3: Values in S array and variables A and B

Filling Arrays with a For Loop

Many times you’ll need to fill the elements of an array with a constant value, a random value, a value calculated from a formula, or a value entered by a user. Let’s look at each scenario!

Constant Initialization

The following code snippet shows how to initialize the first 10 elements of a tasty array (named scoobySnack) with a constant value of 0.

For N = 1 To 10
scoobySnack[N] = 0
EndFor

The For loop repeats 10 times. In the first iteration, the value of N is 1, so the loop sets scoobySnack[1] = 0. In the second iteration, the value of N is 2, so the loop sets scoobySnack[2] = 0, and so on. This creates an array with 10 elements, all of which are 0.

Random Initialization

You can also fill the elements of the scoobySnack array with random numbers, like this:

For N = 1 To 10
scoobySnack[N] = Math.GetRandomNumber(5)
EndFor

The For loop iterates 10 times. In the Nth iteration, the element at index N, scoobySnack[N], is assigned a random number between 1 and 5. Try displaying the value of scoobySnack to see what random numbers you get! Add the following statement after you set scoobySnack[N] inside the Forloop:

TextWindow.WriteLine(scoobySnack[N])

Formula Initialization

You can also initialize the elements of an array using a formula. In this example, you’ll set the Nth element of the scoobySnack array to N * 8; this code will store the multiplication table of eight in your array:

For N = 1 To 10
scoobySnack[N] = N * 8
EndFor

Add the code that displays the value of scoobySnack to see the results!

User Initialization

What if you want to initialize the elements of your array using values entered by a user? The following program prompts the user to enter five numbers and press ENTER after each number. The program then starts a For loop to read the five numbers and store them in thunderCat[1],thunderCat[2], ..., thunderCat[5].

TextWindow.WriteLine("Enter 5 numbers. Press Enter after each one.")
For N = 1 To 5
thunderCat[N] = TextWindow.ReadNumber()
EndFor

This technique is very useful for storing lots of data from a user. What other collections of data might you ask for? How about breakfastMenu, favoriteGames, bestPasswords, funnyJokes, or frozenNames?

TRY IT OUT 15-2

Write a program that fills an array called skeletor with even integers from 20 to 40 (for example, skeletor[1] = 20, skeletor[2] = 22, ...).

Displaying Arrays

Let’s say we have an array named age that holds the ages of three brothers, like this:

age[1] = 14
age[2] = 15
age[3] = 16

You can display the contents of this array in two ways. The first and easiest way is to pass the array’s name to the WriteLine() method, like this:

TextWindow.WriteLine(age)

Here’s the output of this statement:

1=14;2=15;3=16;

This statement displays the elements of the array on a single line separated by semicolons. Each token in this string shows the index and the value of the array’s element at that index. Can you see now where the array’s string initializer syntax came from?

If you want to display the array in an easier-to-read format, you can use a For loop to display each element of the array in its own row:

For N = 1 To 3
TextWindow.WriteLine("age[" + N + "] = " + age[N])
EndFor

Here’s the output of this loop:

age[1] = 14
age[2] = 15
age[3] = 16

If you’re working with a short array, it’s fine to display it on a single line. But if you’re working with a lot of data, it’s best to display the array in a format that’s easy to read.

TRY IT OUT 15-3

Write a program that fills an array called burps with five random numbers between 80 and 100 and then displays the array. Try displaying the array by passing the array’s name to TextWindow.WriteLine() and then by using a For loop. Which looks nicer?

Processing Arrays

Many programs involve processing the elements of an array, such as adding them and finding their average, minimum, maximum, and so on. You’ll learn how to do these tasks in this section.

Finding the Sum

A superhero named Super Here-O wants to know how much money he rescued from 10 robbers in his town. The following program lets Super Here-O enter the amounts he rescued into an array named moneyReturned. The program finds the sum of all the elements of this array:

sum = 0
TextWindow.WriteLine("Enter the 10 amounts that were returned:")
For N = 1 To 10
moneyReturned[N] = TextWindow.ReadNumber()
sum = sum + moneyReturned[N]
EndFor
For N = 1 To 10
TextWindow.Write("$" + moneyReturned[N])
TextWindow.WriteLine(" rescued from robber " + N)
EndFor
TextWindow.WriteLine("$" + sum + " was rescued by Super Here-O!")

To find the sum, you start by initializing the sum variable to 0. You then run a For loop to read each element of the moneyReturned array and add it to the sum variable. When the loop terminates, you start another loop to show how much money was rescued from each robber, and then you display the total amount returned. Run the program to find out whether it’s enough money to buy a new superhero spandex suit!

Finding the Maximum Element

Say you’re competing with nine of your good friends to see who has the most friends on Facebook. Use the following code snippet to find the largest value in an array named friends:

friends = "1=10;2=30;3=5;4=10;5=15;6=8;7=1;8=23;9=6;10=11"
max = friends[1]
For N = 2 To 10
If (friends[N] > max) Then ' Nth element is larger than max
max = friends[N] ' Update max to hold the new maximum
EndIf
EndFor
TextWindow.WriteLine("The most friends is " + max + ".")

First, we filled the 10 elements of the friends array with the number of Facebook friends that you and your nine closest friends have. In this example, your first friend has 10 friends, your second friend has 30, your third friend has 5, and so on, and you (number 10 in the array) have 11 friends. Feel free to change these numbers. The program starts by assuming that the first element, friends[1], is the largest. It then enters a loop that examines the remaining elements of the array, starting at the second element. Every time it finds a number larger than the current maximum, it updates the maximum, max, to that number. When the loop terminates, the maximum value displays.

Using String Values in Arrays

Arrays aren’t restricted to numbers. You can also use arrays to store strings. Let’s say, for example, that you want to create an array to store the names of the books in your collection. You could initialize this array:

book[1] = "The Hobbit"
book[2] = "Little Women"
book[3] = "My Little Pony vs Hello Kitty"

NOTE

You could also use a string initializer to initialize the book array like this (make sure the entire statement is on one line):

book = "1=The Hobbit;2=Little Women;3=My Little Pony vs Hello Kitty"

TRY IT OUT 15-4

Write a program that fills two arrays (noun and verb) with plural nouns and verbs of your choice. Have the program display random sentences in this form: noun verb noun (for example, dogs delight cats).

Saving Records

You can mix different data types within a single array. You can store numbers, both whole and decimal, and strings as different elements in the same array. For example, the following array is valid (do you know this building?):

arr[1] = 1600
arr[2] = "Pennsylvania Avenue NW"
arr[3] = 20500

The first and third elements of this array are numbers. The second element is a string. These three elements could represent a home’s number, its street name, and its ZIP code, respectively. This is one way to create a record, which is a collection of related pieces of data, in Small Basic.

Whew! Well, we’ve covered more than enough to solve oodles of problems. Now let’s spend some time writing fun programs!

Using Indexed Arrays

The first example in this section shows you how to select random elements from an array. The second example simulates a Magic 8 Ball game in which the computer provides randomly selected answers to a player’s questions. Let’s get random!

Random Selection

Let’s say we have a bag that contains 10 balls numbered 1 through 10, and we want to take out five random balls (see Figure 15-4). We’ll write a program that randomly selects five balls and then displays their numbers.

image

Figure 15-4: Randomly selecting five balls from a bag

To create this program, we’ll use an array named ball to hold the numbers of the 10 balls (ball[1] = 1, ball[2] = 2, …, ball[10] = 10). Then the program selects a random number between 1 and 10 to pick a ball. For example, if it picks number 2, it sets ball[2] = 0 to indicate that the second ball has been selected and is no longer available. Then it selects another random number. Let’s say that the second number is also 2. First, the program checks ball[2]. Because it’s 0, it knows that ball[2] has already been selected (you can’t take the same ball out of the bag twice!), and it picks another random number. It continues this until it selects five different random numbers. The complete program is shown in Listing 15-2.

1 ' RandomSelect.sb
2 For N = 1 To 10 ' Puts the 10 balls in an array
3 ball[N] = N
4 EndFor
5
6 For N = 1 To 5 ' Loops to select 5 balls
7 idx = Math.GetRandomNumber(10) ' Gets random ball number
8 While (ball[idx] = 0) ' Ball already selected
9 idx = Math.GetRandomNumber(10) ' Gets another number
10 EndWhile
11
12 TextWindow.Write(ball[idx] + ", ") ' Displays selected ball
13 ball[idx] = 0 ' Marks it out (taken)
14 EndFor
15 TextWindow.WriteLine("")

Listing 15-2: Randomly selecting five different balls

The program starts by setting ball[1] = 1, ball[2] = 2, ..., ball[10] = 10 in a For loop (lines 2–4). It then begins a loop to select the five balls (line 6). In each iteration of the loop, it picks a random number, idx, between 1 and 10 (line 7). A While loop continually sets idx until ball[idx]is not 0 (lines 8–10). After selecting a unique ball number, the program displays the number (line 12), and then it marks that ball as selected by setting its array element to 0 (line 13) so it doesn’t try to select that number again. Here’s a sample run of this program:

5, 9, 10, 1, 2,

Run the program to see which numbers you get!

A Magic 8 Ball

In this example, we’ll write a program that simulates a Magic 8 Ball game. A user asks a yes or no question, and the computer answers. Of course, it’s just for fun, so don’t use it to make important decisions like choosing your spouse or house! The complete program is shown in Listing 15-3.

1 ' Magic8Ball.sb
2 ans[1] = "It is certain. Like really, really certain."
3 ans[2] = "It is decidedly so. By me. I decided."
4 ans[3] = "Without a doubt. Maybe one doubt."
5 ans[4] = "Yes, definitely. Isn't it obvious?"
6 ans[5] = "Very doubtful. The doubt is very full."
7 ans[6] = "Maybe. Depends on the horse race."
8 ans[7] = "No. Wait, yes. Wait, no. Yes, it's no."
9 ans[8] = "Let me consult my Magic 8 Ball... It says yes."
10 ans[9] = "Outlook not so good. Restart Outlook."
11 ans[10] = "Try again. It's funny when you shake things."
12
13 While ("True")
14 TextWindow.WriteLine("Ask me a yes-no question. Do it!")
15 ques = TextWindow.Read()
16 num = Math.GetRandomNumber(10)
17 TextWindow.WriteLine(ans[num])
18 TextWindow.WriteLine("")
19 EndWhile

Listing 15-3: A Magic 8 Ball simulation

The game has 10 possible answers saved in the ans array. After initializing the array (lines 2–11), the game starts an infinite loop to interact with the user. In each iteration it asks the user to enter a yes or no question. It reads the user’s question (line 15), generates a random number between 1 and 10 (line 16), and uses that number to display one of the answers using ans[num] (line 17). After displaying the message, we display a blank line (line 18). For someone who doesn’t know the trick, the computer might look intelligent! Ask your friends to play this game, and see what they think.

How’re you feeling? Sharp as a sponge and fresh as a tack? Great, because it’s game creation time!

TRY IT OUT 15-5

Modify the Magic 8 Ball game so it shows each answer only once. End the game when all the answers have been displayed.

Create the Catch Apples Game

Figure 15-5 shows a game in which apples appear in random positions at the top of the graphics window at random times and fall to the ground. The player has to move the cart using the mouse to catch the apples before they hit the ground. Each apple is worth 1 point. Don’t worry about bruising the apples; they’re hard core!

image

Figure 15-5: The Catch Apples game

Follow these steps to put this great game together one piece at a time.

Step 1: Open the Startup File

Open the file CatchApples_Incomplete.sb in this chapter’s folder. The folder also has all the images you’ll need for this program. The startup file contains the main code (shown in Listing 15-4) and empty placeholders for the four subroutines that you’ll write. Let’s start with the main code.

1 ' CatchApples_Incomplete.sb
2 GraphicsWindow.Title = "Catch Apples"
3 GraphicsWindow.CanResize = "False"
4 GraphicsWindow.Width = 480
5 GraphicsWindow.Height = 360
6 GraphicsWindow.FontSize = 14
7 GraphicsWindow.BrushColor = "Black"
8
9 path = Program.Directory
10 GraphicsWindow.DrawImage(path + "\Background.png", 0, 0)
11
12 msgID = Shapes.AddText("")
13 Shapes.Move(msgID, 240, 0)
14
15 MAX_APPLES = 5 ' Change this to have more apples
16 AddApples() ' Creates the apple array
17
18 cartImg = Shapes.AddImage(path + "\Cart.png") ' 100x80 pixels
19
20 numMissed = 0 ' Missed apples
21 numCaught = 0 ' Caught apples
22
23 While ("True")
24 Shapes.Move(cartImg, GraphicsWindow.MouseX - 50, 280)
25 MoveApples()
26 Program.Delay(5)
27 EndWhile

Listing 15-4: The main code for the Catch Apples game

In lines 2–7, we set the graphic window’s title; size, to match the size of the background image; font size; and font color. Then we draw the background image (line 10) and create the text shape that displays the number of caught and dropped apples (lines 12–13). The MAX_APPLES variable in line 15 is the maximum number of apples that will appear in the graphics window. Once you get the game running, experiment with this number to make the game easier or harder.

Line 16 calls the AddApples() subroutine to create the array that will hold the falling apples. Line 18 adds the cart’s image and saves its identifier in cartImg; we need this identifier to move the cart.

Lines 20–21 initialize the variables numMissed (the number of missed apples) and numCaught (the number of caught apples) to 0. The code then starts the game’s main loop (lines 23–27). In each iteration, we move the cart so its center lines up with the mouse’s x position (line 24). Because the cart’s width is 100 pixels, the cart’s left position is set to MouseX – 50. The cart’s y-position is fixed. We call the MoveApples() subroutine to make apples fall and check whether they touch the cart or the ground (line 25); then we wait 5 milliseconds before repeating these steps (line 26). But don’t tell your dad to wait 5 milliseconds, or he might think you’re sassing!

Run the game now, and move the mouse. The cart follows the mouse, but no apples appear yet. You’ll add the missing subroutines next to finish the game.

Step 2: Add the Apples

Add the AddApples() subroutine in Listing 15-5.

1 Sub AddApples
2 For aplNum = 1 To MAX_APPLES
3 apple[aplNum] = Shapes.AddImage(path + "\Apple.png")
4 scale =(3 + Math.GetRandomNumber(5)) / 10
5 Shapes.Zoom(apple[aplNum], scale, scale)
6 SetApplePosition()
7 EndFor
8 EndSub

Listing 15-5: The AddApples() subroutine

The subroutine uses a For loop to create the five apples. In each iteration, we call AddImage() to load the apple’s image from the game’s folder and save the returned identifier in the apple array (line 3). The first apple is saved in apple[1], the second apple is saved in apple[2], and so on.

To add some variety to the apple game, we’ll change the sizes of the apples. In line 4, we set the scale variable to a random value from the set {0.4, 0.5, 0.6, 0.7, 0.8}, which is calculated by (3 + Math.GetRandomNumber(5)) / 10. In line 5, we pass that value to the Zoom() method to change the apple’s size. This sets the apple’s size to a fraction (between 40 and 80 percent) of its original size.

Next, we’ll call the SetApplePosition() subroutine to position the new apple. Let’s examine what this subroutine does.

Step 3: Position the Apples

Add the SetApplePosition() subroutine in Listing 15-6.

1 Sub SetApplePosition
2 xPos = Math.GetRandomNumber(420)
3 yPos = -Math.GetRandomNumber(500)
4 Shapes.Move(apple[aplNum], xPos, yPos)
5 EndSub

Listing 15-6: The SetApplePosition() subroutine

We set the horizontal position to a random integer between 1 and 420 (line 2) and the vertical position to a negative value between –1 and –500 (line 3). The call to Move() in line 4 puts the apple (at index aplNum in the apple array) at some invisible point above the top edge of the graphics window using the two numbers xPos and yPos. This way, when the apples start falling, they appear at the top of the screen at random times; the apple that was placed at yPos = –100 appears sooner than the one placed at yPos = –500 because it has less distance to fall. As you’ll see in a moment, we’ll also call this subroutine when the player catches or misses an apple.

Step 4: Move the Apples

Now we’re ready to make it rain apples (give the cats and dogs a break). Add the code in Listing 15-7 to the program in the placeholder for the MoveApples() subroutine.

1 Sub MoveApples
2 For aplNum = 1 To MAX_APPLES
3 xPos = Shapes.GetLeft(apple[aplNum])
4 yPos = Shapes.GetTop (apple[aplNum])
5 Shapes.Move(apple[aplNum], xPos, yPos + 1)
6
7 CheckCatch() ' Checks if the apple landed in the cart
8 If (gotIt = 1) Then
9 Sound.PlayClick()
10 numCaught = numCaught + 1
11 SetApplePosition()
12 ElseIf (yPos > 320) Then
13 numMissed = numMissed + 1
14 SetApplePosition()
15 EndIf
16 EndFor
17
18 msg = "Caught: " + numCaught + " Missed: " + numMissed
19 Shapes.SetText(msgID, msg)
20 EndSub

Listing 15-7: The MoveApples() subroutine

In line 2, we start a For loop to drop five apples. We get the upper-left corner of each apple (lines 3–4), and then we move it down by 1 pixel (line 5). We then call CheckCatch() to see whether this apple was caught by the player (line 7). As you’ll see in a moment, this subroutine sets thegotIt flag to 1 if the player caught the apple; otherwise, it sets gotIt to 0. It’s okay if you miss an apple. You won’t hurt its peelings.

When CheckCatch() returns, we check the gotIt flag. If it’s 1 (line 8), that means the apple was caught by the player. In this case, we play a click sound, increment numCaught by 1, and call SetApplePosition() to reposition this apple and let it fall again (lines 9–11). On the other hand, ifgotIt isn’t 1, we check the apple’s y-position to see whether it went below the cart’s center, which means that the player missed it (line 12). In this case, we increase numMissed by 1 and call SetApplePosition() to reposition this apple and let it fall again (lines 13–14). If the apple was neither caught nor missed, then it’s falling and will be processed again the next time we call MoveApples().

After moving and checking the status of the five apples, we update the message that shows the number of caught and missed apples (lines 18–19).

Step 5: Catch or Miss

The last piece to add is the CheckCatch() subroutine in Listing 15-8.

1 Sub CheckCatch
2 xApple = Shapes.GetLeft(apple[aplNum]) + 32 ' Center point
3 yApple = Shapes.GetTop(apple[aplNum]) + 32 ' Bottom point
4 xCart = Shapes.GetLeft(cartImg) + 50 ' Center point
5 yCart = Shapes.GetTop(cartImg) + 40 ' Around the center
6 xdiff = Math.Abs(xApple - xCart)
7 ydiff = Math.Abs(yApple - yCart)
8 gotIt = 0 ' Assumes we didn't get the apple
9 If ((xdiff < 20) And (ydiff < 20)) Then
10 gotIt = 1 ' We got it
11 EndIf
12 EndSub

Listing 15-8: The CheckCatch() subroutine

This subroutine checks the distance between the center of an apple (whose index is given by aplNum) and the center of the cart. If the apple is within 20 pixels from the cart’s center, the subroutine sets gotIt to 1. Otherwise, it sets gotIt to 0.

The game is now complete, and you can play it! Maybe you’ll catch enough apples for an apple pie.

TRY IT OUT 15-6

Currently, the Catch Apples game runs forever. Think of a way to end the game, and then implement it. Can you think of some other ways to improve the game? Maybe you could give the player more points if they catch a big apple! What about the statement to move the cart inside theWhile loop? Can you move this statement to a new MouseMove event handler?

Programming Challenges

If you get stuck, check out http://nostarch.com/smallbasic/ for the solutions and for more resources and review questions for teachers and students.

1. Write a program that simulates rolling a die. Make the program roll a die 10,000 times and keep track of how many times each number appears. A sample run of the program follows. (Hint: use an array named dice that has six elements. If you get 1 in a roll, increment dice[1]. If you get 2, increment dice[2], and so on.)

Num Count Probability
1 1640 0.164
2 1670 0.167
3 1638 0.1638
4 1684 0.1684
5 1680 0.168
6 1688 0.1688

2. Open the file PinBall.sb in this chapter’s folder. This program simulates a pinball machine. As shown in the following illustration, the ball is dropped at the top of the machine. As it rolls down, it strikes fixed pins and bounces to the left or to the right in a random fashion. At the end, the ball lands in one of the seven pockets. The program drops the ball 10,000 times and counts the number of times it lands in each pocket. Study the program and explain how it works.

image

3. Open the file FlowerAnatomy.sb from this chapter’s folder. This program presents an educational game that quizzes the player on the parts of a flower (shown next). The player enters the letters to match the labeled parts of the flower and then clicks the Check button to check the answers. The program compares the user’s answers with the correct ones; then it shows you how the user did by placing a green check mark next to each correct answer and a red X next to each incorrect answer. Study the program and explain how it works.

image

4. Open the file USMapQuiz_Incomplete.sb from this chapter’s folder. The folder also contains the background image shown here (and the Yes and No images from the previous exercise). Complete the program to make this quiz work. Display the two-letter abbreviations for the nine states and provide nine text boxes to let the player match each state with its code.

image