diff --git a/.gitignore b/.gitignore
index a1c2a23..b9e2d42 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
# Package Files #
*.jar
+!gradle/wrapper/gradle-wrapper.jar
*.war
*.nar
*.ear
@@ -21,3 +22,8 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+build/
+.gradle/
+.org.example/
+.DS_Store
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/EvolutionGenerator.iml b/.idea/EvolutionGenerator.iml
new file mode 100644
index 0000000..e2c325a
--- /dev/null
+++ b/.idea/EvolutionGenerator.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..4aadc36
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..736351a
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..fdc392f
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_apiguardian_apiguardian_api_1_1_2.xml b/.idea/libraries/Gradle__org_apiguardian_apiguardian_api_1_1_2.xml
new file mode 100644
index 0000000..ec7423e
--- /dev/null
+++ b/.idea/libraries/Gradle__org_apiguardian_apiguardian_api_1_1_2.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_junit_jupiter_junit_jupiter_api_5_8_1.xml b/.idea/libraries/Gradle__org_junit_jupiter_junit_jupiter_api_5_8_1.xml
new file mode 100644
index 0000000..e4ec376
--- /dev/null
+++ b/.idea/libraries/Gradle__org_junit_jupiter_junit_jupiter_api_5_8_1.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_junit_jupiter_junit_jupiter_engine_5_8_1.xml b/.idea/libraries/Gradle__org_junit_jupiter_junit_jupiter_engine_5_8_1.xml
new file mode 100644
index 0000000..4da4781
--- /dev/null
+++ b/.idea/libraries/Gradle__org_junit_jupiter_junit_jupiter_engine_5_8_1.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_junit_platform_junit_platform_commons_1_8_1.xml b/.idea/libraries/Gradle__org_junit_platform_junit_platform_commons_1_8_1.xml
new file mode 100644
index 0000000..ec1b37e
--- /dev/null
+++ b/.idea/libraries/Gradle__org_junit_platform_junit_platform_commons_1_8_1.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_junit_platform_junit_platform_engine_1_8_1.xml b/.idea/libraries/Gradle__org_junit_platform_junit_platform_engine_1_8_1.xml
new file mode 100644
index 0000000..2940fd5
--- /dev/null
+++ b/.idea/libraries/Gradle__org_junit_platform_junit_platform_engine_1_8_1.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_base_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_base_17.xml
new file mode 100644
index 0000000..44e3c50
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_base_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_base_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_base_win_17.xml
new file mode 100644
index 0000000..460d4db
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_base_win_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_controls_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_controls_17.xml
new file mode 100644
index 0000000..4865e89
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_controls_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_controls_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_controls_win_17.xml
new file mode 100644
index 0000000..c50f1b2
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_controls_win_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_fxml_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_fxml_win_17.xml
new file mode 100644
index 0000000..24ab318
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_fxml_win_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_graphics_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_graphics_17.xml
new file mode 100644
index 0000000..cd21427
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_graphics_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_graphics_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_graphics_win_17.xml
new file mode 100644
index 0000000..b719c2e
--- /dev/null
+++ b/.idea/libraries/Gradle__org_openjfx_javafx_graphics_win_17.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Gradle__org_opentest4j_opentest4j_1_2_0.xml b/.idea/libraries/Gradle__org_opentest4j_opentest4j_1_2_0.xml
new file mode 100644
index 0000000..c0ad60c
--- /dev/null
+++ b/.idea/libraries/Gradle__org_opentest4j_opentest4j_1_2_0.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..34bed90
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..7d93384
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/oolab.iml b/.idea/modules/oolab.iml
new file mode 100644
index 0000000..213d3f3
--- /dev/null
+++ b/.idea/modules/oolab.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/oolab.main.iml b/.idea/modules/oolab.main.iml
new file mode 100644
index 0000000..81e2e95
--- /dev/null
+++ b/.idea/modules/oolab.main.iml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules/oolab.test.iml b/.idea/modules/oolab.test.iml
new file mode 100644
index 0000000..c90d5c8
--- /dev/null
+++ b/.idea/modules/oolab.test.iml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 5dec135..d768145 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,65 @@
# EvolutionGenerator
-Najpiękniejszy generator ewolucyjny
+## Najpiękniejszy generator ewolucyjny, jaki widziała ludzkość.
+
+*Dawno, dawno temu, dawniej niż narodziła się Maryla Rodowicz (tak, da się, też się zdziwiłyśmy!), powstały pierwsze istoty ziemskie. Wciąż wiemy o nich niewiele, jednak umiemy wyobrazić sobie, jak wyglądał proces ich tworzenia. Ba! Umiemy to nawet zaimplementować!*
+
+**EvolutionGenerator** to projekt stworzony na potrzeby przedmiotu "Programowanie Obiektowe" na kierunku Informatyka na Akademii Górniczo-Hutniczej. Autorkami programu są **Aleksandra Smela oraz Julia Smerdel**.
+
+Program to symulacja ewolucji, która pozwala zobaczyć proces rozwoju zwierząt w zależności od wybranych wariantów świata, umożliwia śledzenie ich statystyk oraz zapisywanie danych do plików CSV. Więcej szczegółów można znaleźć pod linkiem: https://github.com/apohllo/obiektowe-lab/tree/master/proj1 .
+
+
+
+## Jak wczytywać dane do pliku?
+Jak dobrze wiemy, wiele zdarzeń zależy od fazy księżyca, ułożenia gwiazd na nieboskłonie czy tego, którą nogą wstała dzisiaj Pani Basia, która jest sprzedawczynią w naszym ulubionym sklepie.
+Nasz program uwzględnia prawie wszystkie te możliwości, a bynajmniej niektóre z nich. No kilka. Ale takie ważniejsze.
+
+**Dostępne warianty:**
+- MAPA: GlobMap, HellMap;
+- ZALESIANIE: ForestedEquators, ToxicCorpses;
+- MUTACJE: LittleAdjustment, TotalRandom;
+- ZACHOWANIE GENÓW: PredestinationBehavior, HijinksBehavior;
+
+Aby zobaczyć stworzony przez nas cud technologiczny, należy stworzyć plik CSV (polecamy np.: program Excel), w którym umieścimy dane do naszej symulacji. **Kolejność wpisywania danych jest istotna.** Poniżej znajduje się przykładowy plik z konfiguracją:
+
+[TestPO.csv](https://github.com/smelaa/EvolutionGenerator/files/10328324/TestPO.csv)
+
+Kolejność wpisywania danych:
+1) wariant mapy
+2) wariant zalesiania
+3) wariant mutacji
+4) wariant zachowania genów
+5) wysokość mapy
+6) szerokość mapy
+7) energia uzyskana przez zjedzenie trawy
+8) minimalna energia potrzebna do stworzenia potomka
+9) startowa energia zwierząt
+10) dzienny koszt życia zwierząt
+11) liczba zwierząt na start
+12) liczba trawy rosnąca każdego dnia
+13) czas odświeżania symulacji (wartość podawana w milisekundach)
+14) długość genomu
+15) true/false
+
+*Ad 15)* jeśli chcemy, aby statystyki z każdego dnia symulacji zapisywane były w nowym pliku CSV, konieczne jest wpisanie w tym polu wartości *true*. Wtedy w argumencie 16) podajemy również ścieżkę do stworzonego już przez nas pliku.
+
+Gdy nie chcemy zapisywać statystyk do oddzielnego pliku, w argumencie 15) wpisujemy wartość *false* (nie wypełniamy już argumentu 16) ).
+
+
+## Co, jak, z czym
+Gdyby do kogoś nie przemówił rożowy, piękny kolor gui, spieszymy z pomocą i tłumaczymy, z czym to się je. Ale od początku.
+
+Po wpisaniu ścieżki do pliku, wyświetla się najcudowniejsze okno dialogowe. W lewym górnym rogu znajdują się dwa przyciski: PLAY oraz PAUSE. Jak nazwa wskazuje, przycisk PAUSE odpowiada za zapauzowanie symulacji, a przycisk PLAY za jej wznowienie.
+Pod spodem zaś umieszczone są statystyki symulacji oraz statystyki aktualnie śledzonego zwierzaczka (zwierzaczki są okrąglutkie - ale to samo futerko! Nasze zwierzaczki są fit, nie są grubaskami, zapewniamy!). Aby zacząć śledzić zwierzaka, wystarczy kliknąć na niego lewym przyciskiem myszy - wtedy zwierzako-kulka zmieni kolor na zielony.
+Zwierzaki z najpopularniejszym genomem wyróżnione są za pomocą żółtego obramowania.
+Po prawej stronie, nie do przeoczenia ze względu na swą wyjątkowość, estetykę i inne arybuty, widoczna jest mapa. To właśnie na niej można śledzić symulację.
+Pod mapą znajduje się przycisk STOP SIMULATION, który zatrzymuje symulację (innymi słowy: na mapę spada ogromny meteoryt , który niszczy wszystko i wszystkich wokół. Gdy naciśniesz ten przycisk, nie ma odwrotu - papa zwierzako-kulki. Klikasz na własną odpowiedzialność).
+
+
+
+## Filmiki:
+https://www.youtube.com/watch?v=dQw4w9WgXcQ
+
+https://youtu.be/XY8TYyofOXM
+
+
+
diff --git a/oolab/build.gradle b/oolab/build.gradle
new file mode 100644
index 0000000..940eaa3
--- /dev/null
+++ b/oolab/build.gradle
@@ -0,0 +1,38 @@
+plugins {
+ id 'application'
+ id 'java'
+ id 'org.openjfx.javafxplugin' version '0.0.13'
+}
+
+group 'org.example'
+version '1.0-SNAPSHOT'
+
+repositories {
+ mavenCentral()
+ javafx {
+ version = "17"
+ modules = [ 'javafx.controls', 'javafx.fxml' ]
+ }
+}
+
+
+
+dependencies {
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
+}
+
+
+test {
+ useJUnitPlatform()
+}
+
+application {
+ getMainClass().set('agh.ics.oop.World')
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(17))
+ }
+}
\ No newline at end of file
diff --git a/oolab/gradle/wrapper/gradle-wrapper.properties b/oolab/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..41dfb87
--- /dev/null
+++ b/oolab/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/oolab/gradlew b/oolab/gradlew
new file mode 100644
index 0000000..1b6c787
--- /dev/null
+++ b/oolab/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/oolab/gradlew.bat b/oolab/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/oolab/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/oolab/settings.gradle b/oolab/settings.gradle
new file mode 100644
index 0000000..8ae9f74
--- /dev/null
+++ b/oolab/settings.gradle
@@ -0,0 +1,2 @@
+rootProject.name = 'oolab'
+
diff --git a/oolab/src/main/java/agh/ics/oop/Animal.java b/oolab/src/main/java/agh/ics/oop/Animal.java
new file mode 100644
index 0000000..30b9448
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/Animal.java
@@ -0,0 +1,162 @@
+package agh.ics.oop;
+
+import agh.ics.oop.gui.MainViewController;
+import javafx.event.EventHandler;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import java.util.Random;
+import static java.lang.Math.round;
+
+public class Animal {
+ protected Direction orientation;
+ protected Vector2d position;
+ protected int energy;
+ public Direction[] genes;
+ protected int activeGeneIx;
+ protected int grassEaten=0;
+ protected int diedDate=0;
+ protected int age=0;
+ protected int children=0;
+ private Map map;
+
+ //konstruktor dla Adama i Ewy
+ public Animal(SimulationVar var,Map map) {
+ this.map=map;
+ Random generator = new Random();
+ orientation=Direction.numberToDirection(generator.nextInt(8));
+ position=new Vector2d(generator.nextInt(var.getMapWidth()), generator.nextInt(var.getMapHeight()));
+ energy=var.getAnimalStartEnergy();
+ genes= new Direction[var.getGenomeLength()];
+ for (int i=0;iother.getEnergy()){return true;}
+ return false;
+ }
+
+ public int genesToSucceed(Animal other){
+ return round(energy/(other.getEnergy()+energy)*genes.length);
+ }
+
+ public Circle getImage(Double size, MainViewController follower) {
+ Color color;
+ try{
+ color=new Color((double) (map.getMaxEnergy() - energy) /map.getMaxEnergy(),0, (double) energy /map.getMaxEnergy(),1);
+ }
+ catch(Exception ex){color=Color.BLACK; ex.printStackTrace(); ex.printStackTrace();}
+ Circle circle = new Circle(size/2, color);
+ if (genesToString().equals(map.getTheMostPopularGenome())){
+ circle.setStroke(Color.valueOf("#fff705"));
+ }
+ circle.setOnMousePressed(new EventHandler() {
+ @Override
+ public void handle(MouseEvent event) {
+ followMe(follower);
+ }
+ });
+ return circle;
+ }
+ public Map getMap() {
+ return map;
+ }
+
+ public int getAge(){
+ return age;
+ }
+ private void followMe(MainViewController follower){follower.follow(this);}
+
+ public String genesToString(){
+ String genome = "";
+ for (Direction gene : genes){
+ genome += gene.toString();
+ }
+ return genome;
+ }
+
+ public Direction getActiveJeans(){
+ return genes[activeGeneIx];
+ }
+ public int getGrassEaten() {
+ return grassEaten;
+ }
+ public int getChildren() {
+ return children;
+ }
+
+ public String diedDateToString() {
+ if (diedDate==0){return "I'm still standing";}
+ else{return String.valueOf(diedDate);}
+ }
+
+ public String ageToString(){
+ if (diedDate==0){return String.valueOf(age);}
+ else{return "Another one bites a dust";}
+ }
+
+ public boolean isAlive(){
+ return diedDate==0;
+ }
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/Direction.java b/oolab/src/main/java/agh/ics/oop/Direction.java
new file mode 100644
index 0000000..6405e1b
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/Direction.java
@@ -0,0 +1,88 @@
+package agh.ics.oop;
+
+public enum Direction {
+ NORTH,
+ NORTHEAST,
+ EAST,
+ SOUTHEAST,
+ SOUTH,
+ SOUTHWEST,
+ WEST,
+ NORTHWEST;
+
+ public Vector2d toUnitVector(){
+ return switch(this){
+ case NORTH -> new Vector2d(0,1);
+ case NORTHEAST -> new Vector2d(1,1);
+ case EAST -> new Vector2d(1,0);
+ case SOUTHEAST -> new Vector2d(1,-1);
+ case SOUTH -> new Vector2d(0,-1);
+ case SOUTHWEST -> new Vector2d(-1,-1);
+ case WEST -> new Vector2d(-1,0);
+ case NORTHWEST -> new Vector2d(-1,1);
+ default -> null;
+ };
+ }
+
+ public int toNumber(){
+ return switch(this){
+ case NORTH -> 0;
+ case NORTHEAST -> 1;
+ case EAST -> 2;
+ case SOUTHEAST -> 3;
+ case SOUTH -> 4;
+ case SOUTHWEST -> 5;
+ case WEST -> 6;
+ case NORTHWEST -> 7;
+ };
+ }
+
+ public String toString(){
+ return switch(this){
+ case NORTH -> "0";
+ case NORTHEAST -> "1";
+ case EAST -> "2";
+ case SOUTHEAST -> "3";
+ case SOUTH -> "4";
+ case SOUTHWEST -> "5";
+ case WEST -> "6";
+ case NORTHWEST -> "7";
+ };
+ }
+ public static Direction numberToDirection(int n){
+ return switch(n%8){
+ case 0 -> NORTH;
+ case 1 -> NORTHEAST;
+ case 2 -> EAST;
+ case 3 -> SOUTHEAST;
+ case 4 -> SOUTH;
+ case 5 -> SOUTHWEST;
+ case 6 -> WEST;
+ case 7 -> NORTHWEST;
+ default -> NORTH;
+ };
+ }
+
+ public Direction add(int n){
+ int sumInt=this.toNumber()+n;
+ return numberToDirection(sumInt);
+ }
+
+ public Direction add(Direction d){
+ int sumInt=this.toNumber()+d.toNumber();
+ return numberToDirection(sumInt);
+ }
+
+ public Direction opposite(Direction direction){
+ return switch(direction){
+ case NORTH -> SOUTH;
+ case NORTHEAST -> SOUTHWEST;
+ case EAST -> WEST;
+ case SOUTHEAST -> NORTHWEST;
+ case SOUTH -> NORTH;
+ case SOUTHWEST -> NORTHEAST;
+ case WEST -> EAST;
+ case NORTHWEST -> SOUTHEAST;
+ };
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/FileMenager.java b/oolab/src/main/java/agh/ics/oop/FileMenager.java
new file mode 100644
index 0000000..ee95cae
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/FileMenager.java
@@ -0,0 +1,57 @@
+package agh.ics.oop;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Objects;
+
+public final class FileMenager {
+ private String filename;
+
+ public FileMenager() {
+ this.filename = "oolab/src/main/resources/defaultfile.csv";
+ }
+
+ public void setFileName(String filename) throws IOException {
+ this.filename = filename;
+ PrintWriter output = new PrintWriter(new FileWriter(filename));
+ output.println("AllAnimals;AllPlants;FreeSpots;MostPopularGenotype;AverageEnergyAlive;AverageAgeDead");
+ output.flush();
+ }
+
+ public void dayStats(Object[] statistics) {
+ StringBuilder stringBuilder = new StringBuilder(); //takie cuś do łączenia stringów
+ for (int i=0;i prefferedSpots=new ArrayList<>();
+ ArrayList restOfSpots=new ArrayList<>();
+ //stworzymy tablicę preffered spots
+ //stworzymy tablicę rest of spots
+ //wylosujemy liczbę od 0 do 9
+ //w zaleznosci od wylosowanej liczby wylosujemy vector z jednej z tablic
+ //jezeli dana tablica jest pusta to wylosujemy z drugiej
+ //zasadzimy trawke
+ for (int x=0;x0) ||prefferedSpots.size()==0){
+ int ix=generator.nextInt(restOfSpots.size());
+ newGrassPosition=restOfSpots.remove(ix);
+ }
+ else{
+ int ix=generator.nextInt(prefferedSpots.size());
+ newGrassPosition=prefferedSpots.remove(ix);
+ }
+ Grass newGrass= new Grass(newGrassPosition);
+ map.addGrass(newGrass);
+ }
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/GlobMap.java b/oolab/src/main/java/agh/ics/oop/GlobMap.java
new file mode 100644
index 0000000..6f111c2
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/GlobMap.java
@@ -0,0 +1,58 @@
+package agh.ics.oop;
+
+public class GlobMap implements IMapType{
+
+
+ @Override
+ public void moveOnMap(Animal animal, SimulationVar var, Map map){
+
+ var.getBehaviorModel().geneBehaviour(animal);
+
+ //jeśli zwierzę może się poruszyć
+ if (animal.energy - var.getDailyEnergyCost() >= 0){
+ animal.energy -= var.getDailyEnergyCost();
+ changeAnimalPosition(animal, var, map); //zmiana pozycji
+
+ }
+ else{
+ animal.diedDate = animal.age;
+ map.setDiedAnimals(map.getDiedAnimals() + 1);
+ map.addToDiedList(animal);
+ }
+
+
+
+ }
+
+ protected void changeAnimalPosition(Animal animal, SimulationVar var, Map map){
+ Direction[] genes = animal.genes;
+ int currGeneIdx = animal.activeGeneIx;
+ int mapHeight = var.getMapHeight();
+ int mapWidth = var.getMapHeight();
+
+ //o ten wektor się poruszamy
+ Vector2d vectorToMove = genes[currGeneIdx].toUnitVector();
+ Vector2d posAfterMovement = animal.position.add(vectorToMove);
+
+
+ if (posAfterMovement.y < 0 || posAfterMovement.y >= mapHeight){
+ animal.orientation = animal.orientation.opposite(animal.orientation);
+ posAfterMovement = animal.position;
+ }
+ //czy równik
+ else if (posAfterMovement.x >= mapWidth || posAfterMovement.x < 0){
+ if (posAfterMovement.x >= mapWidth){
+ Vector2d vector = new Vector2d(0, posAfterMovement.y);
+ posAfterMovement = vector;
+
+ }
+ else{
+ Vector2d vector = new Vector2d(mapWidth - 1, posAfterMovement.y);
+ posAfterMovement = vector;
+ }
+ }
+
+ map.setAnimalsOnField(animal.getPosition(), posAfterMovement);
+ animal.changePosition(posAfterMovement);
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/Grass.java b/oolab/src/main/java/agh/ics/oop/Grass.java
new file mode 100644
index 0000000..360c3c6
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/Grass.java
@@ -0,0 +1,11 @@
+package agh.ics.oop;
+
+public class Grass {
+ private Vector2d position;
+ public Grass(Vector2d position){
+ this.position=position;
+ }
+ public Vector2d getPosition() {
+ return position;
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/HellMap.java b/oolab/src/main/java/agh/ics/oop/HellMap.java
new file mode 100644
index 0000000..ff7353d
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/HellMap.java
@@ -0,0 +1,52 @@
+package agh.ics.oop;
+
+import java.util.Random;
+
+public class HellMap implements IMapType {
+ @Override
+ public void moveOnMap(Animal animal, SimulationVar var, Map map){
+
+ var.getBehaviorModel().geneBehaviour(animal);
+
+ //jeśli zwierzę może się poruszyć
+ if (animal.energy - var.getDailyEnergyCost() >= 0){
+ animal.energy -= var.getDailyEnergyCost();
+ changeAnimalPosition(animal, var, map); //zmiana pozycji
+
+ }
+ else{
+ animal.diedDate = animal.getAge();
+ map.setDiedAnimals(map.getDiedAnimals() + 1);
+ map.addToDiedList(animal);
+ }
+ }
+
+ protected void changeAnimalPosition(Animal animal, SimulationVar var, Map map){
+ Direction[] genes = animal.genes;
+ int currGeneIdx = animal.activeGeneIx;
+ int mapHeight = var.getMapHeight();
+ int mapWidth = var.getMapHeight();
+
+ //o ten wektor się poruszamy
+ Vector2d vectorToMove = genes[currGeneIdx].toUnitVector();
+ Vector2d posAfterMovement = animal.position.add(vectorToMove);
+
+
+ if (posAfterMovement.y < 0 || posAfterMovement.y >= mapHeight || posAfterMovement.x >= mapWidth || posAfterMovement.x < 0) {
+ if (animal.energy - var.getMinEnergyForCopulation() >= 0) {
+ animal.energy -= var.getMinEnergyForCopulation();
+ Random generator = new Random();
+ posAfterMovement = new Vector2d(generator.nextInt(mapWidth), generator.nextInt(mapHeight));
+ }
+ else{
+ animal.diedDate = animal.age;
+ map.setDiedAnimals(map.getDiedAnimals() + 1);
+ map.addToDiedList(animal);
+ return;
+ }
+ }
+ map.setAnimalsOnField(animal.getPosition(), posAfterMovement);
+ animal.changePosition(posAfterMovement);
+ }
+}
+
diff --git a/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java b/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java
new file mode 100644
index 0000000..dc85439
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java
@@ -0,0 +1,23 @@
+package agh.ics.oop;
+
+import java.util.Random;
+
+public class HijinksBehavior implements IBehaviorModel{
+ @Override
+ public void geneBehaviour(Animal animal){
+ //losujemy liczbę od 0 do 9
+ //w zależności od tego albo porusza się normalnie, albo losujemy
+ Random generator = new Random();
+ if (generator.nextInt(10) < 2){
+ animal.activeGeneIx = generator.nextInt(animal.genes.length);
+ }
+ else{
+ if (animal.activeGeneIx + 1 >= animal.genes.length){
+ animal.activeGeneIx = 0;
+ }
+ else{
+ animal.activeGeneIx += 1;
+ }
+ }
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java b/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java
new file mode 100644
index 0000000..3cd7080
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java
@@ -0,0 +1,6 @@
+package agh.ics.oop;
+
+
+public interface IBehaviorModel {
+ void geneBehaviour(Animal animal);
+}
diff --git a/oolab/src/main/java/agh/ics/oop/IHolyGardener.java b/oolab/src/main/java/agh/ics/oop/IHolyGardener.java
new file mode 100644
index 0000000..ba8847f
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/IHolyGardener.java
@@ -0,0 +1,7 @@
+package agh.ics.oop;
+
+import java.util.HashSet;
+
+public interface IHolyGardener {
+ void seedGrass(SimulationVar var, Map map);
+}
diff --git a/oolab/src/main/java/agh/ics/oop/IMapType.java b/oolab/src/main/java/agh/ics/oop/IMapType.java
new file mode 100644
index 0000000..346f683
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/IMapType.java
@@ -0,0 +1,6 @@
+package agh.ics.oop;
+
+public interface IMapType {
+ void moveOnMap(Animal animal, SimulationVar var, Map map);
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/IMutationModel.java b/oolab/src/main/java/agh/ics/oop/IMutationModel.java
new file mode 100644
index 0000000..1392610
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/IMutationModel.java
@@ -0,0 +1,5 @@
+package agh.ics.oop;
+
+public interface IMutationModel {
+ void mutate(Animal child);
+}
diff --git a/oolab/src/main/java/agh/ics/oop/LittleAdjustment.java b/oolab/src/main/java/agh/ics/oop/LittleAdjustment.java
new file mode 100644
index 0000000..38b4d6c
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/LittleAdjustment.java
@@ -0,0 +1,34 @@
+package agh.ics.oop;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+public class LittleAdjustment implements IMutationModel{
+ @Override
+ public void mutate(Animal child) {
+ Random generator = new Random();
+ int mutationsNumber=generator.nextInt(child.genes.length);
+ List toMutate= new ArrayList<>();
+ for (int i = 0; i < child.genes.length; i++){toMutate.add(child.genes[i].toNumber());}
+ for (int i = 0; i < mutationsNumber; i++){
+ int ix= generator.nextInt(toMutate.size());
+ if (generator.nextBoolean()){
+ if (child.genes[ix].toNumber() == 7){
+ child.genes[ix] = Direction.NORTH;
+ }
+ else{
+ child.genes[ix]=Direction.numberToDirection(toMutate.get(ix) + 1);
+ }
+ }
+ else{
+ if(child.genes[ix].toNumber() == 0){
+ child.genes[ix] = Direction.NORTHWEST;
+ }
+ child.genes[ix]=Direction.numberToDirection(toMutate.get(ix) - 1);
+ }
+ }
+
+ }
+
+}
+
diff --git a/oolab/src/main/java/agh/ics/oop/Map.java b/oolab/src/main/java/agh/ics/oop/Map.java
new file mode 100644
index 0000000..44abd18
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/Map.java
@@ -0,0 +1,149 @@
+package agh.ics.oop;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class Map {
+ private HashMap grassOnField = new HashMap<>();
+ private int diedAnimals = 0;
+ private ArrayList animalsOnField=new ArrayList<>(); //wszystkie zwierzątka na mapie
+ private HashMap numberOfAnimalsOnField = new HashMap<>(); //pamietac zeby przy move zmieniac wartosc w tej hashmapie
+ private ArrayList diedAnimalsOnMap = new ArrayList<>();
+ private Statistics stats;
+ private int height;
+ private int width;
+ private IMapType map;
+ private int maxEnergy=0;
+
+ //Big Bang
+ public Map(SimulationVar var) {
+ height=var.getMapHeight();
+ width= var.getMapWidth();
+ map = var.getMapType();
+ stats=new Statistics(this);
+ updateMaxEnergy();
+ for (int i=0;i 0){
+ numberOfAnimalsOnField.put(oldSpot, old - 1); //usuwamy ze starego miejsca
+ }
+
+
+ Integer animalsOnSpot=numberOfAnimalsOnField.remove(newSpot);
+ if (animalsOnSpot == null){animalsOnSpot=0;}
+ numberOfAnimalsOnField.put(newSpot, animalsOnSpot + 1); //dodajemy do nowego miejsca
+ }
+
+ protected void removeAnimal(Animal animal){
+ animalsOnField.remove(animal); //usunięcie z listy zwierząt
+ stats.removeGenesToGenomes(animal.genesToString());
+ int tmp = numberOfAnimalsOnField.remove(animal.getPosition());
+ if (tmp - 1 != 0){
+ numberOfAnimalsOnField.put(animal.getPosition(), tmp - 1);
+ }
+ }
+ protected int howManyAnimalsOnSpot(Vector2d spot){ //zwraca liczbę zwierzątek na danych polu
+ return numberOfAnimalsOnField.get(spot);
+
+ }
+
+ protected ArrayList getAnimalsOnField(){
+ return this.animalsOnField;
+ }
+ public boolean isGrassThere(Vector2d spot){
+ return grassOnField.containsKey(spot);
+ }
+
+ public boolean isAnimalThere(Vector2d spot){ return (numberOfAnimalsOnField.containsKey(spot) && numberOfAnimalsOnField.get(spot)>0);}
+
+ //tego też się wstydzimy
+ public ArrayList getAnimalsOnSpot(Vector2d spot){
+ ArrayList animalsOnSpot=new ArrayList();
+ for (Animal animal: animalsOnField){
+ if (animal.getPosition().equals(spot)){
+ animalsOnSpot.add(animal);
+ }
+ }
+ return animalsOnSpot;
+ }
+ public Animal getAnimalOnSpot(Vector2d spot){
+ for (Animal animal: animalsOnField){
+ if (animal.getPosition().equals(spot)){
+ return animal;
+ }
+ }
+ return null;
+ }
+
+ protected int getDiedAnimals(){
+ return diedAnimals;
+ }
+
+ protected void setDiedAnimals(int n){
+ diedAnimals = n;
+ }
+
+ protected HashMap getAnimalsOnEachSpot(){
+ return numberOfAnimalsOnField;
+ }
+
+ protected ArrayList getDiedAnimalsOnMap(){
+ return diedAnimalsOnMap;
+ }
+
+ protected void addToDiedList(Animal animal){
+ diedAnimalsOnMap.add(animal);
+ }
+
+ protected void removeGrass(Grass grass){
+ if (grassOnField.get(grass.getPosition())!= null) {
+ grassOnField.remove(grass.getPosition());
+ }
+ }
+
+ public Statistics getStats() {
+ return stats;
+ }
+ public int getHeight() {
+ return height;
+ }
+ public int getWidth() {
+ return width;
+ }
+ public int getNumberOfGrassOnField() {
+ return grassOnField.size();
+ }
+
+ public int getMaxEnergy() {
+ return maxEnergy;
+ }
+
+ public void updateMaxEnergy() {
+ maxEnergy=stats.maxEnergyAlive();
+ }
+
+ public HashMap getGrassOnField() {
+ return grassOnField;
+ }
+
+ public String getTheMostPopularGenome(){
+ return stats.getTheMostPopularGenome();
+ }
+}
\ No newline at end of file
diff --git a/oolab/src/main/java/agh/ics/oop/OptionsParser.java b/oolab/src/main/java/agh/ics/oop/OptionsParser.java
new file mode 100644
index 0000000..c8539a0
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/OptionsParser.java
@@ -0,0 +1,30 @@
+package agh.ics.oop;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+public class OptionsParser {
+ public SimulationVar parse(String filePath) throws FileNotFoundException, IllegalArgumentException {
+ try {
+ Paths.get(filePath);
+ Scanner scanner = new Scanner(new File(filePath));
+ scanner.useDelimiter(";");
+ ArrayList variables = new ArrayList();
+ while (scanner.hasNext()) {
+ variables.add(scanner.next());
+ }
+ return new SimulationVar(variables);
+
+ } catch (InvalidPathException | NullPointerException | FileNotFoundException ex) {
+ throw new FileNotFoundException();
+ }catch(IllegalArgumentException ex){
+ throw new IllegalArgumentException();
+ }
+
+ }
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java b/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java
new file mode 100644
index 0000000..1a49044
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java
@@ -0,0 +1,13 @@
+package agh.ics.oop;
+
+public class PredestinationBehavior implements IBehaviorModel{
+ @Override
+ public void geneBehaviour(Animal animal){
+ if (animal.activeGeneIx + 1 >= animal.genes.length){
+ animal.activeGeneIx = 0;
+ }
+ else{
+ animal.activeGeneIx += 1;
+ }
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/SimulationEngine.java b/oolab/src/main/java/agh/ics/oop/SimulationEngine.java
new file mode 100644
index 0000000..cc2aab7
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/SimulationEngine.java
@@ -0,0 +1,155 @@
+package agh.ics.oop;
+
+import agh.ics.oop.gui.MainViewApp;
+import javafx.application.Platform;
+import java.util.ArrayList;
+import java.util.Comparator;
+
+
+public class SimulationEngine implements Runnable{
+ SimulationVar variables;
+ private Map map;
+ private int howManyDays = 0;
+ private MainViewApp observer;
+ private boolean threadSuspended=false;
+ private boolean interrupted=false;
+ public SimulationEngine(SimulationVar variables, MainViewApp observer){
+ this.map = new Map(variables);
+ this.variables = variables;
+ this.observer=observer;
+ }
+
+ public void dayRitual(){
+ howManyDays += 1;
+ //korowód
+ ArrayList diedAnimalsToday = new ArrayList<>();
+
+ for (Animal animal: map.getAnimalsOnField()){
+ if (animal.diedDate != 0){
+ diedAnimalsToday.add(animal);
+ }
+ }
+ for (Animal animal : diedAnimalsToday){
+ map.removeAnimal(animal);
+ }
+
+ //poruszamy wszystkie zwierzątka
+ for (Animal animal:map.getAnimalsOnField()){
+ animal.age += 1;
+ variables.getMapType().moveOnMap(animal, variables, map);
+
+ }
+
+ ArrayList animals = map.getAnimalsOnField();
+ animals.sort(Comparator.comparingInt(el -> el.position.x).thenComparingInt(el -> el.position.y));
+ Vector2d lastVector = new Vector2d(10^9, 10^9);
+ int lastIndex = 0;
+
+ //jedzonko i rozmnażanie
+ ArrayList babies = new ArrayList();
+ for (Animal animal: map.getAnimalsOnField()){
+ if (!animal.getPosition().equals(lastVector)){ //jeśli wektor zwierzątka nie jest identyczny do ostatniego -> aby nie sprawdzac kilka razy tej samej pozycji zwierząt
+ lastVector = animal.getPosition();
+ if (map.howManyAnimalsOnSpot(animal.getPosition())!= 1){ //jeśli jest wiecej niż 1 zwierze na danym polu
+
+ int howManyOnThisSpot = map.howManyAnimalsOnSpot(animal.getPosition());
+
+ ArrayList possibleMatch = new ArrayList<>();
+ for(int i = 0; i < howManyOnThisSpot; i++){
+ possibleMatch.add(animals.get(i + lastIndex));
+ }
+ possibleMatch.sort(Comparator.comparingInt(el -> -el.energy).thenComparingInt(el -> -el.age).thenComparingInt(el -> -el.children));
+ lastIndex = howManyOnThisSpot;
+ Animal winner = possibleMatch.get(0); //wygrał trawkę
+
+ if (map.isGrassThere(winner.position)) {
+ winner.energy += variables.getGrassEnergyProfit();
+ winner.grassEaten += 1;
+ map.removeGrass(new Grass(winner.position));
+ }
+
+ for (int i = 1; i < possibleMatch.size(); i+=2){
+ Animal first = possibleMatch.get(i-1);
+ Animal second = possibleMatch.get(i);
+ if (first.energy >= variables.getMinEnergyForCopulation() && second.energy >= variables.getMinEnergyForCopulation()) {
+ Animal baby = new Animal(variables, first, second); //nowe bobo
+ babies.add(baby);
+ }
+ }
+ }
+
+ else{
+ if (map.isGrassThere(animal.position)) {
+ animal.energy += variables.getGrassEnergyProfit();
+ animal.grassEaten += 1;
+ map.removeGrass(new Grass(animal.position));
+ }
+
+ }
+
+ }
+
+ }
+ for (Animal baby: babies){
+ map.placeAnimalOnMap(baby); //umieszczamy na mapie
+ }
+
+
+
+ //zasianie roślin
+ variables.getGardener().seedGrass(variables, map);
+ //update informacji o maksymalnej enrgii
+ map.updateMaxEnergy();
+ observer.newDayUpdate();
+ }
+
+ protected int getDays(){
+ return howManyDays;
+ }
+ public void pause(){
+ threadSuspended=true;
+ }
+ public void play(){
+ if (threadSuspended) {
+ threadSuspended = false;
+ synchronized(this) {
+ notify();
+ }
+ }
+ }
+ public void stop(){
+ interrupted=true;
+ }
+
+ @Override
+ public void run() {
+
+ while(map.getStats().getAmountOfAnimals()>0 && !interrupted){
+ Platform.runLater(()->{dayRitual();});
+ Platform.runLater(()->{observer.newDayUpdate();});
+ Platform.runLater(()->{
+ if (variables.isPrintToFile()){map.getStats().printToFile(variables.getFileMenager());}
+ });
+ try {
+ Thread.sleep(variables.getRefreshTime());
+ synchronized(this) {
+ while (threadSuspended)
+ wait();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ Thread.currentThread().interrupt();
+ Platform.runLater(()->{observer.showEndScene();});
+ }
+
+ public Statistics getMapStats(){return map.getStats();}
+ public Map getMap() {
+ return map;
+ }
+ public int getHowManyDays() {
+ return howManyDays;
+ }
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/SimulationVar.java b/oolab/src/main/java/agh/ics/oop/SimulationVar.java
new file mode 100644
index 0000000..e81d9ca
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/SimulationVar.java
@@ -0,0 +1,144 @@
+package agh.ics.oop;
+
+import java.io.IOException;
+import java.util.List;
+
+public class SimulationVar {
+ private final IMapType mapType;
+ private final IHolyGardener gardener;
+ private final IMutationModel mutationModel;
+ private final IBehaviorModel behaviorModel;
+ private final boolean printToFile;
+ private final FileMenager fileMenager=new FileMenager();
+ private final int mapHeight;
+ private final int mapWidth;
+ private final int grassEnergyProfit;
+ private final int minEnergyForCopulation;
+ private final int animalStartEnergy;
+ private final int dailyEnergyCost;
+ private final int animalsAtStart;
+ private final int grassSpawnedEveryday;
+ private final int refreshTime;
+ private final int genomeLength;
+ //bardzo brzydkie, aż nam wstyd:(
+ public SimulationVar(List var) throws IllegalArgumentException{
+ if (var.size()!=15 && var.size()!=16){throw new IllegalArgumentException("wrong number of arguments");}
+ switch(var.get(14)){
+ case "false"->{
+ if (var.size()==16){throw new IllegalArgumentException("wrong number of arguments");}
+ printToFile=false;
+ }
+ case "true"-> {
+ if (var.size()!=16){throw new IllegalArgumentException("wrong number of arguments");}
+ printToFile=true;
+ try{
+ fileMenager.setFileName(var.get(15));
+ }
+ catch(IOException ex){throw new IllegalArgumentException("wrong argument");}
+ }
+ default -> throw new IllegalArgumentException("wrong argument");
+ }
+ switch(var.get(0)){
+ case "GlobMap"->this.mapType=new GlobMap();
+ case "HellMap"->this.mapType=new HellMap();
+ default -> throw new IllegalArgumentException("wrong argument");
+ }
+ switch(var.get(1)){
+ case "ToxicCorpses"->this.gardener=new ToxicCorpses();
+ case "ForestedEquators"->this.gardener=new ForestedEquators();
+ default -> throw new IllegalArgumentException("wrong argument");
+ }
+ switch(var.get(2)){
+ case "LittleAdjustment"->this.mutationModel=new LittleAdjustment();
+ case "TotalRandom"->this.mutationModel=new TotalRandom();
+ default -> throw new IllegalArgumentException("wrong argument");
+ }
+ switch(var.get(3)){
+ case "HijinksBehavior"->this.behaviorModel=new HijinksBehavior();
+ case "PredestinationBehavior"->this.behaviorModel=new PredestinationBehavior();
+ default -> throw new IllegalArgumentException("wrong argument");
+ }
+ Integer[] ints=new Integer[10];
+ for (int i=4;i<14;i++){
+ try {
+ if (Integer.parseInt(var.get(i))<=0){throw new IllegalArgumentException("wrong argument");}
+ ints[i-4]= Integer.parseInt(var.get(i));
+ }
+ catch (NumberFormatException e) {throw new IllegalArgumentException("wrong argument");}
+ }
+ this.mapHeight=ints[0];
+ this.mapWidth=ints[1];
+ this.grassEnergyProfit=ints[2];
+ this.minEnergyForCopulation=ints[3];
+ this.animalStartEnergy=ints[4];
+ this.dailyEnergyCost=ints[5];
+ this.animalsAtStart=ints[6];
+ this.grassSpawnedEveryday=ints[7];
+ this.refreshTime=ints[8];
+ this.genomeLength=ints[9];
+ }
+
+
+ public IMapType getMapType() {
+ return mapType;
+ }
+
+ public IHolyGardener getGardener() {
+ return gardener;
+ }
+
+ public IMutationModel getMutationModel() {
+ return mutationModel;
+ }
+
+ public IBehaviorModel getBehaviorModel() {
+ return behaviorModel;
+ }
+
+ public int getMapHeight() {
+ return mapHeight;
+ }
+
+ public int getMapWidth() {
+ return mapWidth;
+ }
+
+ public int getGrassEnergyProfit() {
+ return grassEnergyProfit;
+ }
+
+ public int getMinEnergyForCopulation() {
+ return minEnergyForCopulation;
+ }
+
+ public int getAnimalStartEnergy() {
+ return animalStartEnergy;
+ }
+
+ public int getDailyEnergyCost() {
+ return dailyEnergyCost;
+ }
+
+ public int getAnimalsAtStart() {
+ return animalsAtStart;
+ }
+
+ public int getGrassSpawnedEveryday() {
+ return grassSpawnedEveryday;
+ }
+
+ public int getRefreshTime() {
+ return refreshTime;
+ }
+
+ public int getGenomeLength() {
+ return genomeLength;
+ }
+ public boolean isPrintToFile() {
+ return printToFile;
+ }
+ public FileMenager getFileMenager() {
+ return fileMenager;
+ }
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/Statistics.java b/oolab/src/main/java/agh/ics/oop/Statistics.java
new file mode 100644
index 0000000..b434b71
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/Statistics.java
@@ -0,0 +1,127 @@
+package agh.ics.oop;
+
+
+import java.util.Collections;
+import java.util.HashMap;
+
+import static java.lang.Math.max;
+
+public class Statistics {
+ private Map map;
+
+ private HashMap diedAnimals=new HashMap();
+ private HashMap genomes=new HashMap();
+ private String theMostPopularGenome="";
+
+ public Statistics(Map map) {
+ this.map=map;
+ for(int x=0;x getDiedAnimals() {
+ return diedAnimals;
+ }
+
+ public int getAmountOfAnimals(){ //liczba wszystkich zwierząt na mapie
+ return map.getAnimalsOnField().size();
+ }
+
+ //liczba wszystkich roślin
+ public int getAmountOfGrass(){
+ return map.getNumberOfGrassOnField();
+ }
+
+ //liczba wolnych pól (t pole, gdzie nie ma zwierzątek)
+ public int freeSpots(){
+ int allSpots = map.getWidth() * map.getHeight();
+ int busySpots = map.getAnimalsOnEachSpot().size();
+ if(allSpots - busySpots > 0){
+ return allSpots - busySpots;
+ }
+ else{
+ return 0;
+ }
+ }
+ public void addGenesToGenomes(String genes){
+ if (genomes.containsKey(genes)){
+ genomes.put(genes,genomes.remove(genes)+1);
+ }
+ else genomes.put(genes,1);
+ }
+ public void removeGenesToGenomes(String genes){
+ if (genomes.containsKey(genes)){
+ if (genomes.get(genes)==1){
+ genomes.remove(genes);
+ }
+ else genomes.put(genes,genomes.remove(genes)-1);
+ }
+ //else houston mamy problem
+ }
+ //najpopularniejszy genotyp
+ public String theMostCommonGenotype(){
+ if (genomes.size()>0){
+ Integer maxVal= Collections.max(genomes.values());
+ for (String genes: genomes.keySet()){
+ if (genomes.get(genes).equals(maxVal)){
+ theMostPopularGenome=genes;
+ return genes;
+ }
+ }
+ }
+ return "";
+ }
+
+
+ //średnia energia żyjących zwierząt
+ public int averageEnergyAlive(){
+ if (map.getAnimalsOnField().size() == 0){
+ return 0;
+ }
+ int sum = 0;
+ for(Animal animal : map.getAnimalsOnField()){
+ sum += animal.energy;
+ }
+
+ return sum / map.getAnimalsOnField().size();
+ }
+
+ public int maxEnergyAlive(){
+ int maxEnergy = 0;
+ for(Animal animal : map.getAnimalsOnField()){
+ maxEnergy=max(animal.energy,maxEnergy);
+ }
+
+ return maxEnergy;
+ }
+
+ //średnia długość życia nieżyjących zwierząt
+ public int averageAgeDead(){
+ if (map.getDiedAnimalsOnMap().size()==0){return 0;}
+ int sum = 0;
+ for (Animal animal : map.getDiedAnimalsOnMap()){
+ sum += animal.diedDate;
+ }
+
+ return sum / map.getDiedAnimals();
+ }
+ public void printToFile(FileMenager fileMenager){
+ Object[] statistics = new Object[]{
+ getAmountOfAnimals(),
+ getAmountOfGrass(),
+ freeSpots(),
+ theMostCommonGenotype(),
+ averageEnergyAlive(),
+ averageAgeDead()
+ };
+ fileMenager.dayStats(statistics);
+ }
+ public String getTheMostPopularGenome() {
+ return theMostPopularGenome;
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/TotalRandom.java b/oolab/src/main/java/agh/ics/oop/TotalRandom.java
new file mode 100644
index 0000000..0e17bd6
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/TotalRandom.java
@@ -0,0 +1,21 @@
+package agh.ics.oop;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+
+public class TotalRandom implements IMutationModel{
+ @Override
+ public void mutate(Animal child) {
+ Random generator = new Random();
+ int mutationsNumber=generator.nextInt(child.genes.length);
+ List toMutate= new ArrayList<>();
+ for (int i = 0; i < child.genes.length; i++){toMutate.add(i);}
+ for (int i = 0; i < mutationsNumber; i++){
+ Direction geneToInsert = Direction.numberToDirection(generator.nextInt(8));
+ int ix= generator.nextInt(toMutate.size());
+ child.genes[toMutate.remove(ix)] = geneToInsert;
+ }
+ }
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/ToxicCorpses.java b/oolab/src/main/java/agh/ics/oop/ToxicCorpses.java
new file mode 100644
index 0000000..40e606e
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/ToxicCorpses.java
@@ -0,0 +1,42 @@
+package agh.ics.oop;
+
+import java.util.*;
+import static java.lang.Math.max;
+import static java.lang.Math.round;
+
+public class ToxicCorpses implements IHolyGardener{
+ @Override
+ public void seedGrass(SimulationVar var, Map map) {
+ //stworzymy tablicę vector2d posortowaną względem tego ile zwierzaków umarło na danym polu
+ //wylosujemy liczbę od 0 do 9
+ //w zaleznosci od wylosowanej liczby wylosujemy vector z 20% pól na których umarło najmniej zwierzakow lub 80% pozostałych pól
+ //zasadzimy trawke
+ ArrayList positionsIterator= new ArrayList<>(map.getStats().getDiedAnimals().keySet());
+ ArrayList positions= new ArrayList();
+ for (Vector2d position: positionsIterator){
+ if(!map.isGrassThere(position)){positions.add(position);}
+ }
+ positions.sort(new Comparator() {
+ @Override
+ public int compare(Vector2d o1, Vector2d o2) {
+ return map.getStats().getDiedAnimals().get(o1)-map.getStats().getDiedAnimals().get(o2);
+ }
+ });
+ Random generator = new Random();
+ for (int i=0;i=2){
+ int ix=generator.nextInt(max((int) round(positions.size()*0.2),1));
+ newGrassPosition=positions.remove(ix);
+ }
+ else{
+ int ix=generator.nextInt(positions.size()-(int) round(positions.size()*0.2))+(int) round(positions.size()*0.2);
+ newGrassPosition=positions.remove(ix);
+ }
+ Grass newGrass= new Grass(newGrassPosition);
+ map.addGrass(newGrass);
+ }
+
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/Vector2d.java b/oolab/src/main/java/agh/ics/oop/Vector2d.java
new file mode 100644
index 0000000..6cbc246
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/Vector2d.java
@@ -0,0 +1,61 @@
+package agh.ics.oop;
+
+import java.util.Objects;
+
+public class Vector2d{
+ public final int x;
+ public final int y;
+
+ public Vector2d (int x, int y){
+ this.x=x;
+ this.y=y;
+ }
+
+
+ public String toString() {
+ return "(%d, %d)".formatted(x, y);
+ }
+
+ public boolean precedes(Vector2d other) {
+ return x <= other.x && y <= other.y;
+ }
+
+ public boolean follows(Vector2d other) {
+ return x >= other.x && y >= other.y;
+ }
+
+ public Vector2d add(Vector2d other) {
+ return new Vector2d(x + other.x, y + other.y);
+ }
+
+ public Vector2d subtract(Vector2d other) {
+ return new Vector2d(x - other.x, y - other.y);
+ }
+
+ public Vector2d upperRight(Vector2d other) {
+ return new Vector2d(Math.max(x, other.x), Math.max(y, other.y));
+ }
+
+ public Vector2d lowerLeft(Vector2d other) {
+ return new Vector2d(Math.min(x, other.x), Math.min(y, other.y));
+ }
+
+ public Vector2d opposite() {
+ return new Vector2d(-x, -y);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ Vector2d other = (Vector2d) obj;
+ return (x == other.x && y == other.y);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(x, y);
+ }
+
+}
+
diff --git a/oolab/src/main/java/agh/ics/oop/World.java b/oolab/src/main/java/agh/ics/oop/World.java
new file mode 100644
index 0000000..8f8f669
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/World.java
@@ -0,0 +1,10 @@
+package agh.ics.oop;
+
+import agh.ics.oop.gui.App;
+import javafx.application.Application;
+
+public class World {
+ public static void main(String[] args) {
+ Application.launch(App.class, args);
+ }
+}
\ No newline at end of file
diff --git a/oolab/src/main/java/agh/ics/oop/gui/App.java b/oolab/src/main/java/agh/ics/oop/gui/App.java
new file mode 100644
index 0000000..6346669
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/gui/App.java
@@ -0,0 +1,19 @@
+package agh.ics.oop.gui;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import javafx.fxml.FXMLLoader;
+
+public class App extends Application{
+ @Override
+ public void start(Stage primaryStage) throws Exception {
+ FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/configuration.fxml"));
+ Scene scene = new Scene(fxmlLoader.load());
+ primaryStage.setTitle("START");
+ primaryStage.setScene(scene);
+ primaryStage.show();
+
+ }
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/gui/ConfigurationController.java b/oolab/src/main/java/agh/ics/oop/gui/ConfigurationController.java
new file mode 100644
index 0000000..375171a
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/gui/ConfigurationController.java
@@ -0,0 +1,33 @@
+package agh.ics.oop.gui;
+
+import agh.ics.oop.OptionsParser;
+import agh.ics.oop.SimulationVar;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.util.ResourceBundle;
+
+public class ConfigurationController implements Initializable {
+ @FXML
+ private TextField filePath;
+ @FXML
+ private Label infoLabel;
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+ infoLabel.setText("Start first simulation!");
+ }
+ @FXML
+ public void startSimulation(){
+ try{
+ SimulationVar var= new OptionsParser().parse(filePath.getText());
+ infoLabel.setText("Your simulation is opened in a new window. You can start another one.");
+ new MainViewApp().runApp(var);
+ }
+ catch(FileNotFoundException exception){infoLabel.setText("Wrong config file path. Try again.");}
+ catch(IllegalArgumentException exception){infoLabel.setText("Wrong arguments in config file. Try again.");}
+ catch(Exception exception){infoLabel.setText("Wszyscy zginiemy"); exception.printStackTrace();}
+ }
+}
diff --git a/oolab/src/main/java/agh/ics/oop/gui/MainViewApp.java b/oolab/src/main/java/agh/ics/oop/gui/MainViewApp.java
new file mode 100644
index 0000000..cd8e019
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/gui/MainViewApp.java
@@ -0,0 +1,44 @@
+package agh.ics.oop.gui;
+
+
+import agh.ics.oop.SimulationEngine;
+import agh.ics.oop.SimulationVar;
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import java.io.IOException;
+
+public class MainViewApp extends Application {
+ private Thread engineThread;
+ private SimulationEngine engine;
+ private MainViewController controller;
+ public void runApp(SimulationVar var) throws IOException {
+ engine=new SimulationEngine(var, this);
+ engineThread=new Thread(engine);
+ start(new Stage());
+ engineThread.start();
+ }
+
+ @Override
+ public void start(Stage primaryStage) throws IOException {
+ FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/mainView.fxml"));
+ Scene scene = new Scene(fxmlLoader.load());
+ controller=fxmlLoader.getController();
+ controller.initial(engine);
+ primaryStage.setOnCloseRequest(e -> {
+ primaryStage.close();
+ ((MainViewController) fxmlLoader.getController()).stopButtonAction();
+ });
+ primaryStage.setTitle("Evolution simulation");
+ primaryStage.setScene(scene);
+ primaryStage.show();
+ }
+
+ public void newDayUpdate(){
+ controller.newDayUpdate();
+ }
+ public void showEndScene() {controller.showEndScene();}
+
+
+}
diff --git a/oolab/src/main/java/agh/ics/oop/gui/MainViewController.java b/oolab/src/main/java/agh/ics/oop/gui/MainViewController.java
new file mode 100644
index 0000000..ef94fed
--- /dev/null
+++ b/oolab/src/main/java/agh/ics/oop/gui/MainViewController.java
@@ -0,0 +1,202 @@
+package agh.ics.oop.gui;
+
+import agh.ics.oop.*;
+import javafx.fxml.FXML;
+import javafx.geometry.HPos;
+import javafx.geometry.VPos;
+import javafx.scene.control.Label;
+import javafx.scene.layout.*;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.Random;
+
+import static java.lang.Math.min;
+
+public class MainViewController {
+ private final Double HEIGHT=667.0;
+ private final Double WIDTH=667.0;
+ @FXML
+ private Label numberOfDays;
+ @FXML
+ private Label numberOfAnimals;
+ @FXML
+ private Label amountOfGrass;
+ @FXML
+ private Label numberOfEmptyFields;
+ @FXML
+ private Label theMostPopularGenome;
+ @FXML
+ private Label averageEnergyLevel;
+ @FXML
+ private Label averageDeadAgeLevel;
+ @FXML
+ private Label genome;
+ @FXML
+ private Label activeGene;
+ @FXML
+ private Label energy;
+ @FXML
+ private Label amountOfEatenGrass;
+ @FXML
+ private Label numberOfChildren;
+ @FXML
+ private Label daysAlive;
+ @FXML
+ private Label dayOfDeath;
+ @FXML
+ private HBox mapBox;
+ private GridPane map=new GridPane();
+ private SimulationEngine engine;
+
+ private Animal followedAnimal;
+
+ private boolean amIPsychopath=false;
+
+ public void initial(SimulationEngine engine) {
+ this.engine=engine;
+ updateLabels();
+ cleanFollowedAnimalLabels();
+ map.setGridLinesVisible(true);
+ mapBox.getChildren().addAll(map);
+ }
+ @FXML
+ public void playButtonAction(){
+ engine.play();
+ }
+ @FXML
+ public void pauseButtonAction(){
+ engine.pause();
+ }
+ @FXML
+ public void stopButtonAction(){
+ engine.play();
+ engine.stop();
+ }
+ @FXML
+ public void stopFollowingAnimal(){
+ amIPsychopath=false;
+ cleanFollowedAnimalLabels();
+ }
+
+ private void updateLabels(){
+ numberOfDays.setText(String.valueOf(engine.getHowManyDays()));
+ numberOfAnimals.setText(String.valueOf(engine.getMapStats().getAmountOfAnimals()));
+ amountOfGrass.setText(String.valueOf(engine.getMapStats().getAmountOfGrass()));
+ numberOfEmptyFields.setText(String.valueOf(engine.getMapStats().freeSpots()));
+ theMostPopularGenome.setText(engine.getMapStats().theMostCommonGenotype());
+ averageEnergyLevel.setText(String.valueOf(engine.getMapStats().averageEnergyAlive()));
+ averageDeadAgeLevel.setText(String.valueOf(engine.getMapStats().averageAgeDead()));
+ }
+ private void updateFollowedAnimalLabels(){
+ if (amIPsychopath){
+ genome.setText(followedAnimal.genesToString());
+ activeGene.setText(followedAnimal.getActiveJeans().toString());
+ energy.setText(String.valueOf(followedAnimal.getEnergy()));
+ amountOfEatenGrass.setText(String.valueOf(followedAnimal.getGrassEaten()));
+ numberOfChildren.setText(String.valueOf(followedAnimal.getChildren()));
+ daysAlive.setText(followedAnimal.ageToString());
+ dayOfDeath.setText(followedAnimal.diedDateToString());
+ }
+ }
+
+ private void cleanFollowedAnimalLabels(){
+ genome.setText("-");
+ activeGene.setText("-");
+ energy.setText("-");
+ amountOfEatenGrass.setText("-");
+ numberOfChildren.setText("-");
+ daysAlive.setText("-");
+ dayOfDeath.setText("-");
+ }
+
+ public void renderMap(){
+ map.setGridLinesVisible(false);
+ map.getChildren().clear();
+ map.getColumnConstraints().clear();
+ map.getRowConstraints().clear();
+ map.setGridLinesVisible(true);
+ for (int x=0;x=0 ;y--){
+ Vector2d position = new Vector2d(x,y);
+ GridPane newPane=new GridPane();
+ newPane.getColumnConstraints().add(new ColumnConstraints(WIDTH/engine.getMap().getWidth()));
+ newPane.getRowConstraints().add(new RowConstraints(HEIGHT/engine.getMap().getHeight()));
+ newPane.setGridLinesVisible(true);
+ if (engine.getMap().isGrassThere(position)){
+ newPane.setStyle("-fx-background-color: #fa75dd;");
+ }
+ else{
+ newPane.setStyle("-fx-background-color: #facaf0;");
+ }
+ if (amIPsychopath && followedAnimal.isAlive() && followedAnimal.getPosition().equals(position))
+ {
+ Circle animalImage=new Circle(min(WIDTH/engine.getMap().getWidth(),HEIGHT/engine.getMap().getHeight())/2.0, new Color(0,1,0,1));
+ newPane.add(animalImage,0,0);
+ newPane.setValignment(animalImage, VPos.CENTER);
+ newPane.setHalignment(animalImage, HPos.CENTER);
+ }
+ else if (engine.getMap().isAnimalThere(position)){
+ Animal animal=engine.getMap().getAnimalOnSpot(position);
+ Circle animalImage=animal.getImage(min(WIDTH/engine.getMap().getWidth(),HEIGHT/engine.getMap().getHeight()),this);
+ newPane.add(animalImage,0,0);
+ newPane.setValignment(animalImage, VPos.CENTER);
+ newPane.setHalignment(animalImage, HPos.CENTER);
+ }
+ map.add(newPane,x,engine.getMap().getHeight()-1-y);
+
+ }
+ }
+
+ }
+
+ public void newDayUpdate(){
+ updateLabels();
+ renderMap();
+ updateFollowedAnimalLabels();
+ }
+
+ public void showEndScene() {
+ mapBox.getChildren().clear();
+ try {
+ ImageView image = new ImageView(new Image(new FileInputStream(getEndPicPath())));
+ image.setFitWidth(WIDTH);
+ image.setFitHeight(HEIGHT);
+ mapBox.getChildren().addAll(image);
+
+ } catch (FileNotFoundException e) {
+ mapBox.getChildren().addAll(new Label("THE END :("));
+ }
+
+ }
+
+ public void follow(Animal animal){
+ amIPsychopath=true;
+ followedAnimal=animal;
+ updateFollowedAnimalLabels();
+ }
+
+ public String getEndPicPath(){
+ Random random = new Random();
+ int number=random.nextInt(10);
+ return switch (number){
+ case 0 -> "oolab/src/main/resources/theendpics/theend0.jpg";
+ case 1 -> "oolab/src/main/resources/theendpics/theend1.jpg";
+ case 2 -> "oolab/src/main/resources/theendpics/theend2.jpg";
+ case 3 -> "oolab/src/main/resources/theendpics/theend3.jpg";
+ case 4 -> "oolab/src/main/resources/theendpics/theend4.jpg";
+ case 5 -> "oolab/src/main/resources/theendpics/theend5.jpg";
+ case 6 -> "oolab/src/main/resources/theendpics/theend6.jpg";
+ case 7 -> "oolab/src/main/resources/theendpics/theend7.jpg";
+ case 8 -> "oolab/src/main/resources/theendpics/theend8.jpg";
+ case 9 -> "oolab/src/main/resources/theendpics/theend9.jpg";
+ default -> "oolab/src/main/resources/theendpics/theend.jpg";
+ };
+
+ }
+
+}
diff --git a/oolab/src/main/java/module-info.java b/oolab/src/main/java/module-info.java
new file mode 100644
index 0000000..f33ea43
--- /dev/null
+++ b/oolab/src/main/java/module-info.java
@@ -0,0 +1,8 @@
+module agh.ics.oop.gui {
+ requires javafx.controls;
+ requires javafx.fxml;
+
+
+ opens agh.ics.oop.gui to javafx.fxml;
+ exports agh.ics.oop.gui;
+}
\ No newline at end of file
diff --git a/oolab/src/main/resources/configfiles/Config1.csv b/oolab/src/main/resources/configfiles/Config1.csv
new file mode 100644
index 0000000..9b4b8e0
--- /dev/null
+++ b/oolab/src/main/resources/configfiles/Config1.csv
@@ -0,0 +1 @@
+HellMap;ToxicCorpses;LittleAdjustment;PredestinationBehavior;50;50;2;1;30;1;20;20;300;6;false
\ No newline at end of file
diff --git a/oolab/src/main/resources/configfiles/Config2.csv b/oolab/src/main/resources/configfiles/Config2.csv
new file mode 100644
index 0000000..213a9c9
--- /dev/null
+++ b/oolab/src/main/resources/configfiles/Config2.csv
@@ -0,0 +1 @@
+GlobMap;ToxicCorpses;TotalRandom;PredestinationBehavior;5;5;2;2;7;1;4;3;500;4;false
\ No newline at end of file
diff --git a/oolab/src/main/resources/configfiles/Config3.csv b/oolab/src/main/resources/configfiles/Config3.csv
new file mode 100644
index 0000000..03624e8
--- /dev/null
+++ b/oolab/src/main/resources/configfiles/Config3.csv
@@ -0,0 +1 @@
+HellMap;ForestedEquators;LittleAdjustment;HijinksBehavior;10;10;3;5;15;2;20;5;300;10;true;oolab/src/main/resources/configfiles/Config3Stats.csv
\ No newline at end of file
diff --git a/oolab/src/main/resources/configfiles/Config3Stats.csv b/oolab/src/main/resources/configfiles/Config3Stats.csv
new file mode 100644
index 0000000..e69de29
diff --git a/oolab/src/main/resources/configfiles/Config4.csv b/oolab/src/main/resources/configfiles/Config4.csv
new file mode 100644
index 0000000..da9ebb1
--- /dev/null
+++ b/oolab/src/main/resources/configfiles/Config4.csv
@@ -0,0 +1 @@
+GlobMap;ForestedEquators;TotalRandom;HijinksBehavior;10;10;1;2;20;1;5;1;300;5;true;oolab/src/main/resources/configfiles/Config4Stats.csv
\ No newline at end of file
diff --git a/oolab/src/main/resources/configfiles/Config4Stats.csv b/oolab/src/main/resources/configfiles/Config4Stats.csv
new file mode 100644
index 0000000..e69de29
diff --git a/oolab/src/main/resources/configfiles/Config5.csv b/oolab/src/main/resources/configfiles/Config5.csv
new file mode 100644
index 0000000..34940c9
--- /dev/null
+++ b/oolab/src/main/resources/configfiles/Config5.csv
@@ -0,0 +1 @@
+HellMap;ForestedEquators;LittleAdjustment;PredestinationBehavior;30;30;5;5;50;3;15;10;200;10;false
\ No newline at end of file
diff --git a/oolab/src/main/resources/configuration.fxml b/oolab/src/main/resources/configuration.fxml
new file mode 100644
index 0000000..92f3d8a
--- /dev/null
+++ b/oolab/src/main/resources/configuration.fxml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oolab/src/main/resources/defaultfile.csv b/oolab/src/main/resources/defaultfile.csv
new file mode 100644
index 0000000..e69de29
diff --git a/oolab/src/main/resources/mainView.fxml b/oolab/src/main/resources/mainView.fxml
new file mode 100644
index 0000000..4239cbf
--- /dev/null
+++ b/oolab/src/main/resources/mainView.fxml
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oolab/src/main/resources/theendpics/theend.jpg b/oolab/src/main/resources/theendpics/theend.jpg
new file mode 100644
index 0000000..133074d
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend0.jpg b/oolab/src/main/resources/theendpics/theend0.jpg
new file mode 100644
index 0000000..6ac0114
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend0.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend1.jpg b/oolab/src/main/resources/theendpics/theend1.jpg
new file mode 100644
index 0000000..bac022a
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend1.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend2.jpg b/oolab/src/main/resources/theendpics/theend2.jpg
new file mode 100644
index 0000000..53db5ee
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend2.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend3.jpg b/oolab/src/main/resources/theendpics/theend3.jpg
new file mode 100644
index 0000000..dc939f6
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend3.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend4.jpg b/oolab/src/main/resources/theendpics/theend4.jpg
new file mode 100644
index 0000000..2230bd8
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend4.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend5.jpg b/oolab/src/main/resources/theendpics/theend5.jpg
new file mode 100644
index 0000000..c4b4177
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend5.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend6.jpg b/oolab/src/main/resources/theendpics/theend6.jpg
new file mode 100644
index 0000000..1b3c136
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend6.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend7.jpg b/oolab/src/main/resources/theendpics/theend7.jpg
new file mode 100644
index 0000000..715536c
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend7.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend8.jpg b/oolab/src/main/resources/theendpics/theend8.jpg
new file mode 100644
index 0000000..74f7c1f
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend8.jpg differ
diff --git a/oolab/src/main/resources/theendpics/theend9.jpg b/oolab/src/main/resources/theendpics/theend9.jpg
new file mode 100644
index 0000000..d57364c
Binary files /dev/null and b/oolab/src/main/resources/theendpics/theend9.jpg differ