5
MAKING A BETTER DANCER

image

The dancing program in Chapter 4 was fairly simple and always instructed your turtle to do the same dance moves. In this chapter, we’ll create a new program that makes the turtle do a variety of random moves. While creating this program, you’ll learn about while loops, the Boolean and nil data types, and how to run or skip code blocks based on conditions.

WRITING A BETTER DANCE PROGRAM

Run the text editor by entering edit mydance2 into the command shell. In the text editor, enter the following lines of code, but don’t type the line numbers because they’re only used here for reference:

mydance2

 1. --[[A Better Dance program by Al Sweigart
 2. Make the turtle dance better!]]
 3.
 4. local isUp = false
 5. local isBack = false
 6. local danceMove
 7. print('Hold Ctrl-T to stop dancing.')
 8. while true do
 9.   danceMove = math.random(1, 5)
10.
11.   if danceMove == 1 then
12.     -- turn left
13.     print('Turn to the left!')
14.     turtle.turnLeft()
15.
16.   elseif danceMove == 2 then
17.     -- turn right
18.     print('Turn to the right!')
19.     turtle.turnRight()
20.
21.   elseif danceMove == 3 then
22.     -- forward/back moves
23.     if isBack then
24.       print('Move forward!')
25.       turtle.forward()
26.       isBack = false
27.     else
28.       print('Move back!')
29.       turtle.back()
30.       isBack = true
31.     end
32.
33.   elseif danceMove == 4 then
34.     -- up/down moves
35.     if isUp then
36.       print('Get down!')
37.       turtle.down()
38.       isUp = false
39.     else
40.       print('Get up!')
41.       turtle.up()
42.       isUp = true
43.     end
44.
45.   else
46.     -- spin around
47.     print('Spin!')
48.     for i = 1, 4 do
49.       turtle.turnLeft()
50.     end
51.   end
52. end

After you’ve entered all these instructions, press CTRL, make sure [Save] is selected, and press ENTER. Then quit the editor by pressing CTRL, selecting [Exit], and then pressing ENTER.

RUNNING THE MYDANCE2 PROGRAM

After exiting the editor, run the mydance2 program in the command shell. Press ESC shortly after running the program and watch the turtle do random dance moves. This program will continue running until you terminate it by holding down CTRL-T for a full second. When you’ve stopped the program, return to the command prompt to see output similar to the following:

> mydance2
Hold Ctrl-T to stop dancing.
Spin!
Get down!
Move back!
Move forward!
Spin!
Get up!
Turn to the left!
Terminated

Figure 5-1 shows the turtle doing its spin move.

image

Figure 5-1: The spinning turtle

If you get errors when running this program, carefully compare your code to the code in this book to find any typos. If you still cannot fix your program, delete the file by running delete mydance2 and then download it by running pastebin get QAH0uYqS mydance2.

The mydance2 program uses Booleans, nil, while loops, if statements, and more. Let’s look at it step by step.

THE BOOLEAN DATA TYPE

The program’s first couple of lines contain comments that explain what the program is and who wrote it. Lines 4 and 5 are assignment statements:

mydance2

 1. --[[A Better Dance program by Al Sweigart
 2. Make the turtle dance better!]]
 3.
 4. local isUp = false
 5. local isBack = false

The values assigned to the isUp and isBack variables are false and false. You can tell these aren’t strings because they don’t start and end with single quotes. Rather, these are Boolean values, which are another data type. Boolean values, or Booleans, are always either true or false. (“Boolean” is capitalized, unlike “string” or “number,” because it’s named after the 19th-century mathematician George Boole.)

Some of the turtle dance moves involve moving up and also moving backward. To prevent the turtle from moving too far away from its original position, we use the isUp and isBack variables to keep track of whether the turtle has already moved up or back. Although we set up these variables at the beginning of the program, we won’t use them until later in the program.

THE NIL DATA TYPE

Notice that line 6 declares the danceMove variable without assigning it any value:

mydance2

 6. local danceMove

Even though it isn’t written in the code, danceMove is automatically assigned a value called nil. The nil value is the only value in the data type, which is also called nil. This value represents no value or the lack of a value. Any local statement that doesn’t assign a value to the declared variable assigns nil. Line 6 is the same as writing local danceMove = nil.

LOOPING WITH WHILE LOOPS

In addition to the for loop, another kind of loop is the while loop. A while loop repeatedly executes a block of code as long as some condition is true. A condition is an expression that can be true or false. The condition is checked as part of a while statement, and the block of code that it executes is the action we want it to do when the condition is true.

Line 7 displays a reminder to the player that they can terminate the program by holding down CTRL-T, and line 8 is the while statement:

mydance2

 7. print('Hold Ctrl-T to stop dancing.')
 8. while true do
 9.   danceMove = math.random(1, 5)

The while statement consists of the while keyword, followed by a condition (in this case, true) and the do keyword to mark the beginning of the block. The instructions are inside the block of code starting at line 9. The end of the block is marked with the end keyword. (Because the block is long, this code snippet shows only the first line of the block and doesn’t show the end keyword, which is on line 31.) When the execution reaches the end keyword, it moves to the top of the block and checks the condition again. It continues looping through the code as long as the condition evaluates to true. If the condition is ever false, the execution moves past the while loop’s block.

Figure 5-2 shows an example while loop.

image

Figure 5-2: The execution of a while loop

The while loop continues to loop as long as the condition isn’t false or nil. Many conditions use comparison operators, such as coal < 10 in this example, which tests if the value in the coal variable is less than 10. (You’ll learn more about comparison operators later in this chapter.) Conditions that use comparison operators can evaluate to true or false. If a condition evaluates to a number or string value (for example, some functions will return number values), it is considered the same as being true.

Remember that an expression can be made up of just a single value, in which case the expression evaluates to itself. Recall in Chapter 2 that when you entered the value 42 into the Lua shell, it evaluated to the value 42. The condition on line 8 of the mydance2 program is just the true value. Because this expression always evaluates to true, the while loop will loop forever until the user stops it by terminating the program. This kind of never-ending loop is called an infinite loop. We use an infinite loop in this program because we want the turtle to keep dancing until we hold down CTRL-T to terminate the program.

The turtle has five different dance moves, and the program randomly chooses one based on the value in danceMove. Line 9 calls the math.random() function to create a random number between 1 and 5, and it stores this random number in the danceMove variable.

MAKING DECISIONS WITH IF STATEMENTS

Recall that the flow of execution is the order in which lines of code are executed. The normal flow of execution in our programs is from the top down. Loops such as for loops or while loops are considered flow control statements because they can make the execution move back up to the beginning of the loop.

An if statement is another kind of flow control statement. Line 11 uses an if statement, which executes a block of code only if its condition evaluates to true, as in the following.

mydance2

11.   if danceMove == 1 then
12.     -- turn left
13.     print('Turn to the left!')
14.     turtle.turnLeft()
15.
16.   elseif danceMove == 2 then

An if statement is made up of the if keyword followed by a condition and the then keyword, which marks the beginning of the code block. Line 12 starts the instructions inside the code block that should execute if the condition is true. An elseif, else, or end keyword marks the end of the if statement’s code block. In this case, on line 16 the block ends with the elseif keyword, which you’ll learn more about shortly.

The condition on line 11 also contains code that will be unfamiliar to you because it uses a comparison operator. To better understand how if statements work, let’s look at comparison operators next.

COMPARING TWO VALUES WITH COMPARISON OPERATORS

Comparison operators check a condition by comparing two values and evaluate to a Boolean true or false value. The condition on line 11 is danceMove == 1, which includes the “is equal to” (==) comparison operator. The == operator checks whether the values before it and after it are equal to each other, and returns true if they are or false if they’re not. If the danceMove variable is equal to the value 1, the code on lines 12, 13, and 14 (between the then and elseif keywords) executes. This prints Turn to the left! on the GUI and makes the turtle turn left.

Be careful not to mix up the “is equal to” operator (==) and the assignment operator (=). The comparison operator == checks whether the values on either side of the operator are the same and returns true if they are, whereas the assignment operator = assigns the value on the right side of the operator to the variable on the left side of the operator.

Table 5-1 describes Lua’s comparison operators.

Table 5-1: Comparison Operators in Lua

Comparison operator

Description

==

Is equal to

~=

Is not equal to

>

Is greater than

<

Is less than

>=

Is greater than or equal to

<=

Is less than or equal to

Let’s experiment by entering the following operators into the Lua shell:

lua> 2 == 2
   true
   lua> 4 == 2 + 2
   true
lua> 2 ~= 3
   true
   lua> 2 < 3
   true
   lua> 3 < 3
false
   lua> 3 > 2
   true
   lua> 2 >= 2
   true
lua> 2 + 9 * 2 == (25 – 15) * 2
   true

As you can see, an expression with comparison operators always evaluates to a Boolean true or false value. The “is equal to” operator (==) compares two values and returns true if they are equal . The “is not equal to” operator (~=) returns true if they aren’t equal . The “less than” (<) and “greater than” (>) operators work just like they do in math class. They compare whether the value next to the open part of the operator is bigger than the value on the other side of the operator and return true when that is the case. But if the values on both sides of the operator are equal to each other or if the value next to the open part of the operator is smaller than the value on the other side of the operator, the comparison will return false .

The “greater than or equal to” (>=) and “less than or equal to” (<=) operators will do the same comparison as the less than and greater than operators but will return true if the values on both sides of the operator are equal to each other.

You can also use comparison operators to compare expressions, such as 2 + 9 * 2 == (25 – 15) * 2 . When you see this type of expression, you can evaluate it one piece at a time, as shown here:

image

In the end, the expression will always evaluate to just true or false.

MAKING ALTERNATE DECISIONS WITH ELSEIF STATEMENTS

You can add an elseif statement to the end of an if block. In fact, an elseif statement works almost exactly like an if statement. They both include their own keyword (if or elseif), a condition, and the then keyword, which marks the beginning of the block. The execution instructions are inside the code block, and an elseif, else, or end keyword marks the end of the block.

The elseif statement must be paired with an if statement and only executes its code block when the if statement’s condition is false but the elseif statement’s condition is true. In plain English it means, “If this is true, do this, or else if this other thing is true, do that.” If neither condition is true, neither block executes and the next part of the code executes.

Lines 17 to 19 execute if the condition in line 11, danceMove == 1, is false, and the condition in line 16, danceMove == 2, is true:

mydance2

16.   elseif danceMove == 2 then
17.     -- turn right
18.     print('Turn to the right!')
19.     turtle.turnRight()
20.
21.   elseif danceMove == 3 then

If the danceMove variable is set to 2 on line 9, the program prints Turn to the right! and turns the turtle to the right.

NESTED CODE BLOCKS

Another elseif statement is on line 21 for when danceMove is set to 3. Inside the elseif statement’s block is another if statement on line 23 and its block, which starts at line 24 and ends at line 26. Putting a block inside another block of code is called nesting. Notice that because lines 24 to 26 are inside a new block, the code is indented by two more spaces. This indentation isn’t required, but it does make the code easier to read.

mydance2

21.   elseif danceMove == 3 then
22.     -- forward/back moves
23.     if isBack then
24.       print('Move forward!')
25.       turtle.forward()
26.       isBack = false

The if statement nested in the elseif block executes only when the elseif statement’s condition is true. We need a nested if statement because the dance move on line 21 is different from the others. This dance move makes the turtle move forward, but we don’t want the turtle to keep moving forward; otherwise, it might wander away! So we check whether the turtle has already moved forward and, if it has, move the turtle backward instead. We do this using the nested if statement, which uses the isBack variable in its condition. We set up the isBack variable at the start of the program and use it to store a Boolean that indicates whether the turtle is back to where it originally started.

Remember that a variable can be used in an expression because it evaluates to the value inside it. So if isBack is set to true, then the condition on line 23 is true and lines 24 to 26 execute, which moves the turtle forward and sets isBack to false.

MAKING A DECISION . . . OR ELSE!

Line 27 is an else statement, which ends the if statement’s block. The block after an else statement executes if all of the previous if and elseif conditions are false. In plain English it means, “If this is true, do this, or else if it’s false, do that.” In this case, the else statement is paired with the if statement on line 23 but not with the if or elseif statements on lines 11, 16, and 21. The reason is that the else statement is also nested in the elseif statement on line 21, meaning that it executes only if the condition on line 21 is true.

Lines 28 to 30 execute if the condition on line 23 is false. The block after an else statement ends when the program reaches an end keyword. The else block runs only if all the previous if and elseif statements are false, so it has no condition.

mydance2

27.     else
28.       print('Move back!')
29.       turtle.back()
30.       isBack = true
31.     end

If isBack is set to false, lines 28 to 30 execute, which prints Move back! on the turtle’s GUI, moves the turtle backward, and then sets isBack to true.

Notice that if isBack is true, the program sets it to false. If isBack is false, the program sets it to true. As a result, each time danceMove is set to 3 the turtle alternates between moving forward and backward. So the turtle never goes too far backward or too far forward and always moves between two positions.

MOVING UP AND DOWN

Line 33 is an elseif statement that checks whether danceMove is equal to 4. Notice that because the if statement on line 23 (if isBack then) is nested in the previous elseif block, the program will skip it if the execution moves to the elseif statement on line 33. This means that the elseif statement on line 33 is paired with the if statement on line 11.

mydance2

33.   elseif danceMove == 4 then
34.     -- up/down moves
35.     if isUp then
36.       print('Get down!')
37.       turtle.down()
38.       isUp = false
39.     else
40.       print('Get up!')
41.       turtle.up()
42.       isUp = true
43.     end

The code on lines 35 to 43 is similar to the code on lines 23 to 31. If danceMove is 4, the nested if statement on line 35 runs its block if isUp is true. Otherwise, the else statement on line 39 runs its block.

The program uses isBack and isUp to keep track of what kind of move to make when danceMove is 3 or 4. The if, elseif, and else statements direct where the execution of the program goes based on these three variables.

Figure 5-3 shows the turtle moving up and down.

image

Figure 5-3: The turtle moving up and down

SPINNING ALL AROUND

Another else statement is on line 45, and it’s paired with the if statement on line 11. If every condition for the if and elseif statements on lines 11, 16, 21, 33, and 45 are false, the block after the else statement will run:

mydance2

 8. while true do
 9.   danceMove = math.random(1, 5)
10.
11.   if danceMove == 1 then

      ...snip...

45.   else
46.     -- spin around
47.     print('Spin!')
48.     for i = 1, 4 do
49.       turtle.turnLeft()
50.     end
51.   end
52. end

In this block (which ranges from lines 46 to 51), the turtle prints Spin! to its GUI and enters a loop that makes the turtle turn left four times. This spin leaves the turtle facing its original direction.

Lines 50, 51, and 52 are all end statements. By looking at the indentation, we can match these end statements with the statements they’re paired with, as follows:

  • Line 50 is the end of the block started by the for statement on line 48.
  • Line 51 is the end of the block started by the else statement on line 45.
  • Line 52 is the end of the block started by the while statement on line 8.

Remember that one and only one of the blocks following the if, elseif, and else statements executes. The execution skips the rest. So after one of these blocks is run, the execution moves past the end statement on line 51. The next line is the end statement for the while loop, so the execution moves back to line 8 and rechecks the while statement’s condition. Because this condition is just the value true, the execution will always reenter the block and do another random dance move.

Due to the infinite loop, there is no natural way for this program to end. The turtle will keep dancing forever until you hold down CTRL-T to terminate the program.

BONUS ACTIVITY: WATCHTURTLE

Put your turtle on guard duty. Using loops, make the turtle march forward 10 steps and then turn around and march back. Put all of this code into a loop to make the turtle continue marching until the player presses CTRL-T to terminate the program (or until the turtle runs out of fuel).

WHAT YOU LEARNED

In this chapter, you learned about while loops and conditions, which allow you to run the same code repeatedly. You also learned how to use conditions with if, elseif, and else statements and comparison operators to execute or skip code. These flow control statements allow you to program software to make decisions that direct how your turtle behaves. Comparison operators evaluate to one of the two Boolean values: true or false. The nil data type just has one value, nil, which represents a lack of value.

Of course, if you want smarter turtles, you’ll have to use more than just a few if statements and loops in your code. But you have a good start with your dancing turtle!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.107.90