A JavaFX evolution simulation where animals roam a grid map, eat plants, reproduce, and evolve through genetic inheritance and mutation.
Object-Oriented Programming course project, AGH University of Science and Technology, 2025.
The world is a rectangular grid divided into steppe and jungle. Animals are herbivores driven by a genome - a sequence of genes (values 0-7) that determine rotation and movement each day. Each day an animal rotates by its current gene value, moves one field forward, loses energy, and advances to the next gene. The map wraps horizontally like a globe; animals bounce off the top and bottom poles.
Plants grow each day with an 80/20 Pareto distribution - 80% of new plants appear in the jungle zone (middle 20% of map height), 20% on the steppe. When an animal steps on a plant it eats it immediately.
Reproduction happens when two animals on the same field both have enough energy. The child's genome is a weighted crossover of both parents (proportional to energy), followed by random mutations. Parents transfer a fixed amount of energy to the child.
demo.mp4
- Some fields generate toxic plants that drain energy instead of restoring it.
- A random resistance genome is generated at simulation start.
- Each animal's genome is compared to the resistance genome - the percentage match determines poison resistance (e.g. 60% match = 60% less energy lost from toxic plants).
- To run the base variant without toxicity, set toxic plant probability to
0in the config window.
Core:
- Configurable map, animal, plant and genome parameters
- Globe-style map wrapping with pole bounce
- Per-day simulation loop: remove dead - move - eat - reproduce - grow plants
- Start/stop simulation at any time
Extensions:
- Energy bar rendered under each animal, color shifts green to red
- Save and load configurations as JSON presets (Default, Dense, Large, Small, Sparse, NoToxic, OnlyToxic)
- Animal tracking - pause, click an animal to follow its genome, active gene, energy, plants eaten, children, descendants, age, death day
- Visual highlights - dominant genome animals marked in red, jungle zone shaded green
- CSV export - statistics appended each day, opens in Excel
- Live chart - pick a statistic to plot in real time (animal count, average energy, average lifespan, average children, free fields)
- Map scaling - cell size computed dynamically from window size and map dimensions
src/main/java/agh/ics/oop/
├── model/
│ ├── Animal.java - animal with energy, genome, position, stats
│ ├── Genome.java - genome crossover, mutation, gene cycling
│ ├── Map.java - world state, movement, eating, reproduction
│ ├── Plant.java - normal and toxic plant
│ ├── MapDirection.java - 8-direction enum with rotation and unit vectors
│ ├── SimulationConfig.java - immutable config record with validation
│ ├── SimulationConfigDto.java - DTO for JSON serialization (no resistance genome)
│ ├── SimulationConfigFactory - builds config and generates resistance genome
│ ├── Vector2d.java - 2D integer coordinate
│ ├── WorldElement.java - common interface for animals and plants
│ └── WorldMap.java - map interface
│ └── util/
│ └── MapVisualizer.java - text-based map renderer (used in tests)
├── presenters/
│ ├── ConfigPresenter.java - config window: fields, presets, validation
│ └── SimulationPresenter.java - simulation window: map, stats, tracking
├── statistics/
│ ├── StatisticsTracker.java - computes and stores per-day statistics history
│ └── ChartController.java - live JavaFX line chart
├── view/
│ ├── MapRenderer.java - canvas renderer: grid, animals, plants, jungle, energy bars
│ ├── AnimalStatsUI.java - tracked animal info panel
│ ├── GeneralStatsUI.java - general simulation stats labels
│ └── GuiResources.java - loads animal/plant/toxicPlant images
├── SimulationEngine.java - simulation loop thread, CSV writing
├── PresetService.java - save/load JSON presets via Gson
├── SimulationApp.java - JavaFX app, opens config then simulation window
└── World.java - main entry point
presets/ - built-in JSON configuration presets
src/test/ - JUnit tests
Requirements:
- JDK 25
- Gradle Wrapper (included in repository)
# Linux / macOS
./gradlew run
# Windows
.\gradlew.bat runIn IntelliJ: open the project folder, set SDK to Java 21, run World.java.
The config window opens on startup. All parameters are validated before the simulation starts.
| Parameter | Description |
|---|---|
| Map width / height | Grid dimensions (max 100x100) |
| Starting plant count | Plants placed at day 0 |
| Energy per plant | Energy gained from one normal plant |
| Daily plant growth | New plants spawned each day |
| Starting animal count | Animals placed at day 0 |
| Starting energy | Initial energy per animal |
| Daily energy loss | Energy lost per animal per day |
| Well-fed energy | Minimum energy to be eligible for reproduction |
| Reproduction energy cost | Energy each parent transfers to child |
| Min / max mutations | Range of gene mutations per child |
| Genome length | Number of genes per animal (max 25) |
| Toxic plant probability | 0 = no toxicity (base variant), 1 = all plants toxic |
| Toxic plant energy loss | Base energy loss from eating a toxic plant |
Presets can be saved and loaded from the presets/ folder. The resistance genome is generated fresh each simulation and is not stored in presets.
./gradlew testAnimalTest- energy changes, reproduction energy transfer, child genomeAnimalMovementTest- rotation, movement, orientation after moveEatPlantsTest- normal and toxic plant consumptionMapBoundsTest- horizontal wrapping, pole bounceSortAnimalsTest- animal priority: energy, age, children count