Partilhar via


Solution - Experienced Challenge 9: And They’re Off!

This was one challenge that we actually had to think about. (Does that mean we didn’t think about the other challenges? Um, well ….) That’s because we were initially tempted to try and use Microsoft Office PowerPoint’s animation capabilities to try and create a very smooth, very realistic-looking race. But the more we thought about it, the more we realized that doing something like that was going to take a lot of thinking. Seeing as how thinking isn’t really our specialty, we thought better of it and decided to use a more brute force approach: we’d pick a horse, move it a little closer to the finish line; pick a horse, move it a little closer to the finish line; and so on. It’s not as elegant, but it works. And, as you’re about to see, it works with a minimal amount of code:

Private Sub CommandButton2_Click()

    Set myDocument = ActivePresentation.Slides(1)

 

    Do While True

        If myDocument.Shapes(6).Left > 525 Then

            MsgBox "Blue wins!"

            Exit Sub

        End If

 

        If myDocument.Shapes(7).Left > 525 Then

            MsgBox "Red wins!"

            Exit Sub

        End If

 

        If myDocument.Shapes(8).Left > 525 Then

            MsgBox "Green wins!"

            Exit Sub

        End If

 

        If myDocument.Shapes(9).Left > 525 Then

            MsgBox "Brown wins!"

            Exit Sub

        End If

 

        Randomize

        intDie = Int(Rnd() * 4) + 1

 

        Randomize

        intMover = Int(Rnd() * 10) + 1

 

        Select Case intDie

            Case 1

                myDocument.Shapes(6).IncrementLeft intMover

            Case 2

                myDocument.Shapes(7).IncrementLeft intMover

            Case 3

                myDocument.Shapes(8).IncrementLeft intMover

            Case 4

                myDocument.Shapes(9).IncrementLeft intMover

        End Select

 

        DoEvents

    Loop

End Sub

 

We start things out by creating an object reference to slide 1 in our presentation. (Which, now that we think about it, is the only slide in our presentation.) That’s what this line of code is for:

Set myDocument = ActivePresentation.Slides(1)

Believe it or not, that’s it for preparation and setup; at this point, we’re ready to start racing.

To conduct the race itself, we set up a Do Loop designed to run as long as True is equal to True. (And yes, that means if True is ever equal to False then our race will end prematurely. But that was a risk we were willing to take.) Inside the loop we have a series of four code blocks, code blocks designed to see whether any of our four horses have hit the finish line. For example, the block of code that tracks the progress of the blue horse (Shape 6) looks like this:

If myDocument.Shapes(6).Left > 525 Then

    MsgBox "Blue wins!"

    Exit Sub

End If

 

All we’re doing here is seeing if the left edge of our horse (as determined by the Left property) is greater than or equal to 525. If it is, that means that the blue horse has crossed the finish line and is the winner. In turn, we display the message “Blue wins!” and then exit the subroutine, a move that also brings the race to a close.

Note. How did we know that 525 was the magic number that would mean a horse has crossed the finish line? That was actually pretty easy: we simply placed one of the horses on the finish line and then wrote a temporary subroutine that displayed the value of the horse’s Left property.

And yes, as far as we know that is the way they determine the winner in real horse races.

These first four blocks of code tell us which horse crossed the finish line first. However, how do we actually get those horses to the finish line? Well, our solution was to move a random horse a random amount, and to repeat this process until one of the horses crosses the finish line. To help us move a random horse a random amount we execute these lines of code:

Randomize

intDice = Int(Rnd() * 4) + 1

 

Randomize

intMover = Int(Rnd() * 10) + 1

 

In the first two lines we’re rolling a four-sided die in order to determine which horse we’re going to move. (How in the world could you have a die with just four sides? You know, we never thought of that ….) To simulate the rolling of a four-sided die (we’d prefer to use the word “dice” as well, but our editor insists the dice is plural and die is singular) we first call the Randomize function; this “reseeds” the random number generator and helps ensure that we actually get a random number. (If you don’t call the Randomize function you run the risk of getting the same number each time you roll the dice. Uh, die.)

In the second line, we use the Rnd function to generate a random number between 1 and 4, inclusive. (We also use the Int function to ensure that we get an integer value.) The net effect? We’re going to get a 1, 2, 3, or 4, one number for each of our horses.

In the next two lines we generate a random number that determines the number of points we’re going to move the designated horse. In this case, we’re going to move the horse 1 point, 10 points, or any number of points in between.

That brings us to this block of code:

Select Case intDice

    Case 1

        myDocument.Shapes(6).IncrementLeft intMover

    Case 2

        myDocument.Shapes(7).IncrementLeft intMover

    Case 3

        myDocument.Shapes(8).IncrementLeft intMover

    Case 4

        myDocument.Shapes(9).IncrementLeft intMover

End Select

 

What we’ve done is set up a Select Case block that enables us to grab the desired horse and move him (or her; it’s hard to tell the difference with clip art horses) the correct number of points. As you can see, there’s nothing particularly complicated about the code. If our die came up with a 1 we move the blue horse (Shape 6) the correct number of points. (That number, of course, is stored in the variable intMover.) If our die came up with a 2 we move the red horse (Shape 7). If our die came up with a 3 – well, you get the idea.

After moving one of the horses we call DoEvents; this helps ensure that we actually see the race unfold onscreen. Otherwise we’d click the button, the subroutine would run, the horses would move to their final position and only then would the screen change. It’s way faster, true. But not nearly as exciting.

And then we simply pop back to the top of the loop and repeat the process until we have a winner.

Just like the Kentucky Derby.