Spring 2025 CS 31

Programming Assignment 7
Angry Seabirds

Time due: 11:00 PM Thursday, June 5

You were flying alone over the South Indian Ocean toward Heard Island in a plane with a load of lantern fish to be used as payment for guano, when your airplane developed a serious mechanical problem. Spotting a tiny bit of land, you landed in a small valley on an island. Thanks to your GPS locator, help will find you, but wait! The valley, surrounded by sheer cliffs of sharp volcanic rock, is filled with penguins. A penguin poses no danger to you unless it's ion the same position as you, in which case it will view you as a threat and attack you with powerful pecks. Fortunately, you have your lantern fish with you to throw and distract them, but there are so many of them…

Well, that's the scenario for a new video game under development. Your assignment is to complete the prototype that uses character-based graphics.

There are three species of penguins in the valley: gentoo, macaroni, and king. Each species of penguin has a favorite species of lantern fish it loves to eat. Gentoo penguins like Electrona carlsbergi (which we'll call G fish), macaroni penguins like Protomyctophum tenisoni (which we'll call M fish), and king penguins like Krefftichthys anderssoni (which we'll call K fish). Luckily, you have a limitless supply of all three kinds of fish with you. You can throw a fish in a particular direction. When a penguin notices its favorite kind of fish flying through the air in a particular direction, it alerts all the other penguins of the same species, and those penguins all move one step in the direction the flying fish is moving;all penguins of the other two species ignore that fish. Penguins have short attentions, so after the moving penguins move one step, they forget about moving any more because of that fish.

You can capitalize on this behavior: If you want to try to get all the gentoo penguins to move north, for example, you throw a G fish north. With 50% probability, no gentoo penguin would notice it, so nothing special happens, but with 50% probability, it's seen and all the gentoo penguins move one step north, after which time the fish has landed and they forget about moving north because of it.

If you execute this Windows program or this Mac program or this Linux program, you will see the player (indicated by @) in a rectangular valley filled with penguins (each indicated by a G, M, or K, the first letter of its species). At each turn, you'll select an action for the player to take: move one step or stay put. The player will take the action. You will then select a fish type and direction for the player to throw the fish. Then each penguin will move. Normally, each penguin will pick a random direction and move one step in that direction. However, if the fish is noticed by a penguin for which it's the favorite (it will be noticed with 50% probability), the penguins of that species will instead move one step in the direction the fish is moving. If a penguin moves onto the position occupied by the player, it attacks the player furiously and the player dies. (If the player moves to a position occupied by a penguin, the player dies, so that would be a dumb move.)

The positions may have tall protrusions of sharp volcanic rock. If the player or a penguin moving of its own free will (i.e., not because it's following a fish) chooses a direction such that moving would be to a position occupied by a protrusion or into a cliff wall (i.e., a point outside the walkable area of the valley, like trying to go south from the bottommost row), then the player or penguin just doesn't move that turn. For a penguin moving because it's moving in the direction of a flying fish, if it attempts to move into a protrusion or into a cliff wall, it doesn't move that turn, but suffers 1 unit of damage because of the sharp rock. A penguin that has suffered 3 units of damage is dead and is removed from the game. Clearly, it's in the player's interest to throw fish in a way that attempts to cause a neighboring penguin to move away from the player or to cause penguins to smash into protrusions or the cliff walls at the boundary of the valley.

This smaller Windows version or Mac version or Linux version of the game may help you see the operation of the game more clearly.

(You can run the Linux version by logging in to cs31.seas.ucla.edu and running the command /usr/local/cs/bin/penguinsdemo or /usr/local/cs/bin/minipenguinsdemo. On a Mac, if you click on the downloaded zip file and then double-click on the executable file (e.g., penguinsmac), your operating system may refuse to open it because it can't confirm who developed the program. In that case, right-click on the executable file instead, select Open With and then Terminal.app. Select the gray Open button on the popup that again says it doesn't know the developer. If your Windows system refuses to run the Windows version because it thinks it has a virus, then if you trust me when I say I built the program myself on the SEASnet Windows server with no virus in the source code, and you trust the SEASnet people to not have installed a devious compiler that inserts a virus into code it compiles, and you know how to disable your antivirus software or otherwise get around the refusal, then you can run the Windows version; otherwise, run the Linux version as described at the start of this paragraph.)

At each turn the player may take one of these actions:

  1. Stand. In this case, the player does not move.
  2. Move one step north, east, south, or west. If the player attempts to move onto a protrusion or into a cliff wall (e.g., south, when on the bottom row), the result is the same as standing. If player moves to a position currently occupied by a penguin, the player dies.

The game allows the user to select the player's action: n/e/s/w for movement, or x for standing. The user may also just hit enter to have the computer select the player's move.

After the player moves, the user is prompted for a fish type and direction. You enter a two-character string such as "gn". The first character is the fish type g/m/k (upper or lower case) and the second is n/e/s/w. The player throws the fish, which flies only for the duration of the penguins' turn. (The flying fish is not displayed on the screen.) At the penguins' turn, there is a 1/2 probability that the fish will be noticed by an penguin for which it's the favorite. (Gentoos prefer G fish; macaronis, M fish; and kings, K fish). If it is, all penguins of that species move one step in the direction the fish was thrown if they can; if they can't (because they'd hit a protrusion or move into a cliff wall), they stay put, but suffer 1 unit of damage. If the fish is not noticed by any penguin for which it's the favorite, the penguins of that species act like all the other penguins on that turn: They move normally.

Normally, each penguin picks a random direction (north, east, south, west) with equal probability. The penguin moves one step in that direction if it can; if the penguin attempts to move into a protrusion or into a cliff wall, however, it does not move and suffers no damage. More than one penguin may occupy the same position; in that case, the display will show a species character G, M, or K) indicating the species of one of the penguins at that point (which one is shown is up to the program).

Your assignment is to complete this C++ program skeleton to produce a program that implements the described behavior. (We've indicated where you have work to do by comments containing the text TODO.) The program skeleton you are to flesh out defines four classes that represent the four kinds of objects this program works with: Game, Valley, Penguin, and Player. Details of the interface to these classes are in the program skeleton, but here are the essential responsibilities of each class:

Game

Valley

Player

Penguin

The skeleton program you are to complete has all of the class definitions and implementations in one source file, which is awkward. Since we haven't yet learned about separate compilation, we'll have to live with it.

Complete the implementation in accordance with the description of the game. You are allowed to make whatever changes you want to the private parts of the classes: You may add or remove private data members or private member functions, or change their types. You must not make any deletions, additions, or changes to the public interface of any of these classes — we're depending on them staying the same so that we can test your programs. You can and will, of course, make changes to the implementations of public member functions, since the callers of the function wouldn't have to change any of the code they write to call the function. You must not declare any public data members, nor use any global variables whose values may change during execution (so adding global constants to those already in the skeleton code is OK). You may add additional functions that are not members of any class. The word friend must not appear in your program.

Any member functions that you implement must never put an object into an invalid state, one that will cause a problem later on. (For example, bad things could come from placing a penguin outside the valley.) Any function that has a reasonable way of indicating failure through its return value, should do so. Constructors pose a special difficulty because they can't return a value. If a constructor can't do its job, we have it write an error message and exit the program with failure by calling exit(1);. (We haven't learned about throwing an exception to signal constructor failure.)

What you will turn in for this assignment is a zip file containing this one file and nothing more:

  1. A text file named penguins.cpp that contains the source code for the completed C++ program. This program must build successfully under bothe g31 and either Visual C++ or clang++, and its correctness must not depend on undefined program behavior. Your program must not leak memory: Any object dynamically allocated during the execution of your program must be deleted (once only, of course) by the time your main routine returns normally.

Notice that you do not have to turn in a report describing the design of the program and your test cases.

By Wednesday, June 4, there will be link on the class webpage that will enable you to turn in your zip file electronically. Turn in the file by the due time above.