Prelude

This project presents a scenario where you are tasked with building a complex simulation program. The scenario description provides context for what you will do - you are not asked to create the whole system or anything close to it, and some parts of the description may be irrelevant. There are four elements to the project:
  1. Create a class design for the system. This design will include any classes/interfaces you would use and any inheritance relationships between them/interfaces implemented by classes. It may include where important pieces of data will live and how they will be stored, and may incorporate major methods. Do this before any implementation. You will submit a class diagram for the whole system.
  2. Then begin translating your design into code. Individual steps are given, asking you to build the program as far as supporting specific elements of the system. It is not expected that your whole design will have been incorporated in code at the end, nor that all (or even most) steps will be completed. It is not required that you follow the design exactly, or at all if you find major limitations. Document your code as you go: use JavaDoc and comments as appropriate. Your implementation code itself is not directly being marked. You will submit your generated JavaDoc.
  3. Use Git and GitLab to store your code. As you build your implementation, make regular and appropriate commits of your changes, with good commit messages. Push your changes to a GitLab project you created for this assignment, and add user mwh as a member of it. You will submit your git history.
  4. Create a detailed class diagram for the part of the system you have built. This will not be the same as the design you produced at the start: it will only incorporate the parts you implemented, and it will include attributes and important public methods as they were implemented. You will submit another class diagram for what you built only.

The system has many similarities to the Bug World exercise: consider what you might want to do differently from your experience building that (and note that the constraints are not identical, and your design might be wholly different to what was used there, or might have similarities).

The focus of this project is not the code implementation itself, but the design, documentation, and process you follow. You do not need to implement all functionality in the list of steps, as long as you have built enough to have meaningful class and object structures that you can document. It is not strictly required that the code even works.

In ordinary circumstances, this project would have run for two days Wednesday-Thursday. That gives the appropriate amount of time to spend on it (about ten hours), but given current circumstances people may need to spread that over a longer period, so the formal due date is Friday night, and there will be no penalty for submissions during the weekend. It is expected that even the listed implementation tasks are too large to complete in full, and you should treat implementation as secondary to the class diagrams that bracket it - do your design and diagrams, then implement until it's time to start the final class diagram (which you should leave perhaps two hours for).

The implementation code is not directly marked for either quality or quantity - it's a tool to provide something to document. Instead, the quality of your design, documentation, class diagrams, and commit history will be assessed. It is not a problem if your preliminary design does not match your ultimate implementation.

The scenario description follows. Remember that you will not build the entire system in this project, or even most of it, but you should design for the whole thing. Some parts of the description may be irrelevant or even contradictory.

The Island

You are creating a program to simulate the ecosystem on an island for theoretical biologists. The island has various geographic features, animals, and foliage. Your simulation will be turn-based: each "turn" of the world, all of the entities on the island update themselves simultaneously in response to the passage of time, their needs (such as food or water), and what they detect around them (such as predators). After all entities are updated, the turn is over and the next one begins.

The biologists want to be able to start an island with certain creatures, plants, and geography, simulate it for a time, then start over with either the same or different elements. When a biologist pauses the simulation to add to or modify parts of the simulation, the overall statistics of living things on the island are displayed for them to judge. When loading a saved island, the initial state of the simulation and all its statistics are displayed, but it doesn't run until they set the weather. Biologists can share snapshots of their island with each other, but only while paused.

The user may select a specific creature, or multiple, to follow intensely in the simulation. These creatures are displayed differently and their individual status and statistics are visible at all times. They may also focus on specific geographical features, and see that information about any creatures or plants on them.

The simulation

On their turn, hungry creatures will move towards food sources they like and eat if they reach them. A creature that does not eat for a long time does not survive and is removed from the island. Similarly, thirsty creatures need and seek water. Creatures may try to avoid or hide from predators they detect. Creatures may be on the ground, in the water, or in the air, and different creatures may be able to be in different combinations of those. A creature in the air cannot be interacted with by a creature on the land. A creature that is neither hungry nor thirsty, and is not fleeing, will seek out others of the same species and will produce another creature as their child if two such creatures meet; some will then mate for life. Some creatures, such as birds, will try to give food items to their children until they reach a certain age. Some creatures are brood parasites, and trick other creatures into treating the parasite's children as their own and feeding them. Creatures with no other focus at the moment move about randomly.

Mammals can contract rabies, a contagious disease that changes the animal's personality to be very aggressive, while some parasites also replace its usual behaviour with seeking food for the parasite. Other parasites simply deplete and live off the energy of their host. Parasites cannot be hosts to other parasites, but may sometimes be alone. Consuming certain plants may also alter a creature's behaviour for a time. Only one of these effects can be in force at once.

Plants shrink when they are eaten from and recover over time. A plant that shrinks to nothing does not survive and is removed from the island. Plants may have seeds that cause another of the same plant to grow elsewhere. Geographic features such as water and elevation do not change over time. Rain does not affect geographical features or creatures, only plants, but the wind may.

An entity can only interact with something it is next to, and takes up space that others can't be in at the same time, though a creature or plant may be on top of a geographic feature. A creature can see within a certain distance around itself, which may vary for different creatures, and will detect any interesting entities in range (such as food, water, predators, or mates). You may assume the island is rectangular.

The island includes:
  • Rabbits, mid-sized land animals that eat grass and light vegetation and hop over the ground
  • Sparrows, small birds that nest and lay eggs in trees, can fly quickly or hop slowly over the ground, and eat worms
  • Streams and rivers, areas of fresh water on the ground
  • Scrub brush, small trees covering the ground
  • Kiwi, mid-sized birds that nest underground, with poor vision that cannot fly and eat grubs and worms from the soil
  • Fish, creatures that live and move in water only and prefer to be near their family
  • Pine trees, tall trees often found together
  • Cats, mid-sized land animals with good vision and high speed that prefer to eat birds, but will eat rodents
  • Grass patches, small areas covered in edible grass that grows longer over time
  • Chickens, mid-sized birds that can fly for a short time and roost in high places
  • Crocodiles, large ambush predators that hide in rivers
  • Cheetahs, very fast large land animals that need a lot of food to survive and will chase a prey creature until caught
  • Rats, large rodents that eat worms and eggs
  • Platypus, medium-sized egg-laying amphibians that burrow near water
  • Apple trees, mid-sized trees that produce fruit
  • Wolves, large land animals that will eat any smaller creature and live in packs

Design phase

Create a class design for the system described above and draw a class diagram for it. If you have many identical subclasses of something, you can include only one or two representative children to save repetition. You should not include all attributes or operations at this stage, but very core ones that distinguish different classes may be included if you wish.

When designing your system, consider what you would make an interface and what a class. Consider where the behaviour of a class should be different from others as well as its direct relationships to others. You will include both associations between classes and inheritance/implements/generalisation structures within your diagram.

If necessary, you can create multiple diagrams for different parts of the system (e.g. if it is more effective for space reasons). It should be clear somewhere how the different segments relate to one another.

Implementation Tasks

After you have completed your design, begin to implement the system to support these functionalities following this list of tasks. If you find that you cannot complete one any further, you can move on to the next one - the order is a suggestion only, and jumping around to include more interesting parts is also entirely acceptable. A partial implementation is still worthwhile, and you should try to include a variety of classes or interfaces in your implementation. You are not expected to complete all of the tasks, though you may, and there is no direct benefit in doing so. Leave yourself a few hours to make the final class diagram, and stop in time to do that. Don't forget to (a) document your code as you go and (b) make appropriate Git commits.
  1. Now begin to create your simulation program, supporting only:
    1. An island, of fixed and finite size.
    2. Rabbits on that island that move about randomly each turn.
    3. Automatically running the simulation for ten turns when the program is run.
  2. Create two islands when the program starts. Report the number of each creature surviving at the end on each island. Simply add a small number of rabbits to each island when it is created at this point.
  3. Add grass to your simulation. Grass should grow each turn, but the rabbits do not need to seek it out at this point. Add some grass to each island when it is created.
  4. Add kiwi to your simulation. Assume grubs are found in the ground everywhere and the kiwi can eat wherever it is.
  5. Make rabbits search for food when they are hungry.
  6. Add streams to your simulation. Ensure your creatures act on their thirst.
  7. Have your islands be randomly populated with streams, grass, and creatures.
  8. Add cats. Cats will seek other animals to eat.
  9. Add sparrows. Sparrows can fly.
  10. Add rats.
If you have implemented all ten tasks, move on to the final diagram of your system. If you are getting close to the end of the allocated time, stop and move on to the final diagram of what you've built - it's not worth implementing more of it at that point.

Git Commits

A good commit should be self-contained, leave the program compiling afterwards, and achieve a single thing. Your commit message should have a short first line, and then longer descriptive text in paragraphs below as applicable. The first line should be an imperative statement saying what this commit should achieve. For example:

Add ability to borrow books

Books can be marked as borrowed in a Catalogue by calling the new lendBook(User) method. This method will enforce reservations, but does not yet understand lending limits.

Make regular commits of your code changes as you go. Each time you complete a modification, commit it before moving on to the next piece of work.

Descriptive Class Diagram

After your implementation, make a new class diagram covering the classes that you implemented. In this diagram, include all non-private non-inherited operations and attributes of classes. Again, you may split this into pieces if that is more practical, but it should be clear how they fit together.

Submission

There are three things to submit:
  • Submit your class diagrams in the SWEN502 submissions system. Make sure you label which is the design diagram and which represents your final implementation. You can submit a photo of hand-drawn diagrams, or an image of one you created electronically.
  • Also submit your generated JavaDoc in a zip file.
  • Add user mwh to your GitLab project to submit your code. Don't forget to push your code to it.
You should submit by Friday 10 September, but there are no late penalties for submissions made over the weekend. Don't spend an unreasonable amount of time on the project, and aim for 10-12 hours total as you would do in person.

Plagiarism

Plagiarism is presenting someone else’s work as if it were your own. Plagiarism includes not only the mechanical entry and phrasing of the text but the ideas and thinking behind it. Plagiarism and other violations of academic integrity are prohibited at Victoria. You can refer to the university's policy on academic integrity and plagiarism for further details.