Pipe Fantasy (Part 2)
This is the second part of the Pipe Fantasy project. You will add the “goo” and display the list of incoming pipes. However, instead of starting the goo-flow automatically, the user will click to propagate the goo after all pipes are placed. This approach will make the game easier to implement for now. So, the game works as follows:
- Click to place pipes on tiles (HW 6)
- When all incoming pipes are exhausted, click to move the goo by one tile (HW 8)
The following example illustrates the goo-flow:
In this example, the goo flows into a Cross pipe from left
and flows out to
right
, and later flows into the Cross pipe from top
and flows out from
bottom
.
Before You Start …
Here are a few things to keep in mind before you start working on it:
-
Everything we said about Part 1 still applies!
-
This assignment will ask you to build on top of your solution to Part 1. So, make sure you have a working solution to Part 1 before you start. To help you with this, we will be hosting a help session for Part 1.
Goo Flow
Important: You should complete and test every part before proceeding to the next part. If you don’t, you are very likely to end up with an unfixable program.
In Pipe Fantasy, the goo starts from a starting pipe on the grid. A starting pipe is a pipe that only has an opening in one direction. Moreover, the player does not place the pipe with a click: its location is set when the game begins.
Task 1: Modify your data definition for Pipe
to include starting pipes.
Test your code: all existing check-expects should work.
Task 2: Modify your definition for pipe->image
as follows:
;; pipe->image: Pipe Integer Integer Boolean -> Image
;; Draws the given pipe on a square tile with length tile-side-length. The width
;; of the pipe is pipe-width. Pipe-width should be less than tile-side-length.
;; If filled? then draw the pipe with goo.
(define (pipe->image pipe tile-side-length pipe-width filled?)
...)
Make all necessary changes to support starting pipes and the modified pipe->image
function.
Test your code: all existing check-expects should work. You should run the game and verify that it continues to work as before. You have added support for starting pipes and goo, but are not using them.
Task 3: Goo flows through the pipes on the grid, starting from the starting pipe. The starting pipe is considered to have goo from the beginning. The goo continues to propagate in the direction of the opening until it reaches either:
- An empty cell,
- The boundary of the grid, or
- A pipe that does not have an opening towards the direction of the flow.
Design data called GooFlow
that represents the path taken by the goo and
the direction in which it is flowing. You can modify existing data if you wish,
but it isn’t necessary to do so.
Test your code: all existing check-expects should work. You should run the
game and verify that it continues to work as before. You have designed
GooFlow
but are not using it.
Task 4: Write a function grid-goo-propagate : GooFlow Grid -> GooFlow
that moves the goo forward by one tile. If the goo is stuck, produce the
same goo.
Test your code: all existing check-expects should work. Moreover, you should be able to test the new function. You are not using it in the rest of your game yet.
Task 5: Modify GameState
and other necessary code to support:
- The starting pipe (at some arbitrary location)
- The
GooFlow
, which should start at the starting pipe location.
Test your code: all existing check-expects should work. Your GameState
has a starting pipe and goo-flow, but your functions aren’t using them yet.
So, the game should continue to work as before.
Task 6: Design a function called gamestate-init
that initializes the
gamestate given the following information:
- the grid dimension
- the x and y grid coordinates of the starting pipe
- the direction of the starting pipe
- the incoming pipes list
Task 7: Modify your program to display up to n incoming pipes. ($n$ should be greater than 3, but can be any number you like.)
Hint: We recommend adding this to the right or bottom of grid, so the grid
stays at same mouse coordinate and your computation for mouse coordinates to
grid coordinates are not affected. You might want to add a check in
place-pipe-on-click
to make sure nothing happens if mouse is clicked outside
the grid.
Test your code: all existing check-expects should work. The game should also work and show the incoming pipes. Goo doesn’t yet flow, but that’s ok.
Task 8: Implement the following feature to the game: after the incoming pipes list has been exhausted, the user can click on the grid to propagate the goo, with one mouse click propagating the goo for one step.
Test your code: at this point, the full program should work.
Task 9: Write one or two examples for GameState
(you may use
gamestate-init
) to illustrate the features you have implemented in this
homework.