diff --git a/.gradle/8.10.2/executionHistory/executionHistory.bin b/.gradle/8.10.2/executionHistory/executionHistory.bin index c0a4b6e9b5c9eb964cef30262f4ff6b76a8b5b03..97b9b48bbdd5886fbb8a82db0b1683936f142b3a 100644 Binary files a/.gradle/8.10.2/executionHistory/executionHistory.bin 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 index 8aca32139fab07c3188cba31af7facedf5b5849d..171bc6acfb0e06b4b6c3cecab799a21b784b60ee 100644 Binary files a/.gradle/8.10.2/executionHistory/executionHistory.lock and b/.gradle/8.10.2/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.bin b/.gradle/8.10.2/fileHashes/fileHashes.bin index 2ed903a518b64a69194c55e8a049ff39a0839f58..1b5cbc73c6e61e5bf820916145dfd7bf1d415d90 100644 Binary files a/.gradle/8.10.2/fileHashes/fileHashes.bin 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 index e49212765c741797bec045b9467eb5e66ac21562..95bab72c139aec6844f8b0fcd849a0ddc30fa572 100644 Binary files a/.gradle/8.10.2/fileHashes/fileHashes.lock 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 index 2866b01a8697ad26abfe49b2a5d1235330ad4d4d..352033907f59a15563ae59d12b450338bd14ae98 100644 Binary files a/.gradle/8.10.2/fileHashes/resourceHashesCache.bin and b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 267adf260927eb5a89b797caca8536fd39ec8438..f08260a3a186325b43aa1f1263fafa4e06b8d5be 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index c39049c7d173467720a7872dd13bc4e559fbfa5a..cfdfc0b441cc62dcc09e1f23bf8e6bbdba3d64f4 100644 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/build/classes/java/main/app/SimulatorApplication.class b/build/classes/java/main/app/SimulatorApplication.class index 0945559258306b09c37b530b8c44adfb1b4b4489..3e04e3ad61ce4bc7716996607d7ef0c8de245fe9 100644 Binary files a/build/classes/java/main/app/SimulatorApplication.class and b/build/classes/java/main/app/SimulatorApplication.class differ diff --git a/build/classes/java/main/controller/Controller.class b/build/classes/java/main/controller/Controller.class index 02198abdf2c604ece2c32c166bd85717d737a8a8..4dd7f913efce94e60bb66d88ffc81536e41c6c04 100644 Binary files a/build/classes/java/main/controller/Controller.class and b/build/classes/java/main/controller/Controller.class differ diff --git a/build/classes/java/main/model/FireManager.class b/build/classes/java/main/model/FireManager.class index ea76ad67b5adf13fba5384fb6dd2a8b3286b4952..705b325051543ae9b21b5e6b9d714714e5be4c2d 100644 Binary files a/build/classes/java/main/model/FireManager.class and b/build/classes/java/main/model/FireManager.class differ diff --git a/build/classes/java/main/model/FirefighterBoard$1.class b/build/classes/java/main/model/FirefighterBoard$1.class index 4cdc20809cf2e9031efd5f9fcf97ae781aa4ebdd..9746dde585992544a8ed31b52f2622060d8373b2 100644 Binary files a/build/classes/java/main/model/FirefighterBoard$1.class 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 index 7ad42695d3031c66d3e9fd508bd9ae0b6979cb92..3e742235542383603f5bec9a42fe8c9c5fde97cb 100644 Binary files a/build/classes/java/main/model/FirefighterBoard.class and b/build/classes/java/main/model/FirefighterBoard.class differ diff --git a/build/classes/java/main/model/FirefighterManager.class b/build/classes/java/main/model/FirefighterManager.class index 2ce4265d7559410dce8de411a7cb4e3ffde87b71..89b6c24ed9ef15fad7b0854825234ded5a00d66a 100644 Binary files a/build/classes/java/main/model/FirefighterManager.class and b/build/classes/java/main/model/FirefighterManager.class differ diff --git a/build/classes/java/main/model/ModelElement.class b/build/classes/java/main/model/ModelElement.class index 233ea071f11d658f111ffcfdd0d89e41d52ca544..ab695532d616c8cf4fa9ac577236893340a8bc44 100644 Binary files a/build/classes/java/main/model/ModelElement.class and b/build/classes/java/main/model/ModelElement.class differ diff --git a/build/classes/java/main/model/SimpleFireSpreadStrategy.class b/build/classes/java/main/model/SimpleFireSpreadStrategy.class index 71a1bea3dc54cd4fb7ee7550ab3f50a9706ce540..a1cb78f44996e7467ed4e0de94b471705d890241 100644 Binary files a/build/classes/java/main/model/SimpleFireSpreadStrategy.class and b/build/classes/java/main/model/SimpleFireSpreadStrategy.class differ diff --git a/build/classes/java/main/model/SimpleFirefighterMovementStrategy.class b/build/classes/java/main/model/SimpleFirefighterMovementStrategy.class index 3ead82b78da697d5082af4d91ca1c7c7264e762f..07ada7ef29ea522644ebea653471298b6a8aed32 100644 Binary files a/build/classes/java/main/model/SimpleFirefighterMovementStrategy.class and b/build/classes/java/main/model/SimpleFirefighterMovementStrategy.class differ diff --git a/build/classes/java/main/module-info.class b/build/classes/java/main/module-info.class index a05e120336680c15a80138be7c30617ca4e5473c..88bc26991b02427659843d54b36d2169ec1b6e75 100644 Binary files a/build/classes/java/main/module-info.class and b/build/classes/java/main/module-info.class differ diff --git a/build/classes/java/main/view/FirefighterGrid.class b/build/classes/java/main/view/FirefighterGrid.class index 831699ca3ca58a17f7b79bad1d1464aeb6d30a4c..18e46ef5be06988a93fa104fac2993de3f3c5349 100644 Binary files a/build/classes/java/main/view/FirefighterGrid.class and b/build/classes/java/main/view/FirefighterGrid.class differ diff --git a/build/classes/java/main/view/ViewElement.class b/build/classes/java/main/view/ViewElement.class index 0ea0f2a1be043584c460f2e4488911772ffa0f00..6e0ba4cb9d010f7ec89661d33c7f27a0eeba7153 100644 Binary files a/build/classes/java/main/view/ViewElement.class and b/build/classes/java/main/view/ViewElement.class differ diff --git a/build/classes/java/test/model/FirefighterBoardTest.class b/build/classes/java/test/model/FirefighterBoardTest.class new file mode 100644 index 0000000000000000000000000000000000000000..a0d71f0e7a0e444e0331454984cd677da7957fb9 Binary files /dev/null and b/build/classes/java/test/model/FirefighterBoardTest.class differ diff --git a/build/distributions/firefighter-shadow.tar b/build/distributions/firefighter-shadow.tar new file mode 100644 index 0000000000000000000000000000000000000000..a5c7784ec2465e0063d63410fe13538dd65eda6e Binary files /dev/null and b/build/distributions/firefighter-shadow.tar differ diff --git a/build/distributions/firefighter-shadow.zip b/build/distributions/firefighter-shadow.zip new file mode 100644 index 0000000000000000000000000000000000000000..0c1caf97cb1e82cb07f2de702cb277531e05b4b1 Binary files /dev/null and b/build/distributions/firefighter-shadow.zip differ diff --git a/build/distributions/firefighter.tar b/build/distributions/firefighter.tar new file mode 100644 index 0000000000000000000000000000000000000000..cb82184ff5ea66324b8a972a3b10b5e605e3e053 Binary files /dev/null and b/build/distributions/firefighter.tar differ diff --git a/build/distributions/firefighter.zip b/build/distributions/firefighter.zip new file mode 100644 index 0000000000000000000000000000000000000000..0884f890ea02c128b9a67be3865e20efba7031af Binary files /dev/null and b/build/distributions/firefighter.zip differ diff --git a/build/libs/firefighter-all.jar b/build/libs/firefighter-all.jar index d89d277896c186f81bdedda0944269a911b13256..4d96d916601c71cff5491caa76660f7f282a2ed4 100644 Binary files a/build/libs/firefighter-all.jar and b/build/libs/firefighter-all.jar differ diff --git a/build/libs/firefighter.jar b/build/libs/firefighter.jar new file mode 100644 index 0000000000000000000000000000000000000000..499a4746df06417ae513e85862d43c1009313872 Binary files /dev/null and b/build/libs/firefighter.jar differ diff --git a/build/scripts/firefighter b/build/scripts/firefighter new file mode 100755 index 0000000000000000000000000000000000000000..f14c33053ef5daa948cb848df0d5f2d8fe4204a1 --- /dev/null +++ b/build/scripts/firefighter @@ -0,0 +1,251 @@ +#!/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. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# firefighter 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 firefighter +# +# 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 FIREFIGHTER_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/HEAD/platforms/jvm/plugins-application/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 + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}.." > /dev/null && printf '%s +' "$PWD" ) || exit + +# 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/lib/firefighter.jar:$APP_HOME/lib/javafx-fxml-21-linux.jar:$APP_HOME/lib/javafx-controls-21-linux.jar:$APP_HOME/lib/javafx-graphics-21-linux.jar:$APP_HOME/lib/javafx-base-21-linux.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 + if ! command -v java >/dev/null 2>&1 + then + 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 +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + 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 FIREFIGHTER_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 + + +# Add default JVM options here. You can also use JAVA_OPTS and FIREFIGHTER_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + -classpath "$CLASSPATH" \ + app.SimulatorMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# 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 $FIREFIGHTER_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/build/scripts/firefighter.bat b/build/scripts/firefighter.bat new file mode 100644 index 0000000000000000000000000000000000000000..8a549278323de8af8270f8c39555b9d64b6caed5 --- /dev/null +++ b/build/scripts/firefighter.bat @@ -0,0 +1,94 @@ +@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 +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@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=. +@rem This is normally unused +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 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% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\lib\firefighter.jar;%APP_HOME%\lib\javafx-fxml-21-linux.jar;%APP_HOME%\lib\javafx-controls-21-linux.jar;%APP_HOME%\lib\javafx-graphics-21-linux.jar;%APP_HOME%\lib\javafx-base-21-linux.jar + + +@rem Execute firefighter +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %FIREFIGHTER_OPTS% -classpath "%CLASSPATH%" app.SimulatorMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 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! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%FIREFIGHTER_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/build/scriptsShadow/firefighter.bat b/build/scriptsShadow/firefighter.bat index 9e2b7852d7d9a99ebb07330343dc8410bff878dd..9d9829681fb66d0a67461026443aef372fc9b694 100644 --- a/build/scriptsShadow/firefighter.bat +++ b/build/scriptsShadow/firefighter.bat @@ -1,84 +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 - +@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 index d54225454e4b407b5dc77c5ad491c7b48d190ba2..1359edc24a31a1f301ffff7a8d63ae879abe849e 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/build/tmp/jar/MANIFEST.MF b/build/tmp/jar/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..59499bce4a2bd51cba227b7c00fcf745b19c95a4 --- /dev/null +++ b/build/tmp/jar/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/build/tmp/shadowJar/MANIFEST.MF b/build/tmp/shadowJar/MANIFEST.MF index 983eb8f878c7c5d812feb13f103cec077531b705..2c5dafadb5f53a219e1c22537b872baf7d0b350d 100644 --- a/build/tmp/shadowJar/MANIFEST.MF +++ b/build/tmp/shadowJar/MANIFEST.MF @@ -1,3 +1,3 @@ -Manifest-Version: 1.0 -Main-Class: app.SimulatorMain - +Manifest-Version: 1.0 +Main-Class: app.SimulatorMain + diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java index e88b0e9856086cc6f53f2782175393dca6365eb6..12878f7c6f4c083a7a742c397ecc44f355e33023 100644 --- a/src/main/java/app/SimulatorApplication.java +++ b/src/main/java/app/SimulatorApplication.java @@ -11,49 +11,51 @@ import java.io.IOException; import java.net.URL; public class SimulatorApplication extends javafx.application.Application { - private static final String VIEW_RESOURCE_PATH = "/view/view.fxml"; - private static final String APP_NAME = "Firefighter simulator"; - private static final int ROW_COUNT = 20; - private static final int COLUMN_COUNT = 20; - private static final int BOX_WIDTH = 50; - private static final int BOX_HEIGHT = 50; - public static final int INITIAL_FIRE_COUNT = 3; - public static final int INITIAL_FIREFIGHTER_COUNT = 6; - - private Stage primaryStage; - private Parent view; - private void initializePrimaryStage(Stage primaryStage) { - this.primaryStage = primaryStage; - this.primaryStage.setTitle(APP_NAME); - this.primaryStage.setOnCloseRequest(event -> Platform.exit()); - this.primaryStage.setResizable(true); - this.primaryStage.sizeToScene(); - } - - @Override - public void start(Stage primaryStage) throws IOException { - initializePrimaryStage(primaryStage); - initializeView(); - showScene(); - } - - private void initializeView() throws IOException { - FXMLLoader loader = new FXMLLoader(); - URL location = SimulatorApplication.class.getResource(VIEW_RESOURCE_PATH); - loader.setLocation(location); - view = loader.load(); - Controller controller = loader.getController(); - controller.initialize(BOX_WIDTH, BOX_HEIGHT, COLUMN_COUNT, ROW_COUNT, - INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); - } - - private void showScene() { - Scene scene = new Scene(view); - primaryStage.setScene(scene); - primaryStage.show(); - } - - public static void main(String[] args) { - launch(args); - } + private static final String VIEW_RESOURCE_PATH = "/view/view.fxml"; + private static final String APP_NAME = "Firefighter Simulator"; + private static final int ROW_COUNT = 20; + private static final int COLUMN_COUNT = 20; + private static final int BOX_WIDTH = 30; + private static final int BOX_HEIGHT = 30; + public static final int INITIAL_FIRE_COUNT = 5; + public static final int INITIAL_FIREFIGHTER_COUNT = 4; + + private Stage primaryStage; + private Parent view; + + private void initializePrimaryStage(Stage primaryStage) { + this.primaryStage = primaryStage; + this.primaryStage.setTitle(APP_NAME); + this.primaryStage.setOnCloseRequest(event -> Platform.exit()); + this.primaryStage.setResizable(false); + this.primaryStage.sizeToScene(); + } + + @Override + public void start(Stage primaryStage) throws IOException { + initializePrimaryStage(primaryStage); + initializeView(); + showScene(); + } + + private void initializeView() throws IOException { + FXMLLoader loader = new FXMLLoader(); + URL location = SimulatorApplication.class.getResource(VIEW_RESOURCE_PATH); + loader.setLocation(location); + view = loader.load(); + + Controller controller = loader.getController(); + controller.initialize(BOX_WIDTH, BOX_HEIGHT, COLUMN_COUNT, ROW_COUNT, + INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); + } + + private void showScene() { + Scene scene = new Scene(view); + primaryStage.setScene(scene); + primaryStage.show(); + } + + public static void main(String[] args) { + launch(args); + } } diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 2a60897c6eb8ba847cb8589840c16a0f175ce0a3..7305525e8f61db2eae6c5ef7227f6dae1597365f 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -1,141 +1,91 @@ package controller; -import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ToggleButton; -import javafx.scene.control.ToggleGroup; import javafx.util.Duration; -import javafx.util.Pair; -import model.Board; -import model.ModelElement; import model.FirefighterBoard; -import util.Position; -import view.Grid; -import view.ViewElement; - -import java.util.ArrayList; -import java.util.List; - -import static java.util.Objects.requireNonNull; +import view.FirefighterGrid; public class Controller { - public static final int PERIOD_IN_MILLISECONDS = 50; - @FXML - public Button restartButton; + private FirefighterBoard board; + private Timeline timeline; + @FXML - public Button oneStepButton; + private Label generationNumberLabel; + @FXML - public Label generationNumberLabel; + private Button restartButton; + @FXML - private ToggleButton pauseToggleButton; + private Button oneStepButton; + @FXML private ToggleButton playToggleButton; - @FXML - private Grid<ViewElement> grid; - private Timeline timeline; - private Board<List<ModelElement>> board; @FXML - private void initialize() { - initializePlayAndPauseToggleButtons(); - initializeTimeline(); - } - - private void initializePlayAndPauseToggleButtons() { - ToggleGroup toggleGroup = new PersistentToggleGroup(); - toggleGroup.getToggles().addAll(playToggleButton, pauseToggleButton); - pauseToggleButton.setSelected(true); - } + private ToggleButton pauseToggleButton; - private void setModel(FirefighterBoard firefighterBoard) { - this.board = requireNonNull(firefighterBoard, "firefighter.model is null"); - } + @FXML + private FirefighterGrid grid; - private void updateBoard(){ - List<Position> updatedPositions = board.updateToNextGeneration(); - List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>(); - for(Position updatedPosition : updatedPositions){ - List<ModelElement> squareState = board.getState(updatedPosition); - ViewElement viewElement = getViewElement(squareState); - updatedSquares.add(new Pair<>(updatedPosition, viewElement)); - } - grid.repaint(updatedSquares); - updateGenerationLabel(board.stepNumber()); - } + public void initialize(int boxWidth, int boxHeight, int columns, int rows, int fireCount, int firefighterCount) { + // Initialize the simulation board and connect it to the grid + board = new FirefighterBoard(columns, rows, fireCount, firefighterCount); + grid.initialize(columns, rows, boxWidth, boxHeight, board); - 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++) - viewElements[row][column] = getViewElement(board.getState(new Position(row, column))); - grid.repaint(viewElements); - updateGenerationLabel(board.stepNumber()); - } + // Initialize timeline for automatic progression + timeline = new Timeline(new KeyFrame(Duration.seconds(1), event -> updateGame())); + timeline.setCycleCount(Timeline.INDEFINITE); - private ViewElement getViewElement(List<ModelElement> squareState) { - if(squareState.contains(ModelElement.FIREFIGHTER)){ - return ViewElement.FIREFIGHTER; - } - if (squareState.contains(ModelElement.FIRE)){ - return ViewElement.FIRE; - } - return ViewElement.EMPTY; + // Ensure initial UI state is consistent + updateGenerationLabel(); + pauseToggleButton.setSelected(true); } - private void initializeTimeline() { - Duration duration = new Duration(Controller.PERIOD_IN_MILLISECONDS); - EventHandler<ActionEvent> eventHandler = - event -> updateBoard(); - KeyFrame keyFrame = new KeyFrame(duration, eventHandler); - timeline = new Timeline(keyFrame); - timeline.setCycleCount(Animation.INDEFINITE); - } - public void play() { - timeline.play(); + @FXML + private void restartButtonAction() { + stopSimulation(); + board.reset(); + grid.repaint(); + updateGenerationLabel(); } - - public void pause() { - timeline.pause(); + @FXML + private void oneStepButtonAction() { + stopSimulation(); + updateGame(); } - public void pauseToggleButtonAction() { - this.pause(); + @FXML + private void playToggleButtonAction() { + startSimulation(); } - public void playToggleButtonAction() { - this.play(); + @FXML + private void pauseToggleButtonAction() { + stopSimulation(); } - public void restartButtonAction() { - this.pause(); - board.reset(); - pauseToggleButton.setSelected(true); - repaintGrid(); + private void startSimulation() { + timeline.play(); } - 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(); + private void stopSimulation() { + timeline.stop(); } - public void oneStepButtonAction() { - this.pause(); - updateBoard(); + private void updateGame() { + board.updateToNextGeneration(); + grid.repaint(); + updateGenerationLabel(); } - private void updateGenerationLabel(int value){ - generationNumberLabel.setText(Integer.toString(value)); + private void updateGenerationLabel() { + generationNumberLabel.setText(String.valueOf(board.stepNumber())); } -} \ No newline at end of file +} diff --git a/src/main/java/model/FireManager.java b/src/main/java/model/FireManager.java index e843edffb68418dc041d7492eb3a030f6d3d8686..c8d2f3d53b0fc8841c944838de216ce8b0a22424 100644 --- a/src/main/java/model/FireManager.java +++ b/src/main/java/model/FireManager.java @@ -6,44 +6,29 @@ import java.util.*; public class FireManager { private Set<Position> firePositions; - private int turnCounter; private FireSpreadStrategy fireSpreadStrategy; - public FireManager(FireSpreadStrategy fireSpread) { + public FireManager(FireSpreadStrategy fireSpreadStrategy) { this.firePositions = new HashSet<>(); - this.turnCounter = 0; - this.fireSpreadStrategy = fireSpread; + this.fireSpreadStrategy = fireSpreadStrategy; } + public void initializeFires(int fireCount, int rowCount, int columnCount, Random random) { - firePositions.clear(); + // Initialize fire positions randomly on the grid for (int i = 0; i < fireCount; i++) { firePositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); } } - public List<Position> fireSpread(Map<Position, List<Position>> neighbors){ - List<Position> newFires = new ArrayList<>(); - if (turnCounter % 2 == 0) { - for (Position fire : firePositions) { - List<Position> neighborList = neighbors.get(fire); - if (neighborList != null){ - for (Position neighbor : neighborList) { - if (!firePositions.contains(neighbor)) { - newFires.add(neighbor); - } - } - } - } - } - firePositions.addAll(newFires); - turnCounter++; - return newFires; - } - public void extinguish(Position position){ - if (firePositions.contains(position)) { - firePositions.remove(position); - } - } + public Set<Position> getFirePositions() { return firePositions; } + + public List<Position> spreadFire(Map<Position, List<Position>> neighbors) { + return fireSpreadStrategy.spreadFire(firePositions, neighbors); + } + + public void extinguish(Position position) { + firePositions.remove(position); + } } diff --git a/src/main/java/model/FireSpreadStrategy.java b/src/main/java/model/FireSpreadStrategy.java index a775891351fe0a721567e1a33f99d43078cb151a..ef9f02549a5c6f0b67e6b86565710a82f37b5433 100644 --- a/src/main/java/model/FireSpreadStrategy.java +++ b/src/main/java/model/FireSpreadStrategy.java @@ -7,5 +7,5 @@ import java.util.Map; import java.util.Set; public interface FireSpreadStrategy { - List<Position> spreadFire(Set<Position> positions, Map<Position, List<Position>> neighbors); + List<Position> spreadFire(Set<Position> firePositions, Map<Position, List<Position>> neighbors); } diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java index ea6f8034b0eeaac4c5c9e5ff81b8c67bfc808913..7a45e30989dca0f17f70252a47a86bee0af30ffb 100644 --- a/src/main/java/model/FirefighterBoard.java +++ b/src/main/java/model/FirefighterBoard.java @@ -1,61 +1,78 @@ package model; import util.Position; - +import javafx.util.Pair; 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 List<Position> firefighterPositions; + private Set<Position> firePositions; + private final Map<Position, List<Position>> neighbors; + private final Position[][] positions; - private int rowCount; - private int columnCount; - private final FireManager fireManager; - private final FirefighterManager firefighterManager; - private final NeighborManager neighborManager; - private int step; + private int step = 0; + // Constructor for FirefighterBoard public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { this.columnCount = columnCount; this.rowCount = rowCount; - this.neighborManager = new NeighborManager(rowCount, columnCount); + this.initialFireCount = initialFireCount; + this.initialFirefighterCount = initialFirefighterCount; - this.fireManager = new FireManager(new SimpleFireSpreadStrategy()); - this.firefighterManager = new FirefighterManager(new SimpleFirefighterMovementStrategy()); + this.positions = new Position[rowCount][columnCount]; + this.firefighterPositions = new ArrayList<>(); + this.firePositions = new HashSet<>(); + this.neighbors = new HashMap<>(); - Random random = new Random(); - fireManager.initializeFires(initialFireCount, rowCount,columnCount, random); - firefighterManager.initializeFireFightersPositions(initialFirefighterCount,rowCount,columnCount,random); - this.step = 0; + initializeBoard(); } - @Override - public List<ModelElement> getState(Position position) { - List<ModelElement> elements = new ArrayList<>(); + private void initializeBoard() { + Random random = new Random(); - // Check if the position contains a fire - if (fireManager.getFirePositions().contains(position)) { - elements.add(ModelElement.FIRE); + // Initialize fire positions + for (int i = 0; i < initialFireCount; i++) { + firePositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); } - // Check if the position contains a firefighter - if (firefighterManager.getFirefighterPositions().contains(position)) { - elements.add(ModelElement.FIREFIGHTER); + // Initialize firefighter positions + for (int i = 0; i < initialFirefighterCount; i++) { + firefighterPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); } - return elements; + // Initialize neighbors map + for (int row = 0; row < rowCount; row++) { + for (int col = 0; col < columnCount; col++) { + positions[row][col] = new Position(row, col); + neighbors.put(positions[row][col], calculateNeighbors(row, col)); + } + } } - @Override - public void setState(List<ModelElement> state, Position position) { - fireManager.extinguish(position); - firefighterManager.getFirefighterPositions().remove(position); + private List<Position> calculateNeighbors(int row, int col) { + List<Position> adjacentPositions = new ArrayList<>(); + if (row > 0) adjacentPositions.add(new Position(row - 1, col)); // Top neighbor + if (col > 0) adjacentPositions.add(new Position(row, col - 1)); // Left neighbor + if (row < rowCount - 1) adjacentPositions.add(new Position(row + 1, col)); // Bottom neighbor + if (col < columnCount - 1) adjacentPositions.add(new Position(row, col + 1)); // Right neighbor + return adjacentPositions; + } - // Add elements based on the new state - for (ModelElement element : state) { - switch (element) { - case FIRE -> fireManager.getFirePositions().add(position); - case FIREFIGHTER -> firefighterManager.getFirefighterPositions().add(position); - } + @Override + public List<ModelElement> getState(Position position) { + List<ModelElement> result = new ArrayList<>(); + if (firefighterPositions.contains(position)) { + result.add(ModelElement.FIREFIGHTER); + } + if (firePositions.contains(position)) { + result.add(ModelElement.FIRE); } + return result; } @Override @@ -69,59 +86,91 @@ public class FirefighterBoard implements Board<List<ModelElement>> { } @Override - public List<Position> updateToNextGeneration() { - List<Position> modifiedPositions = new ArrayList<>(); - - // Spread the fires and update affected positions - modifiedPositions.addAll(fireManager.fireSpread(neighborManager.getNeighbors())); - - // Move firefighters and update affected positions - modifiedPositions.addAll(firefighterManager.moveFireFighters( - fireManager.getFirePositions(), - neighborManager.getNeighbors() - )); - - // Increment the step count - step++; - - return modifiedPositions; + public int stepNumber() { + return step; } @Override public void reset() { - // Reset step and reinitialize managers - this.step = 0; - - Random random = new Random(); - fireManager.getFirePositions().clear(); - firefighterManager.getFirefighterPositions().clear(); + step = 0; + firefighterPositions.clear(); + firePositions.clear(); - fireManager.initializeFires(fireManager.getFirePositions().size(), rowCount, columnCount, random); - firefighterManager.initializeFireFightersPositions( - firefighterManager.getFirefighterPositions().size(), rowCount, columnCount, random - ); + initializeBoard(); // Reinitialize the board } @Override - public int stepNumber() { - return step; - } -} - - - + 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 -> firefighterPositions.add(position); + } + } + } + @Override + public List<Position> updateToNextGeneration() { + List<Position> modifiedPositions = new ArrayList<>(); + // Spread fire every two rounds + if (step % 2 == 1) { + firePositions.addAll(spreadFire()); + modifiedPositions.addAll(firePositions); + } + // Update firefighter positions + FirefighterManager firefighterManager = new FirefighterManager(new SimpleFirefighterMovementStrategy()); + List<Position> firefighterModified = firefighterManager.moveFireFighters(firePositions, neighbors); + modifiedPositions.addAll(firefighterModified); + firefighterPositions = firefighterManager.getFirefighterPositions(); + // After firefighters move, extinguish fire in the neighborhood + extinguishNearbyFire(modifiedPositions); + step++; + return modifiedPositions; + } + private Set<Position> spreadFire() { + Set<Position> newFirePositions = new HashSet<>(); + for (Position firePosition : firePositions) { + newFirePositions.addAll(neighbors.get(firePosition)); // Spread fire to neighbors + } + return newFirePositions; + } + private void extinguishNearbyFire(List<Position> modifiedPositions) { + for (Position firefighterPosition : firefighterPositions) { + List<Position> nearbyFires = neighbors.get(firefighterPosition); + for (Position neighbor : nearbyFires) { + if (firePositions.contains(neighbor)) { + firePositions.remove(neighbor); // Extinguish fire in neighboring positions + modifiedPositions.add(neighbor); + } + } + } + } + public List<Pair<Position, ModelElement>> getUpdatedElements() { + List<Pair<Position, ModelElement>> updatedElements = new ArrayList<>(); + // Add fire positions + for (Position firePosition : firePositions) { + updatedElements.add(new Pair<>(firePosition, ModelElement.FIRE)); + } + // Add firefighter positions + for (Position firefighterPosition : firefighterPositions) { + updatedElements.add(new Pair<>(firefighterPosition, ModelElement.FIREFIGHTER)); + } + return updatedElements; + } +} diff --git a/src/main/java/model/FirefighterManager.java b/src/main/java/model/FirefighterManager.java index 5a7422fbdb9c2e1d72d59958545ed218e8158484..ec12a1350431a100df56266a7742ff841628f078 100644 --- a/src/main/java/model/FirefighterManager.java +++ b/src/main/java/model/FirefighterManager.java @@ -6,86 +6,49 @@ import java.util.*; public class FirefighterManager { private List<Position> firefighterPositions; - private FirefighterMovementStrategy firefighterMovementStrategy; + private FirefighterMovementStrategy movementStrategy; - public FirefighterManager(FirefighterMovementStrategy firefighterMovementStrategy) { - this.firefighterPositions = new ArrayList<>(); - this.firefighterMovementStrategy = firefighterMovementStrategy; + public FirefighterManager(FirefighterMovementStrategy movementStrategy) { + this.movementStrategy = movementStrategy; + firefighterPositions = new ArrayList<>(); } + public void initializeFireFightersPositions(int count, int rowCount, int columnCount, Random random) { + // Initialize firefighter positions randomly on the grid for (int i = 0; i < count; i++) { firefighterPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); } } + public List<Position> moveFireFighters(Set<Position> firePositions, Map<Position, List<Position>> neighbors) { List<Position> modifiedPositions = new ArrayList<>(); - - for (int i = 0; i < firefighterPositions.size(); i++) { - Position firefighter = firefighterPositions.get(i); - for (Position neighbor : neighbors.get(firefighter)) { - if (firePositions.contains(neighbor)) { - firePositions.remove(neighbor); // Extinguish fire at the neighbor - modifiedPositions.add(neighbor); // Track extinguished fire position + List<Position> newPositions = new ArrayList<>(); + + for (Position firefighterPosition : firefighterPositions) { + // Move firefighters towards the nearest fire + Position newPosition = movementStrategy.moveToClosestFire(firefighterPosition, firePositions, neighbors); + + // Extinguish fire in the neighboring cells + List<Position> nearbyFires = neighbors.get(newPosition); + for (Position firePosition : nearbyFires) { + if (firePositions.contains(firePosition)) { + firePositions.remove(firePosition); // Extinguish the fire + modifiedPositions.add(firePosition); // Track the modified fire position } } - Position closestFire = findClosestFire(firefighter, firePositions); - - if (closestFire != null ) { - Position newPosition = moveTowards(firefighter, closestFire); - firefighterPositions.set(i, newPosition); - modifiedPositions.add(newPosition); - } - - for (Position neighbor : neighbors.get(firefighter)) { - if (firePositions.contains(neighbor)) { - firePositions.remove(neighbor); - modifiedPositions.add(neighbor); - } - } + // Update the firefighter's new position + newPositions.add(newPosition); + modifiedPositions.add(firefighterPosition); // Track the original firefighter position + modifiedPositions.add(newPosition); // Track the new firefighter position } + firefighterPositions = newPositions; // Update the firefighter positions list with new positions return modifiedPositions; } + public List<Position> getFirefighterPositions() { return firefighterPositions; } - - private Position findClosestFire(Position firefighter, Set<Position> firePositions) { - Position closestFire = null; - int minDistance = Integer.MAX_VALUE; - - for (Position fire : firePositions) { - int distance = Math.abs(fire.getRow() - firefighter.getRow()) + Math.abs(fire.getCol() - firefighter.getCol()); - if (distance < minDistance) { - minDistance = distance; - closestFire = fire; - } - } - - return closestFire; - } - - private Position moveTowards(Position firefighter, Position target) { - int currentRow = firefighter.getRow(); - int currentCol = firefighter.getCol(); - - int targetRow = target.getRow(); - int targetCol = target.getCol(); - - if (currentRow < targetRow) { - return new Position(currentRow + 1, currentCol); // Move down - } else if (currentRow > targetRow) { - return new Position(currentRow - 1, currentCol); // Move up - } else if (currentCol < targetCol) { - return new Position(currentRow, currentCol + 1); // Move right - } else if (currentCol > targetCol) { - return new Position(currentRow, currentCol - 1); // Move left - } - - return firefighter; - } - - - } + diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index 759eee5e54c3a39472d8f7defbbbe6a2b67b8f00..5212cc5dc358e893318e4c01fb2926782f07b496 100644 --- a/src/main/java/model/ModelElement.java +++ b/src/main/java/model/ModelElement.java @@ -1,5 +1,16 @@ package model; + public enum ModelElement { - FIREFIGHTER, FIRE + FIREFIGHTER("blue"), FIRE("red"); + + private final String color; + + ModelElement(String color) { + this.color = color; + } + + public String getColor() { + return color; + } } diff --git a/src/main/java/model/SimpleFireSpreadStrategy.java b/src/main/java/model/SimpleFireSpreadStrategy.java index af5438d7a352124c299e18111432dc2e9ceb2fd6..b03eb0f16bdbd7388f91de5d64a5bb2e680ad432 100644 --- a/src/main/java/model/SimpleFireSpreadStrategy.java +++ b/src/main/java/model/SimpleFireSpreadStrategy.java @@ -1,18 +1,15 @@ package model; import util.Position; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.ArrayList; +import java.util.*; public class SimpleFireSpreadStrategy implements FireSpreadStrategy { + @Override - public List<Position> spreadFire(Set<Position> positions, Map<Position, List<Position>> neighbors) { + public List<Position> spreadFire(Set<Position> firePositions, Map<Position, List<Position>> neighbors) { List<Position> newFirePositions = new ArrayList<>(); - for (Position fire : positions) { - newFirePositions.addAll(neighbors.get(fire)); + for (Position fire : firePositions) { + newFirePositions.addAll(neighbors.getOrDefault(fire, List.of())); } return newFirePositions; } diff --git a/src/main/java/model/SimpleFirefighterMovementStrategy.java b/src/main/java/model/SimpleFirefighterMovementStrategy.java index 8fb526850b9c6bb4a4defe62a597c36b34281cbc..a8f59ec2a646f3cb564eed761865d002c847a492 100644 --- a/src/main/java/model/SimpleFirefighterMovementStrategy.java +++ b/src/main/java/model/SimpleFirefighterMovementStrategy.java @@ -2,9 +2,7 @@ package model; import util.Position; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class SimpleFirefighterMovementStrategy implements FirefighterMovementStrategy { @Override @@ -24,8 +22,8 @@ public class SimpleFirefighterMovementStrategy implements FirefighterMovementStr } private int calculateDistance(Position a, Position b) { + // Use Manhattan distance return Math.abs(a.getRow() - b.getRow()) + Math.abs(a.getCol() - b.getCol()); - - } } + diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 4c36d97709b342e457203c75d081fc5cc1955c0f..60722c4f2d818d7d53a64a6dce509fa6eb0a48a3 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,4 +5,5 @@ module firefighter { opens controller to javafx.fxml; exports app; opens app to javafx.fxml; + opens view to javafx.fxml; } diff --git a/src/main/java/package-info.java b/src/main/java/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/java/view/FirefighterGrid.java b/src/main/java/view/FirefighterGrid.java index 4c9041f034ec9a4eb07ce4334de237f1e99ccdc9..ab926abfa39a23b8fdf3fb818e03f25bd1f78c53 100644 --- a/src/main/java/view/FirefighterGrid.java +++ b/src/main/java/view/FirefighterGrid.java @@ -1,99 +1,70 @@ package view; import javafx.scene.canvas.Canvas; +import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; import javafx.util.Pair; +import model.ModelElement; +import model.FirefighterBoard; import util.Position; -import java.util.List; +public class FirefighterGrid extends Canvas { -public class FirefighterGrid extends Canvas implements Grid<ViewElement>{ - - private void paintElementAtPosition(ViewElement element, Position position) { - paintBox(position.row(), position.column(), element.color); - } + private int columns; + private int rows; private int boxWidth; private int boxHeight; - private int columnCount; - private int rowCount; - - @Override - public void repaint(List<Pair<Position, ViewElement>> positionedElements) { - clear(positionedElements); - paint(positionedElements); - paintLines(); - } + private FirefighterBoard board; - private void clear(List<Pair<Position, ViewElement>> positionedElements) { - for (Pair<Position, ViewElement> positionElement : positionedElements) { - Position position = positionElement.getKey(); - clearBox(position.row(), position.column()); - } - } - - private void paint(List<Pair<Position, ViewElement>> positionedElements) { - for(Pair<Position, ViewElement> pair : positionedElements){ - paintElementAtPosition(pair.getValue(), pair.getKey()); - } - } - - @Override - public void repaint(ViewElement[][] elements) { - clear(); - paint(elements); - paintLines(); - } - - private void clear() { - getGraphicsContext2D().clearRect(0,0,getWidth(), getHeight()); - } - - private void paint(ViewElement[][] elements) { - for(int column = 0; column < columnCount; column++) - for(int row = 0; row < rowCount; row++){ - paintElementAtPosition(elements[row][column], new Position(row, column)); - } - } - - public int columnCount() { - return columnCount; - } - - public int rowCount() { - return rowCount; - } - - @Override - public void setDimensions(int columnCount, int rowCount, int boxWidth, int boxHeight) { + // Initialize the grid dimensions and board reference + public void initialize(int columns, int rows, int boxWidth, int boxHeight, FirefighterBoard board) { + this.columns = columns; + this.rows = rows; this.boxWidth = boxWidth; this.boxHeight = boxHeight; - this.columnCount = columnCount; - this.rowCount = rowCount; - super.setWidth(boxWidth * columnCount); - super.setHeight(boxHeight * rowCount); - } - - private void paintLines(){ - paintHorizontalLines(); - paintVerticalLines(); + this.board = board; + setWidth(columns * boxWidth); // Set canvas width based on grid size + setHeight(rows * boxHeight); // Set canvas height based on grid size } - private void paintVerticalLines() { - for(int column = 0; column < columnCount; column++) - getGraphicsContext2D().strokeLine(column * boxWidth, 0,column * boxWidth, getHeight()); - } + // Repaint the grid and all elements (fire and firefighter) + public void repaint() { + if (board == null) return; // Exit if board is not set + GraphicsContext gc = getGraphicsContext2D(); + gc.clearRect(0, 0, getWidth(), getHeight()); // Clear the canvas before drawing + + // Iterate over the list of updated elements (positions and elements like fire or firefighter) + for (Pair<Position, ModelElement> pair : board.getUpdatedElements()) { + Position position = pair.getKey(); // Get the Position from the Pair + ModelElement element = pair.getValue(); // Get the ModelElement (either FIRE or FIREFIGHTER) + + // Set the color based on the element type + if (element == ModelElement.FIRE) { + gc.setFill(Color.RED); // Fire is red + } else if (element == ModelElement.FIREFIGHTER) { + gc.setFill(Color.BLUE); // Firefighter is blue + } else { + gc.setFill(Color.WHITE); // Empty space is white + } - private void paintHorizontalLines() { - for(int row = 0; row < rowCount; row++) - getGraphicsContext2D().strokeLine(0, row * boxHeight, getWidth(), row * boxHeight); - } + // Draw the element on the grid at the appropriate position + gc.fillRect(position.getCol() * boxWidth, position.getRow() * boxHeight, boxWidth, boxHeight); + gc.setStroke(Color.LIGHTGRAY); // Grid border color + gc.strokeRect(position.getCol() * boxWidth, position.getRow() * boxHeight, boxWidth, boxHeight); + } - private void paintBox(int row, int column, Color color){ - getGraphicsContext2D().setFill(color); - getGraphicsContext2D().fillRect(column * boxWidth,row * boxHeight, boxWidth, boxHeight); + // Optionally, draw the grid lines on top of the elements + drawGridLines(gc); } - private void clearBox(int row, int column){ - getGraphicsContext2D().clearRect(column * boxWidth,row * boxHeight, boxWidth, boxHeight); + // Helper method to draw the grid lines + private void drawGridLines(GraphicsContext gc) { + gc.setStroke(Color.GRAY); + for (int col = 0; col < columns; col++) { + gc.strokeLine(col * boxWidth, 0, col * boxWidth, getHeight()); // Vertical lines + } + for (int row = 0; row < rows; row++) { + gc.strokeLine(0, row * boxHeight, getWidth(), row * boxHeight); // Horizontal lines + } } -} \ No newline at end of file +} diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java index ffb76112e1af543df5af41fa906082ef11be9967..f0a7922c36e72b5c7419e01f27d5845f770e9b9e 100644 --- a/src/main/java/view/ViewElement.java +++ b/src/main/java/view/ViewElement.java @@ -4,7 +4,9 @@ import javafx.scene.paint.Color; public enum ViewElement { FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + final Color color; + ViewElement(Color color) { this.color = color; }