15-112 Fall 2015 Homework 7
Both parts are due Sunday, 18-Oct, at 10pm

Read these instructions first!
Hw7c: Tetris (COLLABORATIVE)

This portion of hw7 is "hw7c", where the "c" means "Collaborative". This problem (Tetris), and only this problem, is optionally collaborative. You may work in groups of up to 2 currently enrolled 15-112 students (yourself included), so do not work with more than one other student. Each student should submit their own work individually, submitted as part of hw7c. Include the name and andrew id of your groupmate, if any, at the top of your hw7c.py file. And as always with collaborative work, you must be actively involved in every part of your solution, and you may never simply copy any code from anyone, nor electronically share your code (email, FB, texting, etc) even with your partner.

  1. playTetris() [30 pts] [COLLABORATIVE]

    Write Tetris according to the design given in this step-by-step tutorial using our event-based animation framework (starting with events-example0.py).

    You may not use a different design, even if you think there's a better way to do it (there probably is, but you still have to do it this way). This may seem limiting, but sometimes you are given specs at Polya Step 1 (just indicating the problem to solve), and other times at Polya Step 2 (also indicating the algorithms to use). This is one of those second kind of specs. Your task is to do Polya Step 3, and write the corresponding code, and then using this week's event animation framework.

    Have fun!!!

Hw7s (SOLO)

This portion of hw7 is "hw7s", where the "s" means "SOLO". All the problems on this portion are SOLO, not collaborative. You must work alone, as you have done on all previous hw's this semester.

  1. hw7b splash screen and modes [10 pts] [SOLO]
    All of hw7b will be submitted in a single file, hw7b.py. How do you place 4 (or more, if you do some bonus) different graphics/animations in a single file? We'll do that using a splash screen and modes (see the mode-demo for details). When we run your submission, we should first get a splash screen saying it is hw7, listing your name and andrew id, and listing the different graphics/animations in a numbered list, like so:
    1. drawCirclePattern
    2. drawSpiral
    3. adaptedSnake
    4. betterSideScroller
    Include more if you do bonus. Then, if the user presses a digit key that corresponds to one of those graphics/animations, you change modes and run that graphic/animation. So the user presses "1" and then sees the result of drawCirclePattern. How to get back to the splash screen? Like so: at any time, in any graphics/animation, if the user presses the escape key ("Escape"), then the mode should switch back to splashScreen.

  2. drawCirclePattern [10 pts] [SOLO]
    Write an animation named drawCirclePattern that draws this picture:

    More precisely, initially draw the image with 10 rows x 10 cols. Each time the user presses the "Up" arrow, increase the dimensions by 1 row x 1 col. Similarly, each time the user presses the "Down" arrow, decrease the dimensions by 1 row x 1 col, never going below 1x1. While the image above shows two circle patterns, you only need to draw one at a time. For example, the left image above was drawn with 10 rows (and 10 columns), and the right image with 5 rows (and 5 columns). The pattern consists of "buttons" (or perhaps "bullseyes"), where each button is really several circles drawn on top of each other. Each circle in a "button" has a radius 2/3rds as large as the next-larger circle, which continues until the radius is less than 1. As for the color of each button, here are the rules to follow:

    Rule 1: Starting from the left-top corner, every 4th diagonal is entirely red.
    Rule 2: For the non-red buttons, starting from the top row, every 3rd row is entirely green.
    Rule 3: For the non-red and non-green buttons, starting from the second-to-leftmost column, every 2nd column is entirely yellow.
    Rule 4: Any non-red, non-green, and non-yellow button is blue.

    Note that these rules can be fairly easily implemented using a single if-elif-elif-else statement. Inside that statement, you might want to set a variable, say one named "color", based on each of these four conditions. Then you could draw with fill=color.

    Note: The drawing should mostly fill the window, but the exact dimensions are up to you, though it may work out well if you arrange it so that the width and height of the drawing are both multiples of the numbers of rows and cols.

  3. drawSpiral [10 pts] [SOLO]
    Similarly to the previous problem, write an animation named drawSpiral that draws this picture:

    More precisely, initially draw the image as described. However, each time the user presses "Up" your image should get around 10% larger, and so fill more of the screen, perhaps spilling offscreen. And each time the user presses "Down" your image should shrink a commensurate amount, so that "Up" followed by "Down" results in no change.

    As for the image, it will be a spiral (or really a series of spiral arms). The spiral arms must be created by drawing a series of circles (the only thing drawn in this exercise are small circles). There should be 28 arms, each arm composed of 32 circles. Each arm spirals, or bends, such that the outermost circle in the arm is drawn pi/4 radians (45 degrees) beyond the innermost circle in that same arm. Hint: You will have to use basic trigonometry here! Also, try to make the color gradients work as indicated (think rgbString). Finally, set timerDelay to something very large, like 10*1000, so this does not constantly redraw, which may be quite slow. Also, while you need to be close to exact for full points, we will be liberal with partial credit on this particular problem, so "fairly close" will get most of the points.

  4. adaptedSnake [20 pts] [SOLO]
    Our snake code from this week mentions this:
    # Note: there is a snake tutorial from previous semesters here: # http://www.kosbie.net/cmu/fall-11/15-112/handouts/snake/snake.html # But this is different in two key ways: # 1) This uses this semester's framework (run function, and in Python3) # 2) This uses a list of tuples to represent the snake # You should understand both solutions, and be able to adapt that # tutorial to use this semester's framework.
    Your task here is to do just that: write adaptedSnake, which uses the approach from that tutorial, but in our current framework (representing the snake as integers on the board instead of as a list of (row,col) positions, but also using our run() function and our event handlers). If it would help, you are free to use any code from our Snake worked example from this semester (just be sure to cite it!).

  5. betterSideScroller [20 pts] [SOLO]
    Write an improved version of our side-scroller demo, with these modifications:
    1. Smooth horizontal motion
      As it is now, the player moves horizontally by one step on a left or right arrow. Instead, the player should start at rest, but a right arrow would increase its speed by 1, and left arrow decreases its speed by 1. Positive speeds mean to move to the right, negative speeds move to the left. Actual movement will not occur in response to arrow presses, but rather in response to timerFired events, but the amount moved on each step will be determined by the speed.

    2. Stopping at walls
      If the player runs into a wall, they will stop, so their horizontal speed becomes 0. Also, they should be positioned so they are immediately next to, but not actually overlapping the wall. Note that if the player is moving fast enough, they could essentially go straight through walls, since their position would change from one side of the wall to the other without ever actually intersecting the wall. This is fine.

    3. Jumping over walls
      Vertical motion will be entirely different. The new way is this: when the player hits the up arrow, they jump. It has to be high enough to clear the walls. Jumping physics is left up to you (and we recommend that you keep it simple), so long as it looks like a jump (up and down), and is playable, so walls are able to be jumped. If you jump up and land on a wall, you are placed on the ground level, with no vertical or horizontal motion, immediately to the left of the wall, but not actually overlapping it.

    4. New wall points system
      Each time you collide with a wall, subtract one from that wall's points, except do not use negative points (just stay at 0 in that case). And each time you jump over a wall, add one to that wall's points. Note that this must work the way the demo currently works, so that only new collisions count, and you don't keep subtracting points as a player takes several moves to fully pass through the wall. And as noted above, note that if you move fast enough, you might essentially pass through a wall without intersecting it, in which case you do not lose points!

    5. Throwing balloons at walls
      By pressing 't', the player can throw a water balloon horizontally, about at eye level (if the player had an eye). The water balloon travels in the same direction the player is going (or to the right if the player is not moving), and goes faster than the player. If it hits a wall on the screen, that wall disappears forever. If it reaches the end of the visible screen without hitting a wall, the balloon disappears. The player can can throw balloons endlessly, but only one at a time.

    6. bonus/optional: betterSnake [up to 2pts] [SOLO]
      Separately from your version of snake for the problem above, write a new and improved version of Snake, betterSnake, included in your splashScreen options, with these additional features, all with a reasonably pleasing user interface:
      1. A score.
      2. A timer.
      3. Multiple snake lives.
      4. A high score file.
      5. A splash screen (at the start of the program), a game over screen, and a help screen.
      6. Walls
        These can be placed randomly, and snakes don't die when they hit walls, they just can't go through walls. So what happens instead? That's up to you. Just do something reasonable and interesting and fun.
      7. Eagles (they eat snakes)
        Eagles start in a random location, but they move towards the snake, and if they get to the snake, they eat it and kill it. Don't make the eagles too aggressive nor too passive, or it won't be fun to play.

    7. bonus/optional:sokoban [up to 3pts] [SOLO]
      First, read the Wikipedia page on Sokoban. Then, write the function playSokoban() that plays the game. Do not use any images. All drawing must be with graphics primitives (lines, rectangles, ovals, etc). Also, do not use any sound. Besides that, design as you will. The nicer the game, the more points awarded. Have fun!

    8. bonus/optional:Dots and Boxes [up to 3pts] [SOLO]
      First, read the Wikipedia page on Dots and Boxes. . Then, write the function runDotsAndBoxes(rows, cols, maxSecondsPerTurn) which will play a human-human Dots and Boxes game on a rows x cols board, but also not allowing more than maxSecondsPerTurn time to elapse on any give turn. If the time elapses, the screen should visibly flash and the player should lose that turn (though not the game). Your user interface can be simple, even quite plain, but it must be functional so two people can use it to play. It must display the board, make clear whose turn it is and where legal moves are, make it easy for players to enter moves, actually make those moves if legal (or reject them if illegal), display who has captured which boxes, alternate turns, display the score, detect game over, and print a suitable game over message. Don't forget about the maximum time per turn, too!