Abstraction: Developing a Board Game

  1. Many board games are played on a square array of tiles. The goal now is to build a block that lets you draw boards with various numbers of tiles, fitting neatly on the stage. For example, draw-n-by-n-board(3) and draw-n-by-n-board(5) should draw these boards:

    3x3array-of-squares-on-stage5x5array-of-squares-on-stage

    The task is complex, so build specialists that accomplish part of the task and then put them together. For example, you might start by building:

    1. tile of size (size), which takes a size and draws one square.
    2. row of, which uses tile of size (size) to draw one row of tiles, like this: row of 5 tiles
    3. nxn-array-of-tiles(tiles-3,size-100), which uses row of to draw as many rows as needed—the same number of rows as there are tiles in each row.
    4. And, calculate tile size which can be used in nxn-array-of-tiles(tiles-3,size-calculated-to-fit-3-by-3) to make sure the entire board fits. (In the example, 3 tiles means three tiles on each row (and three rows), not three tiles altogether.)

    Test each block by itself before building a block that uses it.

    Your top-level board-drawing block, draw n-by-n board, might look something like this.

    draw an n-by-n board that fits within a 300 by 300 space centered on the stage.

  2. Abstraction: Why building the block clear and go to starting place, when all it contains is a few commands to assure that the sprite starts in the right place, pointed the right way, with its pen down, and that the stages is cleared?

    One purpose of hiding the details is to make your code clear, understandable, and easy to debug and update. Instead of seeing the details and wondering what they are for, you know exactly what this piece of code does just by reading the block's name.

    The same is true of tile of size (size). Instead of building that block, you could have used
    repeat 4, move, turn

    Hiding those details does two useful things. It makes your code easier to read. And if, some day, you decide to create the tiles differently—maybe with thicker borders or fills of random colors or by using stamp, from the Pen palette—you can make those changes in a logical place rather than looking all over your program to find where the change might be needed.
  3. Now build some tools you might need for a game.
    1. Build a predicate on the board? that uses your between? block to report true if the sprite is on the board, and reports false if the sprite is dragged completely off the board.
    2. Build which cell? that tells which cell the sprite has been dragged into. Here is one way to do it that uses two other blocks that specialize in reporting which column? and which row? the sprite is in.

      partial script for "which-cell?" reporter

      These blocks will, of course, need to know how many rows and columns there were, so they'll need the input n.

      There are many ways to write which row? and which column? You can, of course, use lots of if statements, but since the number of rows can change, it's hard to know how many to use. One convenient way is to divide the total size of the game board by the size of each cell. To use that result, you need to round down. round a number can do it, but it rounds to the nearest integer, up or down. The function floor of number always rounds down, making it easier to use. The floor function is in the same block as sqrt.
    3. Here's a block that you can use to test how well your other blocks work together.
      play on n-by-n board animation of play
      Try it out for boards of different sizes.
  1. Create a block move to tile (n) that takes a tile number as input and moves your sprite to the center of that tile. Because the location of tile 9 depends on how many tiles there are, your move to tile block will need to know the size of the board.
  2. Create mark tile (n) to move to the specified tile and stamp, from the Pen palette the sprite's shape on that tile to mark it as "taken."
  3. Create a second sprite with a different shape so that people can take turns, with their own sprite, stamping its mark on a tile.
  4. In Unit 3, you will learn ways to keep track of which tiles have been taken by which player. Then you can improve your game more. It could become like tic-tac-toe, or connect-four, or....