Due: 8:00am, Thursday, April 15. Value: 30 pts. Submit to Sauron.
The attached program creates a serene scene of a moonlit night with three ships, each ship containing three pirate ghosts wearing top hats. Note the sublime realism.
We'll modify this program so that the ships glide across the sea. When the user clicks the head of a pirate, it will turn green; and when the user manages to click all three pirates on the ship, the ship will sink. Thus, we'll end up with what one might call a game: Sink the ships with the fewest clicks.
Each ship is represented as a hierarchy of lists, represented
by the below tree diagram. In the
top-level list is a Polygon object corresponding to
the ship's hull,
a list containing shapes constituting the ship's sail, and two
lists containing shapes constituting the two pirates on deck.
Within the list for the sail is also a list containing shapes
constituting a pirate standing on its yard.
Note, though, that nothing in the code you write should be specific to the diagram. For example, if I decided to put each pirate's head as part of the list currently representing the hat, then the program should still work properly.
move_allFirst complete the move_all function.
This function is called repeatedly by the code I provide; but
since the move_all function as provided doesn't do
anything, the ships stay stationary.
The move_all function is given three parameters:
a hierarchy of lists holding shapes, a distance to move in the
x direction, and a distance to move in a y
direction. The function is to descend through all the shapes in the
hierarchy and invoke each shape's move method to tell
it to move as directed by the second and third parameters.
You should accomplish this using recursion:
You will want a for loop to
iterate through each element of the parameter list.
Each time you find a list nested within the parameter list,
you should recursively call your move_all
function with that sub-list as a parameter,
so that all shapes in that subhierarchy are moved.
To help you identify when an element is itself a list, the
provided code includes a function named is_list which
returns True if its parameter
is a list.
Build and test this function before proceeding. Once complete, you should find that each of the ships rolls quietly across the sea.
check_hitNow complete the check_hit function, which takes
two parameters: The first is a hierarchy of shapes, while the
second is a Point object representing a location
where the user has clicked. The function's job is to go through
each circle in the hierarchy, and for any circles containing the
parameter point, the function should call mark_as_hit.
(The mark_as_hit function will color the circle green, and
the program is arranged so that after all three pirates' heads
turn green, the ship will sink.)
Again, you should accomplish this using recursion.
To help, I have provided two functions,
is_circle_containing and mark_as_hit.
The is_circle_containing function takes two
parameters — an object which might be a circle and a point
— and returns True if the
first parameter is a circle and the point lies within it.
The mark_as_hit function takes a single shape as a
parameter, colors it green, and remembers that it has been hit
so that later the code I provide will know when to sink the ship.