Your task is to program a model of an parameterized island consisting of an array of locations (for example, a 100x20 matrix). The locations will be populated with plants and animals. Animals can:

  • eat plants and/or other animals (if their location has suitable food),
  • move (to neighboring locations),
  • breed (if two of a kind exist in a location),
  • die of hunger or be eaten.

OOP

When creating your host of animals, you should use OOP as much as possible: all species will derive from one abstract Animal class, which will contain the behavior that is common to all animals. If specific animals have specific features in regards to their feeding, reproduction, movement, etc., then they need to override the methods of the Animal class.

Here's what you need to do:

1. Create a class hierarchy:

  • Carnivores: Wolf, Boa, Fox, Bear, Eagle

  • Herbivores: Horse, Deer, Rabbit, Mouse, Goat, Sheep, Boar, Buffalo, Duck, Caterpillar

  • Plants

The table below shows how likely an animal is to eat "food" if it is in the same location as that "food". Let's look at the situation where "a wolf eats a rabbit". The number in the table is 60. This means that if a wolf and rabbit are in the same location, there is a 60% chance that the wolf will eat the rabbit. You need to use a multithreaded random number generator.

Wolf Boa Fox Bear Eagle Horse Deer Rabbit Mouse Goat Sheep Boar Buffalo Duck Caterpillar Plants
Wolf - 0 0 0 0 10 15 60 80 60 70 15 10 40 0 0
Boa 0 - 15 0 0 0 0 20 40 0 0 0 0 10 0 0
Fox 0 0 - 0 0 0 0 70 90 0 0 0 0 60 40 0
Bear 0 80 0 - 0 40 80 80 90 70 70 50 20 10 0 0
Eagle 0 0 10 0 - 0 0 90 90 0 0 0 0 80 0 0
Horse 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 100
Deer 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 100
Rabbit 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 100
Mouse 0 0 0 0 0 0 0 0 - 0 0 0 0 0 90 100
Goat 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 100
Sheep 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 100
Boar 0 0 0 0 0 0 0 0 50 0 0 - 0 0 90 100
Buffalo 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 100
Duck 0 0 0 0 0 0 0 0 0 0 0 0 0 - 90 100
Caterpillar 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 100

Animal characteristics:

Weight per animal, kg Maximum number of animals of this species per location Maximum speed (number of location) per turn Number of kilograms of food required to fully feed the animal
Wolf 50 30 3 8
Boa 15 30 1 3
Fox 8 30 2 2
Bear 500 5 2 80
Eagle 6 20 3 1
Horse 400 20 4 60
Deer 300 20 4 50
Rabbit 2 150 2 0.45
Mouse 0.05 500 1 0.01
Goat 60 140 3 10
Sheep 70 140 3 15
Boar 400 50 2 50
Buffalo 700 10 3 100
Duck 1 200 4 0.15
Caterpillar 0.01 1000 0 0
Plants 1 200 N/A N/A

2. An animal must have methods for eating, breeding, and choosing a direction for movement.

3. You can implement the eat method in the herbivore and carnivore classes. But be careful, the herbivore duck eats caterpillars.

4. In specific classes representing particular species, you can modify all the methods to suit the characteristics of the animal.

5. You need to create at least 10 herbivore species and 5 carnivore species (described in Item 1).

Multithreading

Of course, it is possible to write the entire program on one thread using only loops. But we need practice working with multithreading, so you must use threads and thread pools. One scheduled pool to run recurring tasks for plant growth and animal actions, and a task to display system statistics. Alternatively, you can display the statistics in a task with the plants or animals. Inside the animal action task, you can use another thread pool — an ordinary one. You decide which tasks to assign to this pool.

Mandatory parts of the task:

  • Animal hierarchy (OOP)
  • Animal behavior
  • Multithreading
  • Statistics on the state of the island at each iteration (displayed on the console)

Optional parts of the task:

  • Display the parameters in one place so that it is easy to manage the simulation
  • Graphics instead of console statistics. You can use either pseudographics in the console, or JavaFX, Swing...
  • Add other factors that could affect the simulation:
    • more kinds of animals
    • different types of plants
    • custom behavior for a group of animals (for example, wolves hunt and move as a pack rather than separately)
    • ground terrain, including a river that impedes the movement of certain animals

About settings (if you decide to add them)

To make it convenient to change the various settings when starting the program (the island size, the maximum allowable number of plants / animals at one location, the probability that a particular type of animal will move, the number of offspring in different species, etc.), you need to put all these settings somewhere, for example, in a separate class. It should be possible to change the following settings:

  • island size
  • duration of a clock cycle in the simulation
  • the number of animals of each species at the start of the simulation
  • condition for stopping the simulation (e.g. all the animals have died)
  • number of offspring for each type of animal

Unicode (if you decide to do pseudographics)

You can use Unicode characters to depict the animals: 🐃, 🐻, 🐎, 🦌, 🐗, 🐑, 🐐, 🐺, 🐍, 🦊, 🦅, 🐇, 🦆, 🐁, 🐛.