CMU 15-112: Fundamentals of Programming and Computer Science
Homework 4 (Due Saturday 26-Sep at 8pm)



Note about spicy parts!
This hw will not have spicy problems. Instead, we will add some fun bonus ideas soon. Check back tomorrow for those!
Note about style grading:
Remember, we will grade this hw for style!
  1. Hw4 Game! [100 pts]
    Starting from hw4.py, write the "Hw4 Game". This is not really a fun game (sorry), but it contains some important elements that we could put together to make some fun games. We'll be making some of those fun games soon, perhaps this weekend!

    For now, write the "game" as shown in this video:
    Hint: be sure to watch the video!

    Here are the specific instructions:

    1. Start with an empty 10x10 grid filling the main 500x500 portion of a 510x540 canvas (where there's a 35-pixel margin at the top, and a 5-pixel margin on the bottom, left, and right). Display the text 'Hw4 Game!' centered in the top, along with the score, initially 0, at the far right, and labeled 'Score: 0'.

    2. If the user presses a digit N, the game restarts with an empty NxN grid and a score of 0 again, except if they press a digit smaller than 4, make it a (N+10)x(N+10) grid. So, for example, if they press 2, they get a 12x12 grid.

    3. A blue dot starts in the top-left square, sweeping to the right. When it reaches the right edge, it goes down one row and sweeps to the left. When it reaches the left edge, it goes down one row and sweeps to the right. It continues in this way to the bottom, at which point it starts over again at the top left. The dot should fill most, but not all, of the cell it is in, with a few pixels on each side.

      Hint: We strongly recommend that you store the location of the dot using its (row, col) and not its (cx, cy). In general, when dealing with items in a grid, (row, col) is more natural and will lead to clearer code with fewer bugs.

    4. For debugging purposes, make it so that when the user presses 'p' the game pauses. Each following press of 'p' toggles the paused state (from paused to unpaused, or from unpaused to paused). Also, pressing 's' when paused causes the game to take one step -- that is, to act as though a single timerFired event occurred. An example of how to do this is in the course notes!

    5. If the user presses 'r', the game resets, so the score goes back to 0, the dot goes to the top-left cell and is blue, and the explosion (see below) is invisible. Note that resetting should not change the dimensions of the grid.

    6. When the mouse is clicked, an explosion occurs centered on that mouse click (unless an explosion is already in progress, in which case you simply ignore the second click). The explosion is drawn as a growing orange circle. It starts with a radius of 10 and grows by 10's until the radius is 50, then the explosion goes away.

    7. If the explosion intersects the blue dot at any point, then the explosion goes away, the user scores (explosionRadius//10) points (so you want this to happen when the explosion is at its largest), and the blue dot turns red and goes back to the top-left corner heading right.

      Hint: You may want to add a value to your model that you set to True when the explosion is visible, and you set it to False when it is not visible.

    8. If the explosion intersects the red dot at any point, then the explosion goes away, the user scores 10 points, and the red dot turns blue and goes back to the top-left corner heading right.

    9. If the explosion never hits the dot, then the user loses 1 point, except the score can never be negative.

    Here are some helper functions we thought were very useful in our sample solution. You are not required to write these functions, but you might find them helpful:

    1. getCellBounds(app, row, col)
      This was mostly the same as from the notes, but adjusted to account for topMargin being different from other margins.

    2. explosionIntersectsDot(app)
      This function tests whether the explosion is currently visible, and if so, if it intersects the moving dot.

    3. moveDot(app)
      This function moves the dot to the right or left by one column, and then if needed moves it down a row, and then if it's beyond the last row, moves it back to the top-left cell.

    4. growExplosion(app)
      This function does nothing if the explosion is not visible. But if the explosion is visible, this makes it bigger. Then it checks if the explosion intersects the dot (by calling one of the helper functions listed above!), and if so, does the required steps (adjust score, change visibility of explosion, etc). Finally, it checks if the explosion got so big that it should be made not visible (and if so, deducts 1 from the score, unless the score would go negative).

    5. doStep(app)
      This function takes one step for timerFired. We place this in its own function for two reasons: first, it makes it easy for timerFired to ony call the function if the game is not paused. Second, it also makes it easy for keyPressed to call the function when the user presses the 's' key. See the bouncing square" example for more details. Anyhow, this function does two things: it moves the dot and then it grows the explosion. Each of these just requires calling the right helper function from above!

    6. Drawing helper functions
      We found it helpful to use several drawing helper functions. So this is what our redrawAll looks like:
      def redrawAll(app, canvas):
          drawTitleAndScore(app, canvas)
          drawGrid(app, canvas)
          drawDot(app, canvas)
          drawExplosion(app, canvas)
      

    7. Other helper functions
      We included a couple other helper functions as well. You should feel free to add any additional helper functions that you think would be useful.

  2. Hw4 Bonus [up to 4 pts]
    Here are some fun ideas here that you can write for a small amount of bonus. Please try these for the challenge and the learning, and not just for the points. Also, remember that bonus is also solo!

    If you are going to attempt the bonus, you should first watch this helpful video:
    Hint: be sure to watch the video!

    1. Pink Cells [1.5 pts]
      As indicated in the video...
      • When an explosion starts, the cell in which the user clicks turns pink. Remember that you cannot use lists this week (so you'll have to find some other way to keep track of which cells are pink!).
      • Also, you cannot start an explosion from a pink cell. So clicks in pink cells are ignored.
      • Hint: while lists are disallowed here, strings are allowed...

    2. Gray Cells [2.5 pts]
      As indicated in the video...
      • As the explosion grows, any cell the explosion intersects with turns gray, unless it is already pink. You can still start an explosion on a gray cell.
      • Also, this feature is initially off, but if the user presses 'g', for 'gray cells', then this feature is enabled.
      • Remember that lists are disallowed this week!
      • Hint: To intersect a circle and a rectangle, find the x value in the rectangle that is closest to the circle's left or right edge. Then find the y value in the rectangle that is closest to the circle's top or bottom edge. Then see if that (x,y) point is in the circle.