When you put together four walls, you have a room! In this chapter, you’ll create the buildRoom() function, which calls buildWall() four times to construct a room like the one shown in Figure 12-1. This chapter is short and sweet because you did most of the coding work when you wrote the buildWall() function in Chapter 11. When you’re done creating the buildRoom() function, you’ll be able to use it to build complex structures, such as a castle!
Figure 12-1: A 5 × 6 × 4 room built of stone bricks
Let’s design an algorithm that takes length, width, and height values to create rooms of any size. We’ll put the code for this algorithm inside a function named buildRoom() in the hare module. For example, if the turtle needs to build a room that is three blocks long and four blocks wide, it could build four walls like those shown in Figure 12-2. The turtle starts from the bottom-left corner of the room and then builds walls clockwise.
Figure 12-2: A top-down view of a turtle building a 3 × 4 room. The turtle is facing the same direction as the white arrow when it starts building.
Because walls overlap at the corners of a room, the length and width of a room are different from the dimensions of its walls. For example, to build a 3 × 4 room like the one in Figure 12-2, you can’t just build two walls of length three and two walls of length four because the corners would overlap. To properly size the wall lengths of a room, you must account for the corners. Look at the size of each wall in Figure 12-3, which shows a 3 × 4 room and a 4 × 6 room.
Figure 12-3: A 3 × 4 room (left) and a 4 × 6 room (right)
As you can see, the room that is 3 × 4 in size is made up of two walls that are two blocks long and two walls that are three blocks long. The room that is 4 × 6 in size is made up of two walls that are three blocks long and two walls that are five blocks long.
Notice the pattern of our algorithm. The four walls are of two different sizes: one size is the width of the room minus one, and the other size is the length of the room minus one. The algorithm will call the buildWall() function that we created in Chapter 11. The turtle begins in the lower-left corner, as shown in Figure 12-3, and builds the wall on the left side of the room (shown in red). Then, the algorithm tells the turtle to turn right and build the wall at the top of the room (shown in blue). The turtle turns right again, builds the red wall on the right side of the room, turns right, and builds the blue wall at the bottom of the room. When the turtle is done making all four walls, it ends up back where it started. By using this pattern in its algorithm, the buildRoom() function can make rooms of any size.
We’ll put the buildRoom() function in the hare module, just as we did with the buildWall() function, so other programs can use it. From the command shell, run edit hare. Move the cursor to the bottom of the file and continue the code by entering the following:
hare
...snip...
110. -- buildRoom() constructs four walls
111. -- and a ceiling
112. function buildRoom(length, width, height)
113. if hare.countInventory() < (((length - 1) * height * 2) +
((width - 1) * height * 2)) then
114. return false -- not enough blocks
115. end
116.
117. -- build the four walls
118. buildWall(length - 1, height)
119. turtle.turnRight()
120.
121. buildWall(width - 1, height)
122. turtle.turnRight()
123.
124. buildWall(length - 1, height)
125. turtle.turnRight()
126.
127. buildWall(width - 1, height)
128. turtle.turnRight()
129.
130. return true
131. end
After you’ve entered all of these instructions, save the program and exit the editor. You can also download this module by running pastebin get wwzvaKuW hare.
Before the buildRoom() function can create a room, the turtle must first check that it has enough building blocks in its inventory. We’ll need to calculate the number of blocks needed for all four walls of the room. We calculated the number of blocks needed for a single wall on line 67 of hare as:
length * height
But this time the length of the wall is one block shorter than the length of the room. The first of the four walls should be length – 1 blocks long, so our calculation needs to be:
(length – 1) * height
And because the turtle will build two of these walls, we multiply this number by 2:
(length – 1) * height * 2
The other two walls will be one block shorter than the width of the room, which is width – 1 blocks in length, so we add the blocks for those walls to the calculation, as follows.
((length – 1) * height * 2) + ((width – 1) * height * 2)
This is the final formula for the number of blocks a room will require, which we’ll use in the buildRoom() function.
Line 113 calls hare.countInventory() to find out how many blocks are in the turtle’s inventory. If this number is less than the number of blocks needed for the room, which we calculated the formula for in the preceding section, the execution moves to line 114, which returns false from buildRoom(). The code that called buildRoom() can use this return value to learn that the room was not built.
hare
110. -- buildRoom() constructs four walls
111. -- and a ceiling
112. function buildRoom(length, width, height)
113. if hare.countInventory() < (((length - 1) * height * 2) +
((width - 1) * height * 2)) then
114. return false -- not enough blocks
115. end
Otherwise, the execution continues past this code block. Because there are enough blocks to build the room, the turtle calls buildWall(). Line 118 builds the first wall of the room.
hare
118. buildWall(length - 1, height)
After building the wall from the bottom up, the buildWall() function moves the turtle back down to the ground. If the turtle is building a 3 × 4 room, after running line 118, the room will look like the top-down view in Figure 12-4.
Figure 12-4: The 3 × 4 room after building the first wall
Before the turtle can build the second wall, it must turn right. The call to turtle.turnRight() on line 119 makes the turtle face the correct direction so it can build the next wall on line 121.
hare
119. turtle.turnRight()
120.
121. buildWall(width - 1, height)
Note that this wall’s length is width – 1, where width is the width of the room. If the turtle is building a 3 × 4 room, the room will look like Figure 12-5 after line 121 executes.
Figure 12-5: The 3 × 4 room after building the second wall
Similarly, lines 124 to 128 build the other two walls:
hare
122. turtle.turnRight()
123.
124. buildWall(length - 1, height)
125. turtle.turnRight()
126.
127. buildWall(width - 1, height)
128. turtle.turnRight()
129.
130. return true
131. end
After this code executes, the room is complete and the buildRoom() function returns true on line 130 to tell the code that called buildRoom() that the room was successfully built. The turtle will be back at its starting location and facing its original direction, but it will be on top of the first wall it built, as shown in Figure 12-6.
Figure 12-6: With the 3 × 4 room completed, the turtle returns to its starting point.
The end statement on line 131 ends the buildRoom() function’s code block.
In Chapter 11, you made a buildwall program that calls hare.buildWall() so the player can easily build a wall from the command shell. We’ll make a similar buildroom program to call hare.buildRoom(). From the command shell, run edit buildroom and enter the following code:
buildroom
1. --[[Room Building program by Al Sweigart
2. Builds a room of four walls.]]
3.
4. os.loadAPI('hare')
5.
6. -- handle command line arguments
7. local cliArgs = {...}
8. local length = tonumber(cliArgs[1])
9. local width = tonumber(cliArgs[2])
10. local height = tonumber(cliArgs[3])
11.
12. if length == nil or width == nil or height == nil or cliArgs[1] == '?' then
13. print('Usage: buildroom <length> <width> <height>')
14. return
15. end
16.
17. print('Building...')
18. if hare.buildRoom(length, width, height) == false then
19. error('Not enough blocks.')
20. end
21. print('Done.')
After you’ve entered all of these instructions, save the program and exit the editor. You’ll also need the hare module, which you can download by running pastebin get wwzvaKuW hare.
Like the buildwall program, the buildroom program relies mostly on a function in the hare module. First, it gathers the command line arguments from {...}, displaying a usage message if needed, and then it calls hare.buildRoom(). It’s almost identical to the buildwall program except that we use the hare.buildRoom() function instead of hare.buildWall().
After placing the turtle and putting 72 stone brick blocks (or any other kind of building block) into its inventory, right-click the turtle to open its GUI. From the command shell, run buildroom 5 6 4 to watch the turtle build a room five blocks long, six blocks wide, and four blocks high.
With the buildwall and buildroom programs, you can quickly build tall castles or other structures without ever placing a single block! You can craft multiple turtles running either the buildRoom program or the buildWall program to build structures in parallel, as shown in Figure 12-7.
Figure 12-7: Turtles constructing a castle by running the buildwall and buildroom programs
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 buildroom and then download it by running pastebin get U0WVM4wg buildroom.
Although there were no programming concepts to learn in this chapter, it was good practice for developing algorithms. The more experience you get turning vague ideas of what you want the turtle to do into actual code, the better a programmer you’ll be.
You created a wall-building function in Chapter 11 and a room-building function in this chapter. In Chapter 13, you’ll develop an algorithm to build floors and ceilings.