Page 4: Brick Wall
Unit 3, Lab 1, Page 4
In this project, you will use abstraction to draw a brick wall.
Drawing One Brick
A picture of a brick is just a rectangle with a brick red color. However, there’s no draw rectangle
block in Snap!. One way to draw one is by thinking of a rectangle as a very thick line. Here’s the idea:
Any good programming language might have many tools for drawing and moving, but it wouldn’t make sense to have special tools for drawing bricks because most programs don’t involve bricks. That’s the sort of tool you make yourself when you need it.
-
The code below has more details than the picture above. Review it, and determine what it will do.
Run the code. Does it do what you expected?
Ordinarily, Snap! draws rounded ends on thick lines: . That’s often the best choice, and you can see why below. But for bricks, we want flat line ends: , and so we’ll use to turn on flat line ends.
flat vs. rounded line ends
: Abstraction
AAP-3.B.1, AAP-3.B.5
As you learned in Unit 1 Lab 2 Page 2: Making Programs Talk, procedural abstraction is the process of developing a program by breaking up a large problem into smaller sub-problems.
Creating a draw brick
block lets you think in terms of a procedure with a name related to the problem you are solving. This makes your code easier to read, and once you’ve coded and debugged the block, you don’t need to think about how it works each time you use it. That’s the beauty of procedural abstraction.
Using Modularity
You’d like the “top level” block to be something like this:
Getting there involves modularity.
AAP-3.B.2, AAP-3.B.3
Modularity is the process of breaking a problem into smaller pieces. Modularity is a form of procedural abstraction.
There are two kinds of rows, so you’ll make blocks that specialize in each:
- Row A:
- Row B:
-
Use
draw brick
to make blocks and . -
The two kinds of rows should be exactly the same length. Your first try at drawing Row B is probably a little too long. If so, debug it.
Debug by thinking about what you are trying to accomplish, not about your code. For example…
- Should Row B have different-size bricks, different-size gaps, or just different-size bricks on the end?
- If you’re not sure, try all the possibilities and see which looks right in the finished wall.
- Or think “What would make the most sense in a real brick wall?”
-
Write and test the block.
You might want to use the
odd?
predicate from your U2L4-MathLibrary. You learned about exporting and importing blocks on Unit 2 Lab 3 Page 1: What’s a Predicate? - How do you think procedural abstraction manages the complexity of a program?
AAP-3.C
It’s possible to go overboard on abstraction and build so many blocks that your program is just as cluttered as it would be without the custom blocks. But it can be useful to make a custom block even when its definition is just one built-in block. For example, to draw the mortar between blocks (the white gaps), you can just use move (4) steps
, but it might make sense to define a draw mortar
block that uses move
inside it.
Why? You might later decide that four steps is the wrong thickness for mortar and you’d rather have five. Or you might want the mortar to be mortar-colored, slightly gray. With many move (4) steps
instructions scattered through your program, you would have to find and change each one. To make matters worse, your complete project might have move
blocks that aren’t about mortar. But with a draw mortar
block, you can change just its definition, and all the mortar in your picture will be changed.
AAP-3.B
-
Add more inputs to
draw brick wall
(and as needed todraw row A
anddraw row B
) for:- Number of bricks per row
- length and width of a brick
- Gap thickness
Add these extra inputs one at a time, not all at once! When you modify the length of a brick, that should also change the length of an end brick for row B. When you modify the gap thickness, that should also change the distance between the rows.