diff --git a/.gradle/8.10.2/checksums/checksums.lock b/.gradle/8.10.2/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..42461de49dc42f66b6b6fe6a65813dd240252506 Binary files /dev/null and b/.gradle/8.10.2/checksums/checksums.lock differ diff --git a/.gradle/8.10.2/checksums/md5-checksums.bin b/.gradle/8.10.2/checksums/md5-checksums.bin new file mode 100644 index 0000000000000000000000000000000000000000..034244bd2b94f98909fca09510a8451491ab84b9 Binary files /dev/null and b/.gradle/8.10.2/checksums/md5-checksums.bin differ diff --git a/.gradle/8.10.2/checksums/sha1-checksums.bin b/.gradle/8.10.2/checksums/sha1-checksums.bin new file mode 100644 index 0000000000000000000000000000000000000000..a9af8f35de14059f8fd4b8895693791fe2b14210 Binary files /dev/null and b/.gradle/8.10.2/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.10.2/dependencies-accessors/gc.properties b/.gradle/8.10.2/dependencies-accessors/gc.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.gradle/8.10.2/executionHistory/executionHistory.bin b/.gradle/8.10.2/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..47f48ba81a2ea645d483fccceecb84a70ba1b0aa Binary files /dev/null and b/.gradle/8.10.2/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.10.2/executionHistory/executionHistory.lock b/.gradle/8.10.2/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..f6ff60c199d140409d3a15e8dba19603a39f3aa2 Binary files /dev/null and b/.gradle/8.10.2/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.10.2/fileChanges/last-build.bin b/.gradle/8.10.2/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d Binary files /dev/null and b/.gradle/8.10.2/fileChanges/last-build.bin differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.bin b/.gradle/8.10.2/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..18bb931b02f78504383bba96122271ac0e01fc85 Binary files /dev/null and b/.gradle/8.10.2/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.lock b/.gradle/8.10.2/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..b4d9229ad923b7150bf5936336641003b4848500 Binary files /dev/null and b/.gradle/8.10.2/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.10.2/fileHashes/resourceHashesCache.bin b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..ccf8e1028ff23592fa008b93be6507cd9b70bf9e Binary files /dev/null and b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/8.10.2/gc.properties b/.gradle/8.10.2/gc.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000000000000000000000000000000000000..ab7326651a6e033ac99e4103331c2122f16844fc Binary files /dev/null and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000000000000000000000000000000000000..414f69fa2274b7f96b396b81bd92293bce36bc65 --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,6 @@ +<<<<<<< HEAD +#Fri Nov 08 10:44:53 CET 2024 +======= +#Tue Nov 19 10:28:27 CET 2024 +>>>>>>> origin/main +gradle.version=8.10.2 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..a4ce2b139a7bd595ce29890dd615ae14b0fefecc Binary files /dev/null and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe new file mode 100644 index 0000000000000000000000000000000000000000..045ab59c12fc2364a1d918e3ca3894be886b408b Binary files /dev/null and b/.gradle/file-system.probe differ diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/DiagrammeUML.pdf b/DiagrammeUML.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5558e1e6367c868db66cbb07311512b3d0d0a01d Binary files /dev/null and b/DiagrammeUML.pdf differ diff --git a/RAPPORT PROJET PROGRAMMATION ET CONCECPTION.odt b/RAPPORT PROJET PROGRAMMATION ET CONCECPTION.odt new file mode 100644 index 0000000000000000000000000000000000000000..e3c0ebf763f3a3c9db84eb1a9cd894d5ef70daa4 Binary files /dev/null and b/RAPPORT PROJET PROGRAMMATION ET CONCECPTION.odt differ diff --git a/build/classes/java/main/app/SimulatorApplication.class b/build/classes/java/main/app/SimulatorApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..0945559258306b09c37b530b8c44adfb1b4b4489 Binary files /dev/null and b/build/classes/java/main/app/SimulatorApplication.class differ diff --git a/build/classes/java/main/app/SimulatorMain.class b/build/classes/java/main/app/SimulatorMain.class new file mode 100644 index 0000000000000000000000000000000000000000..1d13229f73ef27c233a432bc89aa3dffc086246a Binary files /dev/null and b/build/classes/java/main/app/SimulatorMain.class differ diff --git a/build/classes/java/main/controller/Controller.class b/build/classes/java/main/controller/Controller.class new file mode 100644 index 0000000000000000000000000000000000000000..163ac71b4436ddbd5037429af5bbad43b226d5d6 Binary files /dev/null and b/build/classes/java/main/controller/Controller.class differ diff --git a/build/classes/java/main/controller/PersistentToggleGroup.class b/build/classes/java/main/controller/PersistentToggleGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..314954a9fd4ab6d48da5fec7067063879e670d62 Binary files /dev/null and b/build/classes/java/main/controller/PersistentToggleGroup.class differ diff --git a/build/classes/java/main/model/Board.class b/build/classes/java/main/model/Board.class new file mode 100644 index 0000000000000000000000000000000000000000..a1f8169e45fef3872ae559ad22bdf5a3d6f63dfd Binary files /dev/null and b/build/classes/java/main/model/Board.class differ diff --git a/build/classes/java/main/model/Cloud.class b/build/classes/java/main/model/Cloud.class new file mode 100644 index 0000000000000000000000000000000000000000..e5c7d20ab1f5fcd33a3769dbfa207f33e3611db6 Binary files /dev/null and b/build/classes/java/main/model/Cloud.class differ diff --git a/build/classes/java/main/model/Fire.class b/build/classes/java/main/model/Fire.class new file mode 100644 index 0000000000000000000000000000000000000000..293e54f328d58516173fb87850d80aaa9abd68a6 Binary files /dev/null and b/build/classes/java/main/model/Fire.class differ diff --git a/build/classes/java/main/model/Firefighter.class b/build/classes/java/main/model/Firefighter.class new file mode 100644 index 0000000000000000000000000000000000000000..730693aebeb26e925143ca534322f233c509b93c Binary files /dev/null and b/build/classes/java/main/model/Firefighter.class differ diff --git a/build/classes/java/main/model/FirefighterBoard$1.class b/build/classes/java/main/model/FirefighterBoard$1.class new file mode 100644 index 0000000000000000000000000000000000000000..273e4a03f24da0030d70b9e72a316922173c4878 Binary files /dev/null and b/build/classes/java/main/model/FirefighterBoard$1.class differ diff --git a/build/classes/java/main/model/FirefighterBoard.class b/build/classes/java/main/model/FirefighterBoard.class new file mode 100644 index 0000000000000000000000000000000000000000..bdfa9a3bc400afd08431456757714449d3c3dda8 Binary files /dev/null and b/build/classes/java/main/model/FirefighterBoard.class differ diff --git a/build/classes/java/main/model/ModelElement.class b/build/classes/java/main/model/ModelElement.class new file mode 100644 index 0000000000000000000000000000000000000000..d9a18a708ffa58a2658987950ce55e18a042ee4d Binary files /dev/null and b/build/classes/java/main/model/ModelElement.class differ diff --git a/build/classes/java/main/model/MotorizedFireFighter.class b/build/classes/java/main/model/MotorizedFireFighter.class new file mode 100644 index 0000000000000000000000000000000000000000..e5798657b071e6078a6b90742d91d721ff923d69 Binary files /dev/null and b/build/classes/java/main/model/MotorizedFireFighter.class differ diff --git a/build/classes/java/main/model/TargetStrategy.class b/build/classes/java/main/model/TargetStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..da7b5d502c5df72549a10bebc64bd97a5fdc5805 Binary files /dev/null and b/build/classes/java/main/model/TargetStrategy.class differ diff --git a/build/classes/java/main/module-info.class b/build/classes/java/main/module-info.class new file mode 100644 index 0000000000000000000000000000000000000000..b9b292f976c1b1600c3a99db66f57621346bc2c9 Binary files /dev/null and b/build/classes/java/main/module-info.class differ diff --git a/build/classes/java/main/util/Position.class b/build/classes/java/main/util/Position.class new file mode 100644 index 0000000000000000000000000000000000000000..89bcfc46acba6bd77f0f54570c0b935dce0be942 Binary files /dev/null and b/build/classes/java/main/util/Position.class differ diff --git a/build/classes/java/main/view/FirefighterGrid.class b/build/classes/java/main/view/FirefighterGrid.class new file mode 100644 index 0000000000000000000000000000000000000000..831699ca3ca58a17f7b79bad1d1464aeb6d30a4c Binary files /dev/null and b/build/classes/java/main/view/FirefighterGrid.class differ diff --git a/build/classes/java/main/view/Grid.class b/build/classes/java/main/view/Grid.class new file mode 100644 index 0000000000000000000000000000000000000000..c4fa5e96b46909e2a89e512f2ad9c2d4d042260c Binary files /dev/null and b/build/classes/java/main/view/Grid.class differ diff --git a/build/classes/java/main/view/ViewElement.class b/build/classes/java/main/view/ViewElement.class new file mode 100644 index 0000000000000000000000000000000000000000..6eafa446f503ddf36ffad81fa3aa65c31448d777 Binary files /dev/null and b/build/classes/java/main/view/ViewElement.class differ diff --git a/build/install/firefighter-shadow/bin/firefighter b/build/install/firefighter-shadow/bin/firefighter new file mode 100755 index 0000000000000000000000000000000000000000..ecdb49f7161492f27d686545536b691fbc98cf31 --- /dev/null +++ b/build/install/firefighter-shadow/bin/firefighter @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or 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. +# + +############################################################################## +## +## firefighter start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/.." >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="firefighter" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and FIREFIGHTER_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/lib/firefighter-all.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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $FIREFIGHTER_OPTS -jar "\"$CLASSPATH\"" "$APP_ARGS" + +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/build/install/firefighter-shadow/bin/firefighter.bat b/build/install/firefighter-shadow/bin/firefighter.bat new file mode 100755 index 0000000000000000000000000000000000000000..9d9829681fb66d0a67461026443aef372fc9b694 --- /dev/null +++ b/build/install/firefighter-shadow/bin/firefighter.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem firefighter 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 Add default JVM options here. You can also use JAVA_OPTS and FIREFIGHTER_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@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 init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\lib\firefighter-all.jar + +@rem Execute firefighter +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %FIREFIGHTER_OPTS% -jar "%CLASSPATH%" %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable FIREFIGHTER_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%FIREFIGHTER_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega \ No newline at end of file diff --git a/build/install/firefighter-shadow/lib/firefighter-all.jar b/build/install/firefighter-shadow/lib/firefighter-all.jar new file mode 100644 index 0000000000000000000000000000000000000000..69566b7eac4f8d3787e70cfc3996e0c455128c91 Binary files /dev/null and b/build/install/firefighter-shadow/lib/firefighter-all.jar differ diff --git a/build/libs/firefighter-all.jar b/build/libs/firefighter-all.jar new file mode 100644 index 0000000000000000000000000000000000000000..69566b7eac4f8d3787e70cfc3996e0c455128c91 Binary files /dev/null and b/build/libs/firefighter-all.jar differ diff --git a/build/resources/main/view/DarkTheme.css b/build/resources/main/view/DarkTheme.css new file mode 100644 index 0000000000000000000000000000000000000000..46b78aaf90972dd435399466c9fd861ca73fc59f --- /dev/null +++ b/build/resources/main/view/DarkTheme.css @@ -0,0 +1,142 @@ +.background { + -fx-background-color: #1d1d1d; +} + +.label { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: white; + -fx-opacity: 0.6; +} + +.label-bright { + -fx-font-size: 11pt; + -fx-font-family: "Segoe UI Semibold"; + -fx-text-fill: white; + -fx-opacity: 1; +} + +.label-header { + -fx-font-size: 32pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-opacity: 1; +} + +.table-view { + -fx-base: #1d1d1d; + -fx-control-inner-background: #1d1d1d; + -fx-background-color: #1d1d1d; + -fx-table-cell-border-color: transparent; + -fx-table-header-border-color: transparent; + -fx-padding: 5; +} + +.table-view .column-header-background { + -fx-background-color: transparent; +} + +.table-view .column-header, .table-view .filler { + -fx-border-width: 0 0 1 0; + -fx-background-color: transparent; + -fx-border-color: + transparent + transparent + derive(-fx-base, 80%) + transparent; + -fx-border-insets: 0 10 1 0; +} + +.table-view .column-header .label { + -fx-font-size: 20pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-alignment: center-left; + -fx-opacity: 1; +} + +.table-view:focused .table-row-cell:filled:focused:selected { + -fx-background-color: -fx-focus-color; +} + +.split-pane:horizontal > .split-pane-divider { + -fx-border-color: transparent #1d1d1d transparent #1d1d1d; + -fx-background-color: transparent, derive(#1d1d1d,20%); +} + +.split-pane { + -fx-padding: 1 0 0 0; +} + +.menu-bar { + -fx-background-color: derive(#1d1d1d,20%); +} + +.context-menu { + -fx-background-color: derive(#1d1d1d,50%); +} + +.menu-bar .label { + -fx-font-size: 14pt; + -fx-font-family: "Segoe UI Light"; + -fx-text-fill: white; + -fx-opacity: 0.9; +} + +.menu .left-container { + -fx-background-color: black; +} + +.text-field { + -fx-font-size: 12pt; + -fx-font-family: "Segoe UI Semibold"; +} + +/* + * Metro style Push Button + * Author: Pedro Duque Vieira + * http://pixelduke.wordpress.com/2012/10/23/jmetro-windows-8-controls-on-java/ + */ +.button { + -fx-padding: 5 22 5 22; + -fx-border-color: #e2e2e2; + -fx-border-width: 2; + -fx-background-radius: 0; + -fx-background-color: #1d1d1d; + -fx-font-family: "Segoe UI", Helvetica, Arial, sans-serif; + -fx-font-size: 11pt; + -fx-text-fill: #d8d8d8; + -fx-background-insets: 0 0 0 0, 0, 1, 2; +} + +.button:hover { + -fx-background-color: #3a3a3a; +} + +.button:pressed, .button:default:hover:pressed { + -fx-background-color: white; + -fx-text-fill: #1d1d1d; +} + +.button:focused { + -fx-border-color: white, white; + -fx-border-width: 1, 1; + -fx-border-style: solid; + -fx-border-radius: 0, 0; + -fx-border-insets: 1 1 1 1, 0; +} + +.button:disabled, .button:default:disabled { + -fx-opacity: 0.4; + -fx-background-color: #1d1d1d; + -fx-text-fill: white; +} + +.button:default { + -fx-background-color: -fx-focus-color; + -fx-text-fill: #ffffff; +} + +.button:default:hover { + -fx-background-color: derive(-fx-focus-color,30%); +} \ No newline at end of file diff --git a/build/resources/main/view/view.fxml b/build/resources/main/view/view.fxml new file mode 100644 index 0000000000000000000000000000000000000000..336ffa315645baacbe25bf59171d2ff6d867b9c5 --- /dev/null +++ b/build/resources/main/view/view.fxml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.VBox?> +<?import view.FirefighterGrid?> + +<?import javafx.scene.control.ToggleButton?> +<?import javafx.scene.control.Separator?> +<?import javafx.scene.control.Label?> +<HBox styleClass="background" stylesheets="@DarkTheme.css" + xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" + fx:controller="controller.Controller"> + <VBox> + <Separator maxHeight="-Infinity" maxWidth="-Infinity" + prefHeight="24.0" prefWidth="200.0"/> + <Label maxHeight="-Infinity" maxWidth="-Infinity" alignment="CENTER" prefHeight="24.0" prefWidth="200.0" + text="Generation number"/> + <Label fx:id="generationNumberLabel" alignment="CENTER" contentDisplay="TEXT_ONLY" + maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="24.0" prefWidth="200.0"/> + <Separator maxHeight="-Infinity" maxWidth="-Infinity" + prefHeight="24.0" prefWidth="200.0"/> + <Button fx:id="restartButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#restartButtonAction" prefHeight="24.0" prefWidth="200.0" + text="Restart"/> + <Button fx:id="oneStepButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#oneStepButtonAction" prefHeight="24.0" prefWidth="200.0" + text="One step"/> + <ToggleButton fx:id="playToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#playToggleButtonAction" prefHeight="24.0" + prefWidth="200.0" styleClass="button" text="Play"/> + <ToggleButton fx:id="pauseToggleButton" maxHeight="-Infinity" maxWidth="-Infinity" + mnemonicParsing="false" onAction="#pauseToggleButtonAction" prefHeight="24.0" + prefWidth="200.0" styleClass="button" text="Pause"/> + </VBox> + <FirefighterGrid fx:id="grid" + xmlns="http://javafx.com/javafx" + xmlns:fx="http://javafx.com/fxml"> + </FirefighterGrid> +</HBox> diff --git a/build/scriptsShadow/firefighter b/build/scriptsShadow/firefighter new file mode 100755 index 0000000000000000000000000000000000000000..ecdb49f7161492f27d686545536b691fbc98cf31 --- /dev/null +++ b/build/scriptsShadow/firefighter @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or 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. +# + +############################################################################## +## +## firefighter start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/.." >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="firefighter" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and FIREFIGHTER_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/lib/firefighter-all.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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $FIREFIGHTER_OPTS -jar "\"$CLASSPATH\"" "$APP_ARGS" + +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/build/scriptsShadow/firefighter.bat b/build/scriptsShadow/firefighter.bat new file mode 100644 index 0000000000000000000000000000000000000000..9d9829681fb66d0a67461026443aef372fc9b694 --- /dev/null +++ b/build/scriptsShadow/firefighter.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem firefighter 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 Add default JVM options here. You can also use JAVA_OPTS and FIREFIGHTER_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@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 init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\lib\firefighter-all.jar + +@rem Execute firefighter +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %FIREFIGHTER_OPTS% -jar "%CLASSPATH%" %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable FIREFIGHTER_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%FIREFIGHTER_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega \ No newline at end of file diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..7eedd407d8bf36270d6854f396259aae51bf3cf5 Binary files /dev/null and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/build/tmp/shadowJar/MANIFEST.MF b/build/tmp/shadowJar/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..2c5dafadb5f53a219e1c22537b872baf7d0b350d --- /dev/null +++ b/build/tmp/shadowJar/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: app.SimulatorMain + diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 2a60897c6eb8ba847cb8589840c16a0f175ce0a3..5c49ff4ad43680f1cc4072eca520fd50838fc82a 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -49,7 +49,7 @@ public class Controller { } private void initializePlayAndPauseToggleButtons() { - ToggleGroup toggleGroup = new PersistentToggleGroup(); + ToggleGroup toggleGroup = new ToggleGroup(); toggleGroup.getToggles().addAll(playToggleButton, pauseToggleButton); pauseToggleButton.setSelected(true); } @@ -58,10 +58,10 @@ public class Controller { this.board = requireNonNull(firefighterBoard, "firefighter.model is null"); } - private void updateBoard(){ + private void updateBoard() { List<Position> updatedPositions = board.updateToNextGeneration(); List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>(); - for(Position updatedPosition : updatedPositions){ + for (Position updatedPosition : updatedPositions) { List<ModelElement> squareState = board.getState(updatedPosition); ViewElement viewElement = getViewElement(squareState); updatedSquares.add(new Pair<>(updatedPosition, viewElement)); @@ -70,31 +70,49 @@ public class Controller { updateGenerationLabel(board.stepNumber()); } - private void repaintGrid(){ + private void repaintGrid() { int columnCount = board.columnCount(); int rowCount = board.rowCount(); ViewElement[][] viewElements = new ViewElement[rowCount][columnCount]; - for(int column = 0; column < columnCount; column++) - for(int row = 0; row < rowCount; row++) + for (int column = 0; column < columnCount; column++) + for (int row = 0; row < rowCount; row++) viewElements[row][column] = getViewElement(board.getState(new Position(row, column))); grid.repaint(viewElements); updateGenerationLabel(board.stepNumber()); } private ViewElement getViewElement(List<ModelElement> squareState) { - if(squareState.contains(ModelElement.FIREFIGHTER)){ + if (squareState.contains(ModelElement.MOTORIZED_FIREFIGHTER)) { + return ViewElement.MOTORIZED_FIREFIGHTER; + } + if (squareState.contains(ModelElement.FIREFIGHTER)) { return ViewElement.FIREFIGHTER; } - if (squareState.contains(ModelElement.FIRE)){ + if (squareState.contains(ModelElement.FIRE)) { return ViewElement.FIRE; } + if (squareState.contains(ModelElement.CLOUD)) { + return ViewElement.CLOUD; + } + + if (squareState.contains(ModelElement.MOUNTAIN)){ + return ViewElement.MOUNTAIN; + } + + if (squareState.contains(ModelElement.ROUTE)){ + return ViewElement.ROUTE; + } + + if (squareState.contains(ModelElement.ROCK)){ + return ViewElement.ROCK; + } + return ViewElement.EMPTY; } private void initializeTimeline() { Duration duration = new Duration(Controller.PERIOD_IN_MILLISECONDS); - EventHandler<ActionEvent> eventHandler = - event -> updateBoard(); + EventHandler<ActionEvent> eventHandler = event -> updateBoard(); KeyFrame keyFrame = new KeyFrame(duration, eventHandler); timeline = new Timeline(keyFrame); timeline.setCycleCount(Animation.INDEFINITE); @@ -123,8 +141,7 @@ public class Controller { repaintGrid(); } - public void initialize(int squareWidth, int squareHeight, int columnCount, - int rowCount, int initialFireCount, int initialFirefighterCount) { + public void initialize(int squareWidth, int squareHeight, int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight); this.setModel(new FirefighterBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount)); repaintGrid(); @@ -135,7 +152,7 @@ public class Controller { updateBoard(); } - private void updateGenerationLabel(int value){ + private void updateGenerationLabel(int value) { generationNumberLabel.setText(Integer.toString(value)); } -} \ No newline at end of file +} diff --git a/src/main/java/model/Cloud.java b/src/main/java/model/Cloud.java new file mode 100644 index 0000000000000000000000000000000000000000..bc086886a21eeca6724ce3f093d9aa8cf442ef56 --- /dev/null +++ b/src/main/java/model/Cloud.java @@ -0,0 +1,54 @@ +package model; + +import util.Position; + +import java.util.List; +import java.util.Map; +import java.util.Random; + + +/** + * La classe Cloud représente un nuage dans la simulation. + * Elle est responsable de : + * + * - Gérer la position du nuage dans la simulation. + * - Déplacer le nuage vers une position voisine de manière aléatoire. + * - Permettre au nuage d'éteindre un feu à sa position actuelle. + * + * Cette classe est utilisée pour simuler les déplacements et les interactions des nuages + * avec les feux dans le modèle. + * + * Méthodes principales : + * - Position getPosition() : retourne la position actuelle du nuage. + * - void move(Map<Position, List<Position>> neighbors) : déplace le nuage vers une position voisine aléatoire. + * - void extinguishFire(Fire fire) : éteint le feu à la position actuelle du nuage. + */ + +public class Cloud { + private Position position; + private final Random random = new Random(); + + public Cloud(Position initialPosition) { + this.position = initialPosition; + } + + public Position getPosition() { + return position; + } + + public void move(Map<Position, List<Position>> neighbors) { + List<Position> possiblePositions = neighbors.get(position); + if (!possiblePositions.isEmpty()) { + position = possiblePositions.get(random.nextInt(possiblePositions.size())); + } + } + + public void moveTo(Position target) { + this.position = target; + } + + + public void extinguishFire(Fire fire) { + fire.extinguish(position); + } +} diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java new file mode 100644 index 0000000000000000000000000000000000000000..d729fc74b5e236d962f74c8a8899b1a9c3cde219 --- /dev/null +++ b/src/main/java/model/Fire.java @@ -0,0 +1,62 @@ +package model; + +import util.Position; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * La classe Fire gère l'état et le comportement des feux dans la simulation. + * Elle est responsable de : + * + * - Stocker les positions des feux actifs sur le plateau. + * - Propager les feux vers les cases voisines selon les règles de la simulation. + * - Éteindre les feux à des positions spécifiques, que ce soit individuellement ou en groupe. + * + * Cette classe est utilisée par FirefighterBoard pour gérer et mettre à jour + * l'état des incendies. En séparant les fonctionnalités liées aux feux dans cette classe, + * on simplifie la gestion de l'état du plateau et facilite les modifications futures de la logique de propagation + * ou d'extinction des feux. + * + * Méthodes principales : + * - void spread(Map<Position, List<Position>> neighbors) : propage les feux vers les cases voisines sauf si elles ont des montagnes. + * - void extinguish(Position position) : éteint le feu à une position spécifique. + * - void extinguishAll(Set<Position> positions) : éteint les feux à plusieurs positions. + */ + +public class Fire { + private final Set<Position> firePositions = new HashSet<>(); + + public Fire(Set<Position> initialFirePositions) { + this.firePositions.addAll(initialFirePositions); + } + + public Set<Position> getPositions() { + return firePositions; + } + + public void spread(Map<Position, List<Position>> neighbors, Set<Position> mountainPositions) { + Set<Position> newFirePositions = new HashSet<>(); + + for (Position firePosition : firePositions) { + if (neighbors.containsKey(firePosition)) { + for (Position neighbor : neighbors.get(firePosition)) { + if (!mountainPositions.contains(neighbor)) { + newFirePositions.add(neighbor); + } + } + } + } + + firePositions.addAll(newFirePositions); + } + + public void extinguish(Position position) { + firePositions.remove(position); + } + + public void extinguishAll(Set<Position> positions) { + firePositions.removeAll(positions); + } +} diff --git a/src/main/java/model/Firefighter.java b/src/main/java/model/Firefighter.java new file mode 100644 index 0000000000000000000000000000000000000000..92c230541c7f77f0dc0c467ca9ff9a69d89061f4 --- /dev/null +++ b/src/main/java/model/Firefighter.java @@ -0,0 +1,55 @@ +package model; + +import util.Position; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.HashSet; + +/** + * Cette classe est responsable des actions des pompiers : se déplacer vers le feu + * le plus proche et éteindre les feux voisins + * + */ + +public class Firefighter { + private Position position; + final model.TargetStrategy targetStrategy; + protected Set<Position> mountainPositions; + protected Set<Position> roadPositions; + + public Firefighter(Position position, model.TargetStrategy targetStrategy, Set<Position> mountainPositions, Set<Position> roadPositions) { + this.position = position; + this.targetStrategy = targetStrategy; + this.mountainPositions = mountainPositions != null ? mountainPositions : new HashSet<>(); + this.roadPositions = roadPositions != null ? roadPositions : new HashSet<>(); + + } + + public Position getPosition() { + return position; + } + + public void setPosition(Position position) { + this.position = position; + } + + public void moveTowardsFire(Set<Position> firePositions, Map<Position, List<Position>> neighbors) { + Position newPosition = targetStrategy.neighborClosestToFire(position, firePositions, neighbors); + if (newPosition != null && (!mountainPositions.contains(newPosition) || roadPositions.contains(newPosition))) { + this.position = newPosition; + } + } + + public void extinguishFiresAround(Set<Position> firePositions, Map<Position, List<Position>> neighbors) { + // Éteindre le feu à la position actuelle + firePositions.remove(position); + + // Éteindre les feux dans les positions voisines + List<Position> adjacentPositions = neighbors.get(position); + for (Position neighbor : adjacentPositions) { + firePositions.remove(neighbor); + } + } +} diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java index c0bd67cc4f444a33c41551779b11f3d619412bef..ab0d9f8ed32952f510e83202e11c1518f5cc2431 100644 --- a/src/main/java/model/FirefighterBoard.java +++ b/src/main/java/model/FirefighterBoard.java @@ -6,142 +6,337 @@ import java.util.*; public class FirefighterBoard implements Board<List<ModelElement>> { - private final int columnCount; - private final int rowCount; - private final int initialFireCount; - private final int initialFirefighterCount; - private final TargetStrategy targetStrategy = new TargetStrategy(); - private List<Position> firefighterPositions; - private Set<Position> firePositions; - private Map<Position, List<Position>> neighbors = new HashMap(); - private final Position[][] positions; - private int step = 0; - private final Random randomGenerator = new Random(); - - public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { - this.columnCount = columnCount; - this.rowCount = rowCount; - this.positions = new Position[rowCount][columnCount]; - for (int column = 0; column < columnCount; column++) - for (int row = 0; row < rowCount; row++) - positions[row][column] = new Position(row, column); - for (int column = 0; column < columnCount; column++) - for (int row = 0; row < rowCount; row++) { - List<Position> list = new ArrayList<>(); - if (row > 0) list.add(positions[row - 1][column]); - if (column > 0) list.add(positions[row][column - 1]); - if (row < rowCount - 1) list.add(positions[row + 1][column]); - if (column < columnCount - 1) list.add(positions[row][column + 1]); - neighbors.put(positions[row][column], list); - } - this.initialFireCount = initialFireCount; - this.initialFirefighterCount = initialFirefighterCount; - initializeElements(); - } - - public void initializeElements() { - firefighterPositions = new ArrayList<>(); - firePositions = new HashSet<>(); - for (int index = 0; index < initialFireCount; index++) - firePositions.add(randomPosition()); - for (int index = 0; index < initialFirefighterCount; index++) - firefighterPositions.add(randomPosition()); - } - - private Position randomPosition() { - return new Position(randomGenerator.nextInt(rowCount), randomGenerator.nextInt(columnCount)); - } - - @Override - public List<ModelElement> getState(Position position) { - List<ModelElement> result = new ArrayList<>(); - for (Position firefighterPosition : firefighterPositions) - if (firefighterPosition.equals(position)) - result.add(ModelElement.FIREFIGHTER); - if (firePositions.contains(position)) - result.add(ModelElement.FIRE); - return result; - } - - @Override - public int rowCount() { - return rowCount; - } - - @Override - public int columnCount() { - return columnCount; - } - - public List<Position> updateToNextGeneration() { - List<Position> modifiedPositions = updateFirefighters(); - modifiedPositions.addAll(updateFires()); - step++; - return modifiedPositions; - } - - private List<Position> updateFires() { - List<Position> modifiedPositions = new ArrayList<>(); - if (step % 2 == 0) { - List<Position> newFirePositions = new ArrayList<>(); - for (Position fire : firePositions) { - newFirePositions.addAll(neighbors.get(fire)); - } - firePositions.addAll(newFirePositions); - modifiedPositions.addAll(newFirePositions); + private final int columnCount; + private final int rowCount; + private final int initialFireCount; + private final int initialFirefighterCount; + private final model.TargetStrategy targetStrategy = new model.TargetStrategy(); + private List<Position> firefighterPositions; + private List<Firefighter> firefighters; + private Set<Position> firePositions; + private Map<Position, List<Position>> neighbors = new HashMap(); + private final Position[][] positions; + private int step = 0; + private final Random randomGenerator = new Random(); + private List<Cloud> clouds; + + private Fire fire; + private Set<Position> mountainPositions; + private Set<Position> roadPositions; + private Set<Position> rockyPositions; + private Map<Position, Integer> rockyFireDelays = new HashMap<>(); // Nouveau champ pour suivre les délais sur les rocailles + + + public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.positions = new Position[rowCount][columnCount]; + this.firefighters = new ArrayList<>(); + for (int column = 0; column < columnCount; column++) + for (int row = 0; row < rowCount; row++) + positions[row][column] = new Position(row, column); + for (int column = 0; column < columnCount; column++) + for (int row = 0; row < rowCount; row++) { + List<Position> list = new ArrayList<>(); + if (row > 0) list.add(positions[row - 1][column]); + if (column > 0) list.add(positions[row][column - 1]); + if (row < rowCount - 1) list.add(positions[row + 1][column]); + if (column < columnCount - 1) list.add(positions[row][column + 1]); + neighbors.put(positions[row][column], list); + } + this.initialFireCount = initialFireCount; + this.initialFirefighterCount = initialFirefighterCount; + this.mountainPositions = new HashSet<>(); + this.roadPositions = new HashSet<>(); + this.rockyPositions = new HashSet<>(); + + initializeElements(); } - return modifiedPositions; - - } - - @Override - public int stepNumber() { - return step; - } - - private List<Position> updateFirefighters() { - List<Position> modifiedPosition = new ArrayList<>(); - List<Position> firefighterNewPositions = new ArrayList<>(); - for (Position firefighterPosition : firefighterPositions) { - Position newFirefighterPosition = - targetStrategy.neighborClosestToFire(firefighterPosition, - firePositions, neighbors); - firefighterNewPositions.add(newFirefighterPosition); - extinguish(newFirefighterPosition); - modifiedPosition.add(firefighterPosition); - modifiedPosition.add(newFirefighterPosition); - List<Position> neighborFirePositions = neighbors.get(newFirefighterPosition).stream() - .filter(firePositions::contains).toList(); - for (Position firePosition : neighborFirePositions) - extinguish(firePosition); - modifiedPosition.addAll(neighborFirePositions); + + public void initializeElements() { + clouds = new ArrayList<>(); + firefighterPositions = new ArrayList<>(); + firePositions = new HashSet<>(); + mountainPositions = new HashSet<>(); + roadPositions = new HashSet<>(); + rockyPositions = new HashSet<>(); + + while (mountainPositions.size() < 10) { + Position newPosition = randomPosition(); + mountainPositions.add(newPosition); + System.out.println("Mountain Position: " + newPosition); // Affiche la position générée + } + + for (int i = 0; i < 10; i++) { + clouds.add(new Cloud(randomPosition())); + } + + for (int index = 0; index < initialFireCount * 10; index++) + firePositions.add(randomPosition()); + fire = new Fire(firePositions); + + int motorizedCount = initialFirefighterCount / 3; + + for (int i = 0; i < motorizedCount; i++) { + MotorizedFireFighter motorizedFireFighter = new MotorizedFireFighter(randomPosition(), targetStrategy, mountainPositions, roadPositions); + firefighters.add(motorizedFireFighter); + firefighterPositions.add(motorizedFireFighter.getPosition()); + } + + // Initialisation des pompiers réguliers + for (int i = 0; i < initialFirefighterCount - motorizedCount; i++) { + Firefighter firefighter = new Firefighter(randomPosition(), targetStrategy, mountainPositions, roadPositions); + firefighters.add(firefighter); + firefighterPositions.add(firefighter.getPosition()); + } + + while (roadPositions.size() < 10) { + Position newPosition = randomPosition(); + roadPositions.add(newPosition); + System.out.println("Road Position: " + newPosition); + } + + while (rockyPositions.size() < 10) { + Position newPosition = randomPosition(); + rockyPositions.add(newPosition); + System.out.println("Rocky Position: " + newPosition); + } } - firefighterPositions = firefighterNewPositions; - return modifiedPosition; - } - - @Override - public void reset() { - step = 0; - initializeElements(); - } - - private void extinguish(Position position) { - firePositions.remove(position); - } - - - @Override - public void setState(List<ModelElement> state, Position position) { - firePositions.remove(position); - for (; ; ) { - if (!firefighterPositions.remove(position)) break; + + private Position randomPosition() { + return new Position(randomGenerator.nextInt(rowCount), randomGenerator.nextInt(columnCount)); } - for (ModelElement element : state) { - switch (element) { - case FIRE -> firePositions.add(position); - case FIREFIGHTER -> firefighterPositions.add(position); - } + + @Override + public List<ModelElement> getState(Position position) { + List<ModelElement> result = new ArrayList<>(); + + // Vérifie le type de chaque pompier + for (Firefighter firefighter : firefighters) { + if (firefighter.getPosition().equals(position)) { + if (firefighter instanceof MotorizedFireFighter) { + result.add(ModelElement.MOTORIZED_FIREFIGHTER); + } else { + result.add(ModelElement.FIREFIGHTER); + } + } + } + if (firePositions.contains(position)) { + result.add(ModelElement.FIRE); + } + if (clouds.stream().anyMatch(cloud -> cloud.getPosition().equals(position))) { + result.add(ModelElement.CLOUD); + } + + if (mountainPositions.contains(position)) { + result.add(ModelElement.MOUNTAIN); + } + + if (roadPositions.contains(position)) { + result.add(ModelElement.ROUTE); + } + + if (rockyPositions.contains(position)) { + result.add(ModelElement.ROCK); + } + + + return result; + } + + + @Override + public int rowCount() { + return rowCount; + } + + @Override + public int columnCount() { + return columnCount; + } + + + public List<Position> updateToNextGeneration() { + List<Position> modifiedPositions = updateFirefighters(); + modifiedPositions.addAll(updateFires()); + modifiedPositions.addAll(updateClouds(neighbors)); + +// Parcourt chaque nuage dans la liste des nuages +// Pour chaque nuage, on vérifie s'il se trouve à une position où il y a un feu. +// Si un feu est présent à la position du nuage, ce dernier l'éteint en appelant la méthode extinguishFire. +// La position du nuage (où le feu a été éteint) est ajoutée à la liste des positions modifiées. + for (Cloud cloud : clouds) { + Position cloudPosition = cloud.getPosition(); + if (this.getState(cloudPosition).contains(ModelElement.FIRE)) { + cloud.extinguishFire(fire); + modifiedPositions.add(cloudPosition); + } + } + + step++; + return modifiedPositions; + } + + + private List<Position> updateFires() { + List<Position> modifiedPositions = new ArrayList<>(); + if (step % 2 == 0) { + List<Position> newFirePositions = new ArrayList<>(); + for (Position fire : firePositions) { + for (Position neighbor : neighbors.get(fire)) { + // Vérifie que la position voisine n'est pas occupée par un nuage, + // qu'elle n'est pas une montagne, et qu'elle n'est pas une route + if (!clouds.stream().anyMatch(cloud -> cloud.getPosition().equals(neighbor)) + && !mountainPositions.contains(neighbor) + && !roadPositions.contains(neighbor)) { + if (rockyPositions.contains(neighbor)) { + if (!rockyFireDelays.containsKey(neighbor)) { + rockyFireDelays.put(neighbor, 4); + } else { + int remainingDelay = rockyFireDelays.get(neighbor); + if(remainingDelay>1){ + rockyFireDelays.put(neighbor, remainingDelay - 1); // Décrémenter le délai + } else { + // Si le délai est écoulé, le feu se propage + newFirePositions.add(neighbor); + rockyFireDelays.remove(neighbor); // Retirer le délai une fois que le feu se propage + } + } + }else { + newFirePositions.add(neighbor); + } + } + } + } + firePositions.addAll(newFirePositions); + modifiedPositions.addAll(newFirePositions); + } + + return modifiedPositions; + } + + + @Override + public int stepNumber() { + return step; + } + + private List<Position> updateFirefighters() { + List<Position> modifiedPositions = new ArrayList<>(); + List<Position> firefighterNewPositions = new ArrayList<>(); + + for (Firefighter firefighter : firefighters) { + Position originalPosition = firefighter.getPosition(); + Position newFirefighterPosition = originalPosition; + + // Déplacer le pompier vers le feu le plus proche + if (firefighter instanceof MotorizedFireFighter) { + // Premier mouvement + Position firstMove = targetStrategy.neighborClosestToFire(newFirefighterPosition, firePositions, neighbors); + if (firstMove != null && !mountainPositions.contains(firstMove)) { + if (roadPositions.contains(firstMove)) { + newFirefighterPosition = firstMove; + } else { + newFirefighterPosition = firstMove; + } + } + + // Deuxième mouvement + Position secondMove = targetStrategy.neighborClosestToFire(newFirefighterPosition, firePositions, neighbors); + if (secondMove != null && !mountainPositions.contains(secondMove)) { + if (roadPositions.contains(secondMove)) { // Privilégie une position avec une route + newFirefighterPosition = secondMove; + } else { + newFirefighterPosition = secondMove; + } + } + } else { + Position neighbor = targetStrategy.neighborClosestToFire(newFirefighterPosition, firePositions, neighbors); + if (neighbor != null && !mountainPositions.contains(neighbor)) { + // Vérifie si la position est une route + if (roadPositions.contains(neighbor)) { + newFirefighterPosition = neighbor; + } else { + newFirefighterPosition = neighbor; + } + } + } + + // Mettre à jour la position du pompier + firefighter.setPosition(newFirefighterPosition); + firefighterNewPositions.add(newFirefighterPosition); + + // Éteindre les feux autour de la nouvelle position + extinguish(newFirefighterPosition); + List<Position> neighborFirePositions = neighbors.get(newFirefighterPosition).stream() + .filter(firePositions::contains).toList(); + for (Position firePosition : neighborFirePositions) { + extinguish(firePosition); + } + + // Ajouter les positions modifiées à la liste + modifiedPositions.add(originalPosition); + modifiedPositions.add(newFirefighterPosition); + modifiedPositions.addAll(neighborFirePositions); + } + + firefighterPositions = firefighterNewPositions; + return modifiedPositions; + } + + + @Override + public void reset() { + step = 0; + initializeElements(); + } + + private void extinguish(Position position) { + firePositions.remove(position); + } + + + @Override + public void setState(List<ModelElement> state, Position position) { + firePositions.remove(position); + firefighterPositions.remove(position); + for (ModelElement element : state) { + switch (element) { + case FIRE -> firePositions.add(position); + case FIREFIGHTER -> { + Firefighter firefighter = new Firefighter(position, targetStrategy, mountainPositions, roadPositions); + firefighters.add(firefighter); + firefighterPositions.add(position); + } + case MOTORIZED_FIREFIGHTER -> { + MotorizedFireFighter motorizedFireFighter = new MotorizedFireFighter(position, targetStrategy, mountainPositions, roadPositions); + firefighters.add(motorizedFireFighter); + firefighterPositions.add(position); + } + case MOUNTAIN -> mountainPositions.add(position); + + case ROUTE -> roadPositions.add(position); + + case ROCK -> rockyPositions.add(position); + } + } + } + + private List<Position> updateClouds(Map<Position, List<Position>> neighbors) { + List<Position> modifiedPositions = new ArrayList<>(); + for (Cloud cloud : clouds) { + Position oldPosition = cloud.getPosition(); + cloud.move(neighbors); + Position newPosition = cloud.getPosition(); + + if (!oldPosition.equals(newPosition)) { + fire.extinguish(oldPosition); + modifiedPositions.add(oldPosition); + + fire.extinguish(newPosition); + modifiedPositions.add(newPosition); + } + } + return modifiedPositions; } - } -} \ No newline at end of file +} diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index 759eee5e54c3a39472d8f7defbbbe6a2b67b8f00..5f84f39f7e8fb30c3fff6d35f9f5a1793af38fcf 100644 --- a/src/main/java/model/ModelElement.java +++ b/src/main/java/model/ModelElement.java @@ -1,5 +1,5 @@ package model; public enum ModelElement { - FIREFIGHTER, FIRE + FIREFIGHTER, FIRE, CLOUD, MOTORIZED_FIREFIGHTER, MOUNTAIN, ROCK, ROUTE } diff --git a/src/main/java/model/MotorizedFireFighter.java b/src/main/java/model/MotorizedFireFighter.java new file mode 100644 index 0000000000000000000000000000000000000000..5d7cecf5878002e439a2d4a8ae34c143c4a8022f --- /dev/null +++ b/src/main/java/model/MotorizedFireFighter.java @@ -0,0 +1,34 @@ +package model; + +import util.Position; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class MotorizedFireFighter extends Firefighter { + + public MotorizedFireFighter(Position position, model.TargetStrategy targetStrategy, Set<Position> mountainPositions, Set<Position> roadPositions) { + super(position, targetStrategy, mountainPositions, roadPositions); + } + + @Override + public void moveTowardsFire(Set<Position> firePositions, Map<Position, List<Position>> neighbors) { + Position current = getPosition(); + + // Premier mouvement + Position firstMove = targetStrategy.neighborClosestToFire(current, firePositions, neighbors); + if (firstMove != null && (!super.mountainPositions.contains(firstMove) || super.roadPositions.contains(firstMove))) { + current = firstMove; + } + + // Deuxième mouvement + Position secondMove = targetStrategy.neighborClosestToFire(current, firePositions, neighbors); + if (secondMove != null && (!super.mountainPositions.contains(secondMove) || super.roadPositions.contains(secondMove))) { + current = secondMove; + } + + // Mise à jour de la position finale après deux mouvements + setPosition(current); + } +} diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java index ffb76112e1af543df5af41fa906082ef11be9967..3c5172d49fd77606d3db0f6c5e00d298b40d6e7b 100644 --- a/src/main/java/view/ViewElement.java +++ b/src/main/java/view/ViewElement.java @@ -3,7 +3,7 @@ package view; import javafx.scene.paint.Color; public enum ViewElement { - FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE), CLOUD(Color.GRAY), MOTORIZED_FIREFIGHTER(Color.BLACK), MOUNTAIN(Color.GREEN), ROUTE(Color.BROWN), ROCK(Color.HOTPINK); final Color color; ViewElement(Color color) { this.color = color;