Brick Wall

Humpty Dumpty on brick wall

In this project, you will use abstraction to draw a brick wall.

Sample image of 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.
draw brick, length:(length) width:(width){set pen size to(width); move(length) steps}

  1. Talk with Your Partner The code below has more details than the picture above. Review it, and determine what it will do.
    draw brick, length:(length#) width:(width#){set pen color to (red); set flat line ends to (true); set pen size to (width); pen down; move(length) steps; pen up}
    Click here to load this file. Then save it to your Snap! account. Run the code. Does it do what you expected?
  2. Ordinarily, Snap! draws rounded ends on thick lines: line with round ends. That's often the best choice, and you can see why below. But for bricks, we want flat line ends: flat line ends, and so we'll use set (flat line ends) to 'predicate input slot' to turn on flat line ends.

    Square with flat line ends versus square with round line ends
    flat vs. rounded line ends
    set [video capture] to 'predicate input slot' with menu open showing: turbo mode, flat line ends, video capture, mirror video
: 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:
draw brick wall, rows: (7)
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:

    AAP-3.C
  1. Use draw brick to make blocks draw row A and draw row B.
  2. Read More Too much abstraction?

    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.

  3. 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?"
  4. Write and test the draw brick wall, rows: (7) 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?
  5. Save your work
    AAP-3.B
  6. Talk with Another Pair How do you think procedural abstraction manages the complexity of a program?
  1. Add more inputs to draw brick wall (and as needed to draw row A and draw row B) for:
    1. Number of bricks per row
    2. length and width of a brick
    3. Gap thickness
    draw brick wall, rows: (21) bricks per row: (11) brick length: (30) width: (10) gap thickness: (5)
    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.