From 6b3845a489281d1fdbbe962fd05464fad6dae8e1 Mon Sep 17 00:00:00 2001 From: badrr <badr.radellah@etu.univ-amu.fr> Date: Fri, 29 Nov 2024 09:47:04 +0100 Subject: [PATCH] final project --- .../executionHistory/executionHistory.bin | Bin 0 -> 35642 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .gradle/8.10.2/fileHashes/fileHashes.bin | Bin 0 -> 22647 bytes .gradle/8.10.2/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../8.10.2/fileHashes/resourceHashesCache.bin | Bin 0 -> 20129 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .gradle/buildOutputCleanup/outputFiles.bin | Bin 0 -> 18893 bytes .gradle/file-system.probe | Bin 0 -> 8 bytes .../java/main/app/SimulatorApplication.class | Bin 0 -> 3284 bytes .../classes/java/main/app/SimulatorMain.class | Bin 0 -> 438 bytes .../java/main/controller/Controller.class | Bin 0 -> 7536 bytes .../controller/PersistentToggleGroup.class | Bin 0 -> 2668 bytes build/classes/java/main/model/Board.class | Bin 0 -> 553 bytes build/classes/java/main/model/Cloud.class | Bin 0 -> 1267 bytes build/classes/java/main/model/Fire.class | Bin 0 -> 1252 bytes .../classes/java/main/model/Firefighter.class | Bin 0 -> 442 bytes .../java/main/model/ModelElement.class | Bin 0 -> 1243 bytes .../main/model/MotorizedFirefighter.class | Bin 0 -> 478 bytes build/classes/java/main/module-info.class | Bin 0 -> 337 bytes build/classes/java/main/util/Position.class | Bin 0 -> 1399 bytes .../java/main/view/FirefighterGrid.class | Bin 0 -> 3994 bytes build/classes/java/main/view/Grid.class | Bin 0 -> 401 bytes .../classes/java/main/view/ViewElement.class | Bin 0 -> 1622 bytes build/resources/main/view/DarkTheme.css | 142 +++++++++++++++++ build/resources/main/view/view.fxml | 40 +++++ .../compileJava/previous-compilation-data.bin | Bin 0 -> 22159 bytes src/main/java/app/SimulatorApplication.java | 15 +- src/main/java/controller/Controller.java | 37 +++-- src/main/java/model/Board.java | 101 ++++++------ src/main/java/model/BoardUpdater.java | 26 ++++ src/main/java/model/Cloud.java | 50 ++---- src/main/java/model/CloudUpdater.java | 36 +++++ src/main/java/model/Elements.java | 11 ++ src/main/java/model/Fire.java | 41 +++-- src/main/java/model/FireExtinguisher.java | 32 ++++ .../java/model/FireExtinguisherUpdater.java | 42 +++++ src/main/java/model/FireUpdater.java | 36 +++++ src/main/java/model/Firefighter.java | 62 +------- src/main/java/model/FirefighterBoard.java | 147 ------------------ src/main/java/model/FirefighterUpdater.java | 36 +++++ src/main/java/model/FirefightingBoard.java | 111 +++++++++++++ src/main/java/model/ModelElement.java | 2 +- src/main/java/model/MotorizedFirefighter.java | 38 +---- .../model/MotorizedFirefighterUpdater.java | 36 +++++ src/main/java/model/Mountain.java | 31 ++++ src/main/java/model/Neighbors.java | 24 +++ .../java/model/RandomPositionsGenerator.java | 20 +++ src/main/java/model/Road.java | 31 ++++ src/main/java/model/State.java | 29 ++++ src/main/java/model/StateManager.java | 59 +++++++ src/main/java/model/Updater.java | 9 ++ src/main/java/util/Position.java | 44 +----- src/main/java/util/TargetStrategy.java | 53 ------- src/main/java/view/ViewElement.java | 3 +- 54 files changed, 890 insertions(+), 454 deletions(-) create mode 100644 .gradle/8.10.2/executionHistory/executionHistory.bin create mode 100644 .gradle/8.10.2/fileHashes/fileHashes.bin create mode 100644 .gradle/8.10.2/fileHashes/resourceHashesCache.bin create mode 100644 .gradle/buildOutputCleanup/outputFiles.bin create mode 100644 .gradle/file-system.probe create mode 100644 build/classes/java/main/app/SimulatorApplication.class create mode 100644 build/classes/java/main/app/SimulatorMain.class create mode 100644 build/classes/java/main/controller/Controller.class create mode 100644 build/classes/java/main/controller/PersistentToggleGroup.class create mode 100644 build/classes/java/main/model/Board.class create mode 100644 build/classes/java/main/model/Cloud.class create mode 100644 build/classes/java/main/model/Fire.class create mode 100644 build/classes/java/main/model/Firefighter.class create mode 100644 build/classes/java/main/model/ModelElement.class create mode 100644 build/classes/java/main/model/MotorizedFirefighter.class create mode 100644 build/classes/java/main/module-info.class create mode 100644 build/classes/java/main/util/Position.class create mode 100644 build/classes/java/main/view/FirefighterGrid.class create mode 100644 build/classes/java/main/view/Grid.class create mode 100644 build/classes/java/main/view/ViewElement.class create mode 100644 build/resources/main/view/DarkTheme.css create mode 100644 build/resources/main/view/view.fxml create mode 100644 build/tmp/compileJava/previous-compilation-data.bin create mode 100644 src/main/java/model/BoardUpdater.java create mode 100644 src/main/java/model/CloudUpdater.java create mode 100644 src/main/java/model/Elements.java create mode 100644 src/main/java/model/FireExtinguisher.java create mode 100644 src/main/java/model/FireExtinguisherUpdater.java create mode 100644 src/main/java/model/FireUpdater.java delete mode 100644 src/main/java/model/FirefighterBoard.java create mode 100644 src/main/java/model/FirefighterUpdater.java create mode 100644 src/main/java/model/FirefightingBoard.java create mode 100644 src/main/java/model/MotorizedFirefighterUpdater.java create mode 100644 src/main/java/model/Mountain.java create mode 100644 src/main/java/model/Neighbors.java create mode 100644 src/main/java/model/RandomPositionsGenerator.java create mode 100644 src/main/java/model/Road.java create mode 100644 src/main/java/model/State.java create mode 100644 src/main/java/model/StateManager.java create mode 100644 src/main/java/model/Updater.java delete mode 100644 src/main/java/util/TargetStrategy.java diff --git a/.gradle/8.10.2/executionHistory/executionHistory.bin b/.gradle/8.10.2/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..443d4d5ea93b32a3dc4d063767a912cdc82ed35f GIT binary patch literal 35642 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 Jml~?50|5H&*9!mu literal 0 HcmV?d00001 diff --git a/.gradle/8.10.2/executionHistory/executionHistory.lock b/.gradle/8.10.2/executionHistory/executionHistory.lock index 0480205df97bb90c7d52cd13b2dab59ff642a77a..d3b6d4e9e68aba47925719e91064028d23b2f565 100644 GIT binary patch literal 17 UcmZR+l_mROZDjon1_)3G060VhnE(I) literal 17 UcmZR+l_mROZDjon1_)39060Aak^lez diff --git a/.gradle/8.10.2/fileHashes/fileHashes.bin b/.gradle/8.10.2/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..a79d267978955d653818ac77d353056e20bc1fc1 GIT binary patch literal 22647 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 Ha2^BzLQ3t6 literal 0 HcmV?d00001 diff --git a/.gradle/8.10.2/fileHashes/fileHashes.lock b/.gradle/8.10.2/fileHashes/fileHashes.lock index e7c208981bc92398a6f20f01d067290243cc2f24..850c64af6de6967637cd111fe779c806fbfc8311 100644 GIT binary patch literal 17 VcmZR!SrmR}pBH-<0~j!-0RS%!1Qh@P literal 17 UcmZR!SrmR}pBH-<0|e{@054wzX8-^I diff --git a/.gradle/8.10.2/fileHashes/resourceHashesCache.bin b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..7c2f7414f6ad7716a4b6f4d622d56616f836fee9 GIT binary patch literal 20129 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 literal 0 HcmV?d00001 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 1ca5f492f53f2a0fb2ecc71ddac5072417c9f223..c3231602f858320fe10e544fc872e1bf439216b3 100644 GIT binary patch literal 17 UcmZRMh_{lPws>110|XoZ04e1JGXMYp literal 17 UcmZRMh_{lPws>110|d+l04cx(4gdfE diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..5e8b136f48d43e5a0ae1493dcf50928121d85224 GIT binary patch literal 18893 zcmZ=^V2}{_4+RVeAc|m)vPMH-Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zMnhmU1V%$(Gz3ONU^E0qLtr!nhD!*9GB7Z3K|CX&!vtdRmoqRJ@Gvkih)qA0KkeuY z0RfOG1A|8}bo$``n%8@7-G14w1Qq`Z6W`{QF2Er_PXsDH8z#Qj<8RItsiJuhanF@7 z@%^(*tn(R{XF$cZVdAG)<MzE5>4l1Wq{756q`6yf;&?p~s@@+ae$g}AqV{AH*!2ty zp0+UY%ds1$h2*aV`GtXj!Lt=6{!nn;v7;Y6A;vIxvctrm%&H8lI6K=2BH_6kCjQ=y zb%R9af|F43=`is>voz+_bO!W8#68Mk;(x0)-rjHdT?#7h2oq-r72no3)4&oU?kNcq z=azaTw031qDMZ|3KTKS1ZS3YpJnEeganE9yxKncc`l6q%SrBoL$1w4j$V1MRvh$8Y z#n-~blUNokk(g5bA0qCV2oo<l&9Q#pm+$fragU2I@sio)8|P{qh54%!CJv(+7?>0x zdPd375Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z t5Eu=C(GVC7fx#96#taM$oD2*Mj8M$Lhav(J9!w&j;G>Ou$TOL$x&VocFP;DZ literal 0 HcmV?d00001 diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe new file mode 100644 index 0000000000000000000000000000000000000000..dd8d8c71378bdebbd024af691eb99aedfb1b3956 GIT binary patch literal 8 PcmZQzV4PeoW_K9?23i6$ literal 0 HcmV?d00001 diff --git a/build/classes/java/main/app/SimulatorApplication.class b/build/classes/java/main/app/SimulatorApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..9f4ba80d3723bf3c3d2277cabddbdb2158b0e3b0 GIT binary patch literal 3284 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 GNCE&ua0)R1 literal 0 HcmV?d00001 diff --git a/build/classes/java/main/app/SimulatorMain.class b/build/classes/java/main/app/SimulatorMain.class new file mode 100644 index 0000000000000000000000000000000000000000..1314135817cf7f41f01f0fac00bb895810cda7b6 GIT binary patch literal 438 zcmX^0Z`VEs1_nn42`&aE24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk- z5<5l)W)00SE(Q(;PId+^9tLg(9!3U<#DW6-;LP08oWzp+BFBP)oXq6JlFa-(Mh2GL z#LPTK1~H9jAB35~B}JKe>DHQI><oO241y@SeZlHkobyvs85#I}GV@aXN^_G^i$W5U za#9%?gnaUo6LZ26i!wocs31#8MrJW1gRl>VN!E-EEQv+wAW19^U}WG5&Mz%WPIb!! zn+^8@$Ps!V_cACl@G>wlfB+K%BPehf7#a8(7#Q>!7#SED7#LW!wlgqpWME)mVh~_p zU|<6aGBXG=Ffj0d*{lpg48jZy44j~#f@(H~Yu>@Yj?fH>1O^6H1{MZ36az#UL>U+u L7#YOC)`$ZD2<=yo literal 0 HcmV?d00001 diff --git a/build/classes/java/main/controller/Controller.class b/build/classes/java/main/controller/Controller.class new file mode 100644 index 0000000000000000000000000000000000000000..ba9a9a72b88e5144c8d5c44921a83eae7d3a08f8 GIT binary patch literal 7536 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 E06^eG@c;k- literal 0 HcmV?d00001 diff --git a/build/classes/java/main/controller/PersistentToggleGroup.class b/build/classes/java/main/controller/PersistentToggleGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..c628d6aee41898dcc4426423e5c33466a8821e27 GIT binary patch literal 2668 zcmX^0Z`VEs1_nolIxYq#24;2!79Ivx1~x_pg{;J~#Iy?i;^fr4RQ=@qypp2)9Q}~| z^z@um_oDpL0!9Wlo6Nk-5<5l)W)00SE(Q(;PId+^9tLg(9!3TQsE(Y}BK?5WqT<Zr zlGMBs6zyE;sZfDpMg~<4O&_R@$@w`ssmUdo`FX|q{z=8DMP-ReIjKIG#U<843=9l> zJPiB{0*nlt`FYM6iFxU%DU1x>8a{;Vv&L#Z$W(|aAXaK#YLPWJgAju-JA()hgD8U- zBZDGAS1~ehC#Iyp^fNMOX<+jSNFL25P@qXLNU}3X@i0g;$S^YKV6h8Rp9;hnMh2F= z)QS>t=tpreNHECpFvv3~Ff#C`r<ORTq@<<<mnMO9GcpK416RMaBr``JBxcRcpv0ie z&Y;4>pvs`e$iN4(86nNcz>!&!T9jClU&P2DhN9aODsIiqpuwQY&Y;D^pbc`n5W)nQ z5=I90jKpHU)QS?2T3wJQ^%xmMV8-Pn=B4ZVCuOB3msqni7%(zOgN(qD<k%UE5OIMm zO*)m9l;r1eGMF%!vNM?RFqkt~Ffz!Zn3$PYP+Fqzn_pU->ROhXSHj4^=j$ID>>3~B z>f`Dd?CQeEAOVZIRFDFFu(FWKf>diE21W)e9tLX$8%74UjKsW@oK!}JBqEX>%s||3 zMx;z6OFh6=6j^gI7&6%LFxWFVFf#BZrlf#f<d&IJl3K*bU<OZVNIJpJh1rTE4l@yy z>Npsjco>`+To@Sy(^E@=Q$hJHH3gD885!iEF@z&3thpH67~I(zJa`y98N3)71VDkT zj})7X3~Z@|rHMJkj0~a>7b44AYesP~m@xS8F!+MX8TRD-yyDW_R7M6C=lqmZMh1SL z%)C^;(%hufq7YEVXJioa$xlwq2}>->1o5GQEF~G4#f%I}gfl)P15Zw3Zc<93N?vNY ziXkI|A;eK>75d0U4Jcbcau$dMDhi+(%~~^zk%6ZKT=GFu86$%-EP(MuD<cCNL=z)} zEI#Gdj0|ka;F64yK@X;oIF~Up@CKJ8CTII57C?gq*{cSO46bmm;&CX<PKXlpTmtq! zS1wYnktd*mk%22XzqBYh)h!d0OQf)t|9YTQ!^j}ul%HQxTvC)+;G0^Kk)Kj5z!1XE z%8&}GPSSW7f*C>t7%~_c#NqxxO3~JuVf?HNSs<m^JPa`mu>uUaj0{R}r8xb=&&H6? z#ZbUd$j(s2!%)mn!pNWmat<V!X6BXUXQ%4>fYXd`YDr>RVsc4-Q6(b-cP=vT48$T7 zO%P8&vRbi<Pkw%OX@NC3xFE`cONuh{(vd}=wm~!^@-9R<@sbcL@f!@O0Z~kLPRz*( z&MZl_W@O;;%*#tHa?VLCE>10GXDDZ6Pz8kv!Cb<~zy`@S><m><Jt$T{d<JnJEJ)ZH zY8V;hK*r-%%E-V52|oq}1`Y-$1`uFoU;wpF7#JD+7#JAb7?>Cs85kHuw6-%aYHed+ z*V@Iv%fPUcL6C`IBLf2i6N5jfy}$s{CCtFWAi^NbpuiBoz`(!*(Z>+T5X8VBzywNW zP%}3$urRQK8bsRL7{q5X*l2HKklo3k$jIQUvy(xckzpo-n$AuJ9Y%%&4Elb$2N(>k zSR`3CF&Jw}vg~58WMJ6FV7vVP_2vH$gB-vNc7PNE8v_G_C<8l#7=sFfID;001cMcW zEQ14sJlHW>3@i*<3<3<H3}Fl`3@Qv_4B-qBU`IPb90+m_LnK2K10zE;0|Nsu0}I0+ z1_5>kjb9AfOae@xln-@%Jg5!Fz`!7&t+kE8aT|l{Oa^wHZ4BNB$MAs-mSo^&kYeCx zkO4bD0W2l}w+!MGP{;}}#4&)(1X;_>z{t<Q%#Z*M*hGdT1_lN(1}26)24;q2h7^Wm jFe{xQlOczpl!1Xkh=GYgf}xC|f`yZzlA)TRmO&B#^*r(k literal 0 HcmV?d00001 diff --git a/build/classes/java/main/model/Board.class b/build/classes/java/main/model/Board.class new file mode 100644 index 0000000000000000000000000000000000000000..ecd1336b457fb2c6c77d72d175d53e4bae454df9 GIT binary patch literal 553 zcmX^0Z`VEs1_nn4DRu@XMh5QO{FKxjeW(1yq7-%p7Dfhvti-ZJ{hY+SbbbG%tkmQZ zMh1?e{Bq~~(!3Hz24)RSPeumr<ouk{+&rildvR(>a7k(bBLj<ur)C%<18Y%gaVkV{ z7$XB$aY<@{UukYqY7rv?UwUeZTV_#eT4s7i2}nRnL(>Q11dy<6MM-8}dTC~HMrx5Y zBLhczYKe1BerXCLgAiPuYffrzYF<gPH6sIOaAta5Vo7OHDkFm_h5{QOuvbb;GIR8O zGK))We89|r{Nl`#%=|oSJ8L^@Mh14Mix?S9@R|^uio*c$^wbjH{F3~l%&OEBkSE}N z0~sBZpP0hPzztSYnpcvTna9Y$6`WsMl$`38nUl)Mzy%I^J&;q`7#SEDm>EETn}v~q zm4S@`6eH|VnuCE8%;#d@2GcxHab5;KFrS}6fPs-gkb!}Li9v{kkwF-VFT%peAPQ9{ Th9nMBCyvZ#U}TU0n;;1Q#2SI? literal 0 HcmV?d00001 diff --git a/build/classes/java/main/model/Cloud.class b/build/classes/java/main/model/Cloud.class new file mode 100644 index 0000000000000000000000000000000000000000..8dcbc37aed2db074546809869075deef1c561b29 GIT binary patch literal 1267 zcmX^0Z`VEs1_nn46D|fO24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk- z5<5l)W)00SP6iGJPId+^9tLg(9!3W4-29Z(9DV1U{L&Og20@U*%)}fp*Ezp5uY{3- z(UYBlkC8zbY;I{uW{$pNQBh*0PiAom7XvQ?Gsr+e9tI%>VMYeNWRN)l`Nf$fnfZCe zj0^%k2yGx8*6a+Tj0}9Jf?Nz74B|Wt5)6`z3_QiDB}n>(HP8*v3<D{b=3$UwkY!}x zNk>sGq@jtfo}EFSk%155OV^y#+|<01Vnzne;LP;A#FEmYR7M6xG%YqhU|+&qVQpv4 z$iSlEsTsz|z~Y>rlFG=y?~|FA>Q|bZlv)&$n3R*s$ROmCpPZNzmROVt;zI>lN-{Ew z85wweAhv@8)tZq(8N-p-Y~(CJgrXR#>6HbkP#aXxg9p<jkhA&IQ%gMaGD|=)3yD-_ z4NXr*22rSXq|{;!QZL|}T9T2U5|CJwn44OXT2#!)AOdqVvRXz4S4h|)3qpMh3u_yQ z3UH8uQUIn4LE+04oL^d$oa&Yd3QR6=Na=wR34<a72LlrWBZC|R69W?{kufkbC@?TE zFfk}H2!WC?0|Nsa10w?~gAxNHgE9jHLns3?0}}%SgQ(Va21YIEtqkm1yBT;Rw=?i> zWf0g1)~dq5z#zoH!oa}5&A`II!@$YF%OJwQ$Dqo<z#s<E%%H}g&Hw_UU`rSo7(oe+ zfeCDdJ_Cr)z`&}tg+X8g+(?i+Kn8=1;bCB8U|?W{8Ut~$1_L7~kwXm$0Q-o6flW&r z>M&*oki$UvnSnu^ft5i5$w6#TlR&=JWDsUxWYA(@V1U@d#-Pcd2oD!+21W)Q23=@q zAUl<P4VqJBz!pFZfjU*dkwJn%59&l?s1rH0v=1<dY-12Z1Run&97qOmLS3j2@;4&` kg8+koBZCZs0fs}iF-W0@8L~N0hcGZf<JpkG2<&WQ0Lb6;T>t<8 literal 0 HcmV?d00001 diff --git a/build/classes/java/main/model/Fire.class b/build/classes/java/main/model/Fire.class new file mode 100644 index 0000000000000000000000000000000000000000..465cb4df67a517d056d1ade6cb49281769807781 GIT binary patch literal 1252 zcmX^0Z`VEs1_nn46D|fO24;2!79Ivx1~x_pfvm)`ME#t^ymWp4q^#8B5=I6#o6Nk- z5<5l)W)00SP6iGJPId+^9tLg(9!3VP-29Z(9DTRUqEto(0g$@P#2gUMIlnZogpq;K zlbwN&kwFk_YH3Mkj=o1?aYk@z2^Rw|12f1lK^_Jn24O}9-n7i3)PVfr%#zIfykbTM zejkLM;M5Xpb_P*K23`~~E(Q(;aUKQ<21!N+p5oLJB;7(9XxcTyK&qvA7-Se^85wxe zQB(_RXrd`+XOL%P;DdP1H77MUHLs+Yk%2QfGd(Y{q!i>?1ymh2K49O$oM3Hd&B(x_ z;i(zM$iU*9pOOmlP-b4LUukYqYEejHQcfx(gOE>ta$-(cVo@fD4;5r7$;d2bWZ?0E zSPlwHYeohobQfZ?kFx*~d}63(R~Do~%~wVX8BBvfZst!<E%D6DEXhpFfyN}WhNdSY zgD6xtQUb9CsTc4~Ey>7F2}mqT%uOvxEh=VY5P>-vSuG=j3nbi-1)*Mrg|iJr1vor| zQ%f)%2nt)S;QZ2}<W#pzP(X5mLP-ylHW(BcI2f217#ZXkm>7gWX_SEh%o1i`WKaOJ z6&ctV7#Ua@lo%Kplo=QpLK&DDm>3usM76dvFltF}WnkCZ&A=PEoq>NVgTO|x78M2t z1|bF(1_lOR1{MZB22KWk1`!4U22}<I1~G_c1~mqC1`rShTgu452uf)TOkgYY89;mn z23D;t3<4YAMuObIz#sxPhKGTXfq{V)Y7E4s8Vrn}#0@nhfPo2Y6`Phe)M3mFAcui6 zFav`$11p0J*d&O9*q|mcFt9ObGJt%q#lXM-u>~Ze2oDc!21W)Q23=@qAUl<P4VqIG zz!pFZfjU*dkwJn%59&l?s1rH0v=1<dY-12Z1Run&97qOmLS3j2@;4&`g8+koBZCZs c0fs}iF-W0@8L~N0hcGZf<JXYE2<&WQ07_r&!~g&Q literal 0 HcmV?d00001 diff --git a/build/classes/java/main/model/Firefighter.class b/build/classes/java/main/model/Firefighter.class new file mode 100644 index 0000000000000000000000000000000000000000..fb5822010569277b91e906a7bb675ac35da745a5 GIT binary patch literal 442 zcmX^0Z`VEs1_nn4F)jus24;2!79Ivx1~x_pvE2NW)Es@c%%W7+ijvH{^wP}YjMO4V z1~!|_yv!0iMg|rQPt7oP1`b9BL4?}0%=C<s)FO5UE=C4Eh_Gu;YHn&?Niib>i*tTT zDkB5GPi9`KUukYqYEejHQcfx(gOE>ta$-(cVo@fD4;5r7$;d2bWDxd&7z1(%)O2e` z262!hG81!<M4j_X^GX;Q7(E#oID<3O^Abx+i&7aGypi-H`@|Y54s)K3PgY`CqJC*f zW{$p3W^sv)511K{Uz}NznV)BEXKiQA$iNkxUs{x$>Xr#|wg8gtdLZ2liVW-wObm<+ zoD2*Mj0}vRpk!cV;AUW8uw!6iU}9ikVAGP`&cL{lfq{XEfro*C0Tk>E44e$C3|tJn j3=9ln5LFC(4Ezirz{ViJAjrVTz{DT~)+5Xy0;WX)xCLtX literal 0 HcmV?d00001 diff --git a/build/classes/java/main/model/ModelElement.class b/build/classes/java/main/model/ModelElement.class new file mode 100644 index 0000000000000000000000000000000000000000..766931b7d86443a91ddc6cc4e96f592b3cc53abe GIT binary patch literal 1243 zcmX^0Z`VEs1_nn4XLbfAMh2nW{FKxjeP0minv<HFnpeWfz{tSD!@$bG#>l|!<{9Mb z=IQPc;u^%rAmW3m+8U&sgNK0=q?`q$93;Ta!@vU)V0HHK4|M^F@bNJ4gG5Ap{X_hN zJfmD)Kx&~zgA@qzFbIJZaQOO%`h_@p`hf&Rco;-Mf-FJ)j$mWNc^D)ZBpDglRl*#7 zLS2Iy8APM8xr&QHnn8x0L6V0-mO+k@fi*cNKQEP$K}18-Co8cmQ9ma!FJ0e1DJwO( z#F~pifkBa-L5YV!nL&k-fe)d;HLo<6k%7G|F{d=uKaG*WR0B!3b53G$u{DxFa7j^S zUb;214Il%+=Bx2As559VGO*cX=4F=HF*1lD8wJ(rsTsz>z{<tI$e_l-z{$bD!@<DM z!63xJAPN#Q<Y6#kFa~)Y?4Dvq25}8dte$6NV1p@Pan4UkWn|#@$;?ajE6q(xEec6Y z%1LEp(7<B9Cbp1dWDxSnPfpAUODxI+X@%-%$xF;l1<4^o3+f9-1_9sHl8pS6fW)H2 z+|-iPqGCn{mXeIjVnzne;LP;A#FEmYR7M774b3n{1`eC#9B7cJA%!I<;B2rt$IhCO zfh#z_v?w{%EfeGsLFBZn2Xc*rAp;|W0s{jByMrVs88a|ANP^NQnC4+%1JnFaS_n#u zf@lFLQ0ih}U|?n7WH4bcW?*D6Wnf@XVqjzd0j^C9V%r#`4lqb>U|?WiWH4i3U|<8w zF*9&7C^MKdFoD&ZFff5dxr7+Cb}+~vU|<BPXF^eL!N9=415w3b$za96z+ersmyv;? zfq{Vulvo&;!G;+!Ff%ZNJfo#8vz<Y8BLhep*=B@E><l&_Uw}>GWMW_tU;txVuogQ3 zE>QY`ddZ1_1>_?JEdjQ@42+S?n;4jbBUv^vum?x7ZerjHj%3@!z#AONzKKB~IFe%% zgK#j&3#eY^V6bPfgPK<eH7|5G17oC+Ci8X%t<4O~V2(Bmn8Oa{=&*u0Twsna8<@ij y=IF75IRapgJ_nd1yo14DGlLk&&k(D*7?>Cs7+4tm7?>HD7$6>VU~mL`&<Oye=<Zhl literal 0 HcmV?d00001 diff --git a/build/classes/java/main/model/MotorizedFirefighter.class b/build/classes/java/main/model/MotorizedFirefighter.class new file mode 100644 index 0000000000000000000000000000000000000000..30f0a1cb84767e5c05ec92af2d604bd5e617071b GIT binary patch literal 478 zcmX^0Z`VEs1_nn4F)jus24;2!79Ivx1~x_pvE2NW)Es@c%%W7+ijvH{^wP}YjMO4V z1~!|_yv!0iMg|rQPt7oP1`b9BDTrF%{F3~l%&OEBkfyZE^o)|!B6bEYMg~5JylYNs zZfaghF(U(ubAC!HBLlxrW?rgaX>L+#QAlD^PAVgVkWYScVoq3MQ6`8F6=W&N$Sh`L zknw>SgUuRiMg|3tvoaHNut_`Tm*$l)GBA2FGH?cGrspM=loq8jGI&Ex1i2U4lh#mi zn1gM6vJ%S@^-D`KbM$>Oi%V>Lz|4UB;>?oF{5)$rYddR32Cm@z(xT*4w@i>nB(XU| z4`d93A_F@E69XdyCj$cmBLgESxEUB3xEUB2>=>9Bm>3us*tDd#GcaysU|?Wk;9+23 v07VT011AG30~Z4?0|SE?L=^)c13v=@urUZQ2r@7-Ffj;$^$0VFfN4<xVDWko literal 0 HcmV?d00001 diff --git a/build/classes/java/main/module-info.class b/build/classes/java/main/module-info.class new file mode 100644 index 0000000000000000000000000000000000000000..81adf2cbd56ceb6466f120bc7c89d7b59cfb2e9c GIT binary patch literal 337 zcmX^0Z`VEs1_nn4Np=P%Mh5QO{FKt1RNc(Hw0uSeuHgLAqU2P!%$!t41_2}~y{yEt zL`DWSU$AOn26jdU?zGIJ)U?d>jFQwMVFpe{22PL~y`;qAR7M6iBSSp{JyT%@9!3U! zka${!UUGh3Nl|`IF(U($k)bdHKO+M-R3@z=H%FL35TP`^D6t?TGr3rVL70(&IkBKX zgh7;%feUIvPHGV&gJ5DofqrmiZfQ<pNq&)UVrCvYgBT+NKg5L~zH?4uad86!10w?r zFf%YSFfcGNurRPPFfiCLuz@957&saj7`Pa?85kIN8Ti1Y0GMQC5CW@UVh~{fnZpO> OGlJDHFi3#S5(faiazv#7 literal 0 HcmV?d00001 diff --git a/build/classes/java/main/util/Position.class b/build/classes/java/main/util/Position.class new file mode 100644 index 0000000000000000000000000000000000000000..66d847d3166c32ee8297dd7615040ae908de271d GIT binary patch literal 1399 zcmX^0Z`VEs1_nn4TP_AB24;2!79Ivx1~x_pfvm)`ME#t^ymbAb)a3l46h;O%o6Nk- z5<5l)W)00SP6iGJPId+^9tLg(9!3V<(vr*^{eb-9%#zIfJVplQqWp4321ZYiGCm## zevlfr<ouk{+&m!$1_nVM1|bGvMh1?O{NR$J%)E3)24xK&6f>+feGpE7D6$4=73E<N zV-RO#;K)cU&T!68No8aZ!qDmoQYp#9AjKff$iS9bSelqq%*ddEt`5lt|D>$c<PvMm zC`JZW4Np(aFh&Lzi0S-3nR%&xrMXF|MInhvIUxId@{<#D!V-%zL42qnOG!p%F(U&% znlBg`1bkCVGV)Ub5{nXZQ%h2diWwP1G_ZIM9Il>>45Av?oyC~X$RLC%#mK-FoL^d$ zoa&YdavLu!4)j2w$H>42i#-9S{QQ#QlA^={h<l1T7<3sKxQg=2ts(Kk&&a^e&&a^b z&&FWL#bCr>%+6rK!(hr_#>gNKG7FLzic0fJGILY)A>jozijjdc31&JY!$xEeWagFS zXQ%2z6nZ4)rR1a*tN7&SXO|XOBY6fI!AK%djUkl<sV=F-$wiq3CHY0jTAXtdi;Iy3 zpk_p48iH&)O1gsh!kUqR$1^W4wFqovYB4*5B_o3>!p~5rAe#d713QB?BZC}%rHl-0 z5DzmLGH@_3F)%PNF$jUO4Fdy%5GZRfFfgz&Ffy<*$S^Q5$TBc6_=55x0|NuU)^-L) zE$OWc>{>Eg8F)8>waP)2GcYhS$TKi7C@?UClrktVC^CQmKiFtSuoyoB4+9f}5(5JR zCldoVScri^kU@w+nSl{(lOY2m14t>m)-DDC28In-ZQy|@f!ZL*AjY7AMY{+C!y2Nr zOEIWIwc9W-fy0ACOM4fC1TOtz5H(Qi85lSi)ELyk?&gL&L?6s&U|`kS!oZHt8LUua z7#aAnYUU+IGYf+T*r%EdS_}*fd<>wl<pGB-h|~s)F)|o1urP2i=rHIp=rfozFfed2 OFfv#$STWczNCE(*?HMir literal 0 HcmV?d00001 diff --git a/build/classes/java/main/view/FirefighterGrid.class b/build/classes/java/main/view/FirefighterGrid.class new file mode 100644 index 0000000000000000000000000000000000000000..f6de666959a2628b436cb1c723bb16b559cf622b GIT binary patch literal 3994 zcmX^0Z`VEs1_nolrCbb549x5dEIbUX3~Y=HQdx;*iD?!3#mT98srt!@d1Z;k`p#gA zk%7%7GcU8mj*)>`Lo<wvfrEjQoq>yoft!Jck%70gBr``pAip@XBr`vck%74=zZ|U4 z6Qq!jhk+lYiY+-mr!+T@lR=O{h@C;0he3ovl#xN8EHkxSKP)q~+%+dPH#M(>k%2Wi zKPSJ4kwMA_#X$v$nRzAp&LBB!E(UQ133dia9tJ4}X+{PSupw@lMX70-=@})dMeaqJ zDU1vpU@cDh6^sn>8lIlGjRW~eoI#d{L5@KlWPeU-Vi6;Qum)I%KG=6YnZ+g65Os<? z3`$^iVB<kfQQ=`w1%)6NSi~nYFSVGPL7hQ^ok5d_L5o3~k%1576@*EQ3>=vysYQt; zAb*N!Xd+qU2^F{IX3%BOV`tFkVK87YWMmLRm;h74$iSYFSnQWtQ34L_D3A_g9tINz zQ$_}sJg~3`%<P=RymWp4q^#8B5^Ht_b4CUMka=kp5H|%RW)^WVm@!!LFj#?fv!$n& zc&Ao^{AR<$V9Q{~$iR^d3Kei*vTAsGf`Y<~!GVXt5u~0YJ+&k(F{d;Yq{Eqq!G*z< zkwFX`8qjEUEJ36X6%8M7gdxScwGTLyVQQcu?GB0&HjtT~pfLAhWDwVgj>gmsa*Q~G z4-bPcgC8S<NP23Cdr@LRMrLxcbADb)YDI~W3nPO%G$_zhIGR#$+6v%d2xJIiWB~aq zJTs*v1029EAeV&jFoc4nIMY*0JW@f)jf)|iA%dMDl7}IRA)1jv85*!C*$B-NMg~rB za0aC&moPH0Yq+?$xM+rPGKe$8@-W0P#4|E*Lvo9AekmwRFnWUI5_uSsKyn;K`Q=~< zQ1(gz<z73GbQ%vsI#@a>zXI%NkYFYcLl#JoGbz6U=3FL*93F;ThCD_Fj^fl3uu?__ z77Z6rFfuU|@GumD<T#5F9u#LN=3yuSC2<jOq<Z8RWme_ql_chX6FVqe%6J&cK?;Px z3c^y0N-~q-(%}r1JPcK!(BUdBDay}I1!)6?TMZ9GEkhk61AB35iCbn)4kLpsB-g=X z32dBx04Vc=Q$;vK0}n$Z$S97q%$yuh2(mLYGct%^OBf)Bwem2uF?caDuotC*&0=Th zU}WF~CqPIs!Qz~slFG=y4|0=VX>L+#QAlD^PAVgVkWYScVoq3MQ6`8F6=W&N$Sh`L z5QC&bv@*w<k%2uGR*nfllpv>aP?-cTCi&6QJR^fp0aP+I1)6P&85snS3I}j01hO2( zVU-1`P{+BWskH&~k#o5Xnx&X-w6nIeW@O+D&P>lsEGaEYWn}PzL<yv*06BqNV>QDV z8Tes-g!&K^%+MSIDFPBRi>w(LOv!RNBLi=6Nn&!gZ(;#7L|6(EGm97*IH0jo%*eo7 zoLb_NnVXtdoSC0j49b0;o}ls!TDXARqK{l!f*dX2n_7~QpAwK*l$e`Zl3G;E$Y2d~ zAWA-mRF~F}Pz5C~8we9Q5rBf1D>%QjC^^+F6O_(G&{B~e$PEmN4B`w-42%rz3@i*x zpq$OXz`z8`%wRf>As$R8foVYoMo=Bjz{t?az`&r-z{tSJz`($&wVi=+BUo7%0|Nsa zSdfdMn}LCW2h3(==wavu%eyeRLNy07urM$)Ffa&e>1<<Q*V)FvtG$ImU>k!N!XQw) zfq{XSL4bh|Y?uN>1Jp1E20?~ChJLUGf(#QFCW3v@#vsqY1a@5_0}}%i0|NuUmi9IV z84#hMwT(d;WIQti$eltAEDQ_`VhpSd;tX625)6C{l3;7ZAll&8@H0$en9RV)Fa_=( zkjPX9Muur%KTT&~0#)cxYj-g)Gq5r+FqmrZWKd&d@YUJLpu@;8lR;f)Cxa0q!vO{} zKizE%76%wOtXQ-pS++5-g9zSj4A#s4UjsRg1?)JGvltj;7^E0v8I&317z`QY8B7=y zzz)=6U|~>Z-~;=ag+YozoM8sTOmNtk!X0gj<Y<tGAgX3TRZU_5Ie#_-0|Pe$(;o(Q zb_U&F3_3{uQGy5Kat3B_I2oY%M+xB{E!}Ml_6HaQq5j&&;I#bzZG=}K;jGLc#h}8V z!=TEb&!7hO1}HkE7=#$+Kpk%Ycf0|H<3Xw*jt9wMalAU*@r<Bi7@ElZplN_lYa4?b zC<%DLk^mDplp#(7g{L+HCxZ?HFM}@FX`m2eVBmv0h>u||Lo)*-IHEzx8<hGT7&yUc zPe^MUgEt?@27j$>48hwN!a!b!m=8(81`L7>hG26c*+B?uE)#<igBR4LOBvX}!EDTI zE2FiAA!ZSSHnW|q))t0@MGVqf+OkG6M!Oj}B4uT^GbC?gaB5*@T>k%Y3lrn=|Cd45 zK~l670~-Sag9!r{gDHaugBgPwgDHa!g9(EXg9X@nkVknK6d1S};u)A3m>3Kg_!;8C zsofarBnAd!s8>OWLx6$h4+9h99|lgwUkviU7+4t?8REcs8WaGC?7xK}W(_zifU*@R zd>9z4!4^XN%L+A|ks%4I<^*)j_E<H~W0(&OtclP(rmiKsl_6D2lw~VJhL-eJh8QiG ztqciTveFst+ZnR8L|J4&jC@c4LE=M>ft`VY!G(d9!IgoV!Hq$H!JR>r!Gl4T!IMFa z!3%7y2{`+zL*2~4pbly%fn!=7)GPuAmpZtd1QlQE;F1zla;kz0K2X3|L(4@@t!)fN zTH6>(5f0!3XFy*D76v~C4hDa)g^)nvgj&c1YTiKoS;fE!woaSbMjDbRltGCN#7@m< z=Y!IaR9Df$$Oz4Lki-B<+d&Lm48aU43_%Q93?X3aKxvzaK?5B1pwe3#YB4CnIYFfX z6XP!ibp|F-I}E!!5*9Il-2rw$Mn=2VHU@u?TQV}*w=v*wM>qo)Lj;2gLpXyLLnMkj zK#38rJERz-q3)<)-~?w94NxfPZeyqh(V*;-n$Zq*fYug<)OM{c3?Qe}qlbG80|!Ga zI6^^n6DT(@Fla!%4`RWb0tp;Y<)H!UJ%aO!ErT7@6-f-7;8+AzC*HVi$0!C88RQv~ zz+MNHd<+Z<aGN1H5)=pu;AmkIaAas>SOBe2jG=`Xr<V2shNf){EeLNx@)~kg3rj`| XLG>~t1A_plGKbVtix?JzGwBilr4>4| literal 0 HcmV?d00001 diff --git a/build/classes/java/main/view/Grid.class b/build/classes/java/main/view/Grid.class new file mode 100644 index 0000000000000000000000000000000000000000..b0148f831a19ab0bf46bfcb627f8a2be7b5470d8 GIT binary patch literal 401 zcmX^0Z`VEs1_nn4VRi;4Mh4EZ%+zvy_oB=cb_Nzk27#=^vPAuy#JqHU|D>$c<Pt^( z_M+5+#LT=BMh0OGAFy<3NoJ0|PiAq6wPqM217~n%dR}5lX;CU8gEhJe8?cVF3VpDi zfW*uq8y^TWzc{lbGe6Hd#MRo)+74`zxJGm|SUs`>z%m>f(a|BUU?y*IYKco`Zfag} zW`15VBLlmJr>CbU$RXUx`8lPzdCvKzAjdLmXnHa-a1`a2Lj^Q!T&*xox5E@-WZ(+U zFD*(=b<502Wn|z41&$ub<7|u!j10^SAi&DP$iT|L#=ywH&cMLH#J~aObHe#tEQ}1? b3_J{=Fy&?71JnE<nt=(bLx4dLtWyX8PlaF^ literal 0 HcmV?d00001 diff --git a/build/classes/java/main/view/ViewElement.class b/build/classes/java/main/view/ViewElement.class new file mode 100644 index 0000000000000000000000000000000000000000..c1d3219fb1703274bf77fb3fedd0509e3bf4a3f9 GIT binary patch literal 1622 zcmX^0Z`VEs1_nolRCWd?Mh1bh%+zxIu*}qQ*PPVc)VvZ-21W)J9tKthHbw?+H_sqf zH&1tu5Z53^1|c7GwbmfT96Su1AjK>o#UKH09tIwe0IRESKu9D=gpY@TA1vbR;~(k* z5)tHK5CVya`1*(V2YE)hx`1>;tpX_!;b9O3DPRfmcLeJY=V6cl32^xOhx&y$disG> zN%1g9GsrM9u&abQ`h>a$GcpKAW4e-yL5@M5ok50&L4iS$k%2WiCqFNhkwHX5(<dvj zEKxrvF)v-;KPf9Uxx|`_L772?ok5j{L5)G3k%14Pz%{Qlmyv<JEHS4v)jy4q!BhiD zw{uQnaj`X$KyXP>W?s5AvJD^uz~*c6FlaGoGcvH*Waed-*fBDQAsYqN>8Tk8@}Vvd zgC2uE$kF*Z`9+KjQeZpMD)ft!Q}a^w3lcN)O7xvUa@HIStegx+494sXCOizLAWae= z*JD%5$iU*{6Y9#vz{p?@a*PEdg8?=-;I>RNjDvv_WSun+gAK?o<{(!W4h9~OkUbBB z14xK9+`}`(m4ksFB<Re;-~tk4aSw8g<X{j2iMjJIc!0$m14A7-7(_v0-aHIGATd@a zA4g|z4h9L3pg#{o07NjzKim)G>>wV7V1^J-%!4DOn2|wLLlaBfGcvHj6tFnwr=&76 z@cU%urTUfTCZ!gIBqrsgGBT)P@wz5vGGb&9^2tw5%n3^@$^>bI>SoDH%uNN!fdU(n zmY`9{$ROaGT9T2U5|CJwn44OXT2#!)z*3TtS<J}58JwA(msnC-l*-5;3$Y(tL|JQw zF*0!2B<Da=3bO`CKm{Bx5W7IB$_CT1cGipxT*3LJMaijdnIKOJAmwpAkW(ED85kLq z85kHi9V9{7oq@qY5|op{G!FwCnC6GlLQq;1N=txf1_4moWMB}G0_8#m1_o9JPKHp1 z5C%quFa`z&B?d+Y5a8OxAi0e}_5g$21_lNOMuu<(1_m~;92)~CgBn8w0~1)i2?G;Y zluL+FYX^hU0R~2pdL|V0kqitBJP=h3Q4G-x3=A<Kdl?xR8W<Ru7_=BH7?{C^c`z_D zuz(b6Y0GS9(9qJ|%Am860i*_GJs$%z$m0xb3|tJ{4BQMLW5pPlK<XJ{!CnJdqsO4n zzznv4mzjY<fB}LT7#QNf2E_|-fzlw<x1M0@7#Iu%*!MCpMlx?=U=EIC*~Gve9Lc(g zfh#zYZ4(1;a3uRC27%y6j!g{0!I1)Nn;67`L7qen6b^<2hD4~bQy5r5VaQOin}IP> z$bfkhgW+}tv&{_5V7?{GCI%}opB>D%W!=PJ2j+8u`HpOx7@WX-UNGO4eG`Klm@fe4 zdva`I@B;IN!F*qkll;H}VmlZDH#10r!VKa%E^zp;GZZqgF)%@cAc-Lv926-4!d*i7 literal 0 HcmV?d00001 diff --git a/build/resources/main/view/DarkTheme.css b/build/resources/main/view/DarkTheme.css new file mode 100644 index 0000000..46b78aa --- /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 0000000..336ffa3 --- /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/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..1ab43a3ea9ccf94372fb5664ca54f09cc38b32c7 GIT binary patch literal 22159 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�nphSvGRy~wyklfo45D{)GAsqT>OVW!q!va- z1{RQ?L0v+I6(AXqxoxZrt3ay1Ffy#+#My5JO)RJ*4^ylI>6yUHun9_U;bdfBS;skn zxu1CpGs8BJi=MMDWM#Mw8V&)qH$QN$U_HysumhxiAtOUSC^RQBGVBJa1ee`=K{B^l z81{i_R)+l`dJYrAJW#i8DeHIEsT`XaZ*y*8e8R@C0@O}C#{?dzIS5j>jhW#Xh(628 zaGaBofeTa@Jz}24x`%Zi=Sue5tZf`!%nT<$Zk)^kDQOr^b22ip{^hvEev@Sm(<*j` zWsvXzjfl)<Vz>$_ML?l7n`t*2!x@m;1MIswo0vDSFXm)84+_2e%(p=!W*0!|VHWEu z&M%Cw*^jbL<N((=``8#6SY|U{<=D;E%F1vF<hE>v<DkTPnuXySNISIBm;=g*e;FAz zf!bA5Ii@o*+yn*5W6rzm47Wkr7P2zj1&KW4*u=<iALJ0w_|H4ePt5Dt8Mc6QeP^A{ z$nX%Pwu0d?CnJL#sQ(YDB|(Mr38oJ$pt^D{CnV$S;C#-$pLGFaIjGDAmDrHZNeZ}C z#PAek$}<jzS0MU58^c?WeW0@aG3O(;qf89%KtZ^K@f<t22zn247idt0;RA>Tie`pw zpkDhnPEeH$8gpX!3^M5wJHuBH{g;tpGbjxDI2pcyl71g2ta}L`AL;~|G?{ZgGs6#1 zDD|`Sfkq2{gLJQBW&jlx3=E8&xl-8;j0_A6ivKwE{&R*laJe;d`8ILsGcl`k^E7iY zw1UQ4KxcwEw{YpTa{0D#1-EnQn=zYPG;@K3jXSvXI=NiCxZIk!*f}6#tleCCJzUPc zT>47P$`B!iJ}$j}E`}bY0X&FAKi32<y@_0|lR&oW>OlmxCv)jd;R@~I0=a;JfiYkz zm)<lk_vu_AGq?hJxom9hAnGh<a_P<D@}12U+{7g&4i;k)5uU@PH<!zG9#`0WE`4`q z52%?g3%K+aas@Bq3R%phZ^%50X$coYM@dm)Nosl}SSRCBuHa={AqF6s<y?9zxPqFv zG$Aq?E4lPmaXGC9d6Jt2BDRLhiHl_|m)<%q=O!*kh?v8AF1-z0p-nJ%t8C=b+r;J9 z#3c`rm)p#xw}mToE0<Ff7Yo#Hp4+(e8n__xs@u8rwnEtqJGk_Aayjh+*(nRPQ+hX- z-X5;dbujat_Hya%;|lGB@$L6>=^fy5pU>q3G0*oPm);>R_rqLn^SQX8VqQnM^tzyS zupQ;nJH{2Tn9B&FUjI0k-fXCx=m{>plb}eEg2+jp;?g_K6}lQ`7v~u+y|Y~I=ePpS zgF;F`Pza)q_X3yRMK0GSE`JE$?-G~ZWiH1yt{@0M@CujSYN#Dtpp?hBi4lC(9RP_C Bro;dM literal 0 HcmV?d00001 diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java index e88b0e9..c0a8fda 100644 --- a/src/main/java/app/SimulatorApplication.java +++ b/src/main/java/app/SimulatorApplication.java @@ -15,10 +15,15 @@ public class SimulatorApplication extends javafx.application.Application { 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; + private static final int BOX_WIDTH = 30; + private static final int BOX_HEIGHT = 30; + public static final int INITIAL_FIRE_COUNT = 6; public static final int INITIAL_FIREFIGHTER_COUNT = 6; + public static final int INITIAL_CLOUD_COUNT = 4; + private static final int INITIAL_ROAD_COUNT = 5; + public static final int INITIAL_MOTORIZEDFIREFIGHTER_COUNT = 4; + public static final int INITIAL_MOINTAIN_COUNT = 10; + private Stage primaryStage; private Parent view; @@ -26,7 +31,7 @@ public class SimulatorApplication extends javafx.application.Application { this.primaryStage = primaryStage; this.primaryStage.setTitle(APP_NAME); this.primaryStage.setOnCloseRequest(event -> Platform.exit()); - this.primaryStage.setResizable(true); + this.primaryStage.setResizable(false); this.primaryStage.sizeToScene(); } @@ -44,7 +49,7 @@ public class SimulatorApplication extends javafx.application.Application { view = loader.load(); Controller controller = loader.getController(); controller.initialize(BOX_WIDTH, BOX_HEIGHT, COLUMN_COUNT, ROW_COUNT, - INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); + INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT,INITIAL_CLOUD_COUNT , INITIAL_ROAD_COUNT,INITIAL_MOTORIZEDFIREFIGHTER_COUNT,INITIAL_MOINTAIN_COUNT); } private void showScene() { diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index 2a60897..9639cb6 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -12,9 +12,7 @@ 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 model.*; import util.Position; import view.Grid; import view.ViewElement; @@ -40,7 +38,9 @@ public class Controller { @FXML private Grid<ViewElement> grid; private Timeline timeline; - private Board<List<ModelElement>> board; + private Board board; + private State<List<ModelElement>> state; + private Updater boardUpdater; @FXML private void initialize() { @@ -54,20 +54,24 @@ public class Controller { pauseToggleButton.setSelected(true); } - private void setModel(FirefighterBoard firefighterBoard) { + private void setModel(FirefightingBoard firefighterBoard) { this.board = requireNonNull(firefighterBoard, "firefighter.model is null"); + this.state = new StateManager(board); + this.boardUpdater = new BoardUpdater(board); } private void updateBoard(){ - List<Position> updatedPositions = board.updateToNextGeneration(); + List<Position> updatedPositions = boardUpdater.update(); List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>(); for(Position updatedPosition : updatedPositions){ - List<ModelElement> squareState = board.getState(updatedPosition); + List<ModelElement> squareState = state.getState(updatedPosition); ViewElement viewElement = getViewElement(squareState); updatedSquares.add(new Pair<>(updatedPosition, viewElement)); } grid.repaint(updatedSquares); updateGenerationLabel(board.stepNumber()); + if (board.getFire().getPositions().isEmpty()) + pause(); } private void repaintGrid(){ @@ -76,7 +80,7 @@ public class Controller { 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))); + viewElements[row][column] = getViewElement(state.getState(new Position(row, column))); grid.repaint(viewElements); updateGenerationLabel(board.stepNumber()); } @@ -85,9 +89,21 @@ public class Controller { if(squareState.contains(ModelElement.FIREFIGHTER)){ return ViewElement.FIREFIGHTER; } + if(squareState.contains(ModelElement.CLOUD)){ + return ViewElement.CLOUD; + } + if(squareState.contains(ModelElement.MOTORIZEDFIREFIGHTER)){ + return ViewElement.MOTORIZEDFIREFIGHTER; + } + if(squareState.contains(ModelElement.MOUNTAIN)){ + return ViewElement.MOUNTAIN; + } if (squareState.contains(ModelElement.FIRE)){ return ViewElement.FIRE; } + if (squareState.contains(ModelElement.ROAD)){ + return ViewElement.ROAD; + } return ViewElement.EMPTY; } @@ -124,9 +140,10 @@ public class Controller { } public void initialize(int squareWidth, int squareHeight, int columnCount, - int rowCount, int initialFireCount, int initialFirefighterCount) { + int rowCount, int initialFireCount, int initialFirefighterCount,int initialCloudCount ,int initialRoadsCount, + int initialMotorizedFirefighterCount, int initialMountainCount) { grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight); - this.setModel(new FirefighterBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount)); + this.setModel(new FirefightingBoard(columnCount, rowCount, initialFireCount, initialFirefighterCount,initialCloudCount , initialRoadsCount,initialMotorizedFirefighterCount,initialMountainCount)); repaintGrid(); } diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java index bb089a4..1d9a993 100644 --- a/src/main/java/model/Board.java +++ b/src/main/java/model/Board.java @@ -3,63 +3,70 @@ package model; import util.Position; import java.util.List; +import java.util.Set; /** - * This interface represents a generic board for modeling various state-based systems. + * This interface represents a board for modeling various state-based systems. * - * @param <S> The type of state represented on the board. */ -public interface Board<S> { +public interface Board { - /** - * Get the state of the board at a specific position. - * - * @param position The position on the board for which to retrieve the state. - * @return The state at the specified position. - */ - S getState(Position position); + /** + * Get the number of rows in the board. + * + * @return The number of rows in the board. + */ + int rowCount(); - /** - * Set the state of a specific position on the board to the specified state. - * - * @param state The state to set for the given position. - * @param position The position on the board for which to set the state. - */ - void setState(S state, Position position); + /** + * Get the number of columns in the board. + * + * @return The number of columns in the board. + */ + int columnCount(); + /** + * Set the step number of the board to the specified value. + * + * @param step The step number to be set for the board. + */ + void setStep(int step); - /** - * Get the number of rows in the board. - * - * @return The number of rows in the board. - */ - int rowCount(); + /** + * Reset the board to its initial state. + */ + void reset(); - /** - * Get the number of columns in the board. - * - * @return The number of columns in the board. - */ - int columnCount(); + /** + * Get the current step number or generation of the board. + * + * @return The current step number or generation. + */ + int stepNumber(); - /** - * Update the board to its next generation or state. This method may modify the - * internal state of the board and return a list of positions that have changed - * during the update. - * - * @return A list of positions that have changed during the update. - */ - List<Position> updateToNextGeneration(); + /** + * Get the element representing the positions of firefighters on the board. + * + * @return The element containing the positions of firefighters. + */ + FireExtinguisher getFirefighter(); + /** + * Retrieve the element containing the positions of clouds on the board. + * + * @return The element representing the positions of clouds. + */ + Elements<List<Position>> getCloud(); - /** - * Reset the board to its initial state. - */ - void reset(); + /** + * Get the element representing the positions of fire on the board. + * + * @return The element containing the positions of fire. + */ + Elements<Set<Position>> getFire(); - /** - * Get the current step number or generation of the board. - * - * @return The current step number or generation. - */ - int stepNumber(); + FireExtinguisher getMotorizedFirefighter(); + + Elements<List<Position>> getRoad(); + + Elements<List<Position>> getMountain(); } diff --git a/src/main/java/model/BoardUpdater.java b/src/main/java/model/BoardUpdater.java new file mode 100644 index 0000000..1776606 --- /dev/null +++ b/src/main/java/model/BoardUpdater.java @@ -0,0 +1,26 @@ +package model; + +import util.Position; + +import java.util.List; + +public class BoardUpdater implements Updater { + private final Board board; + + public BoardUpdater(Board board) { + this.board = board; + } + + @Override + public List<Position> update() { + Updater updater = new FirefighterUpdater(board); + List<Position> modifiedPositions = updater.update(); + updater = new CloudUpdater(board); + modifiedPositions.addAll(updater.update()); + updater = new MotorizedFirefighterUpdater(board); + modifiedPositions.addAll(updater.update()); + updater = new FireUpdater(board); + modifiedPositions.addAll(updater.update()); + board.setStep(board.stepNumber()+1); + return modifiedPositions; } +} diff --git a/src/main/java/model/Cloud.java b/src/main/java/model/Cloud.java index ad88e36..d1bafb9 100644 --- a/src/main/java/model/Cloud.java +++ b/src/main/java/model/Cloud.java @@ -1,46 +1,30 @@ package model; import util.Position; -import java.util.List; -import java.util.Random; -import java.util.Set; -public class Cloud { - private List<Position> positions; +import java.util.ArrayList; +import java.util.List; - public Cloud(List<Position> initialPositions) { - this.positions = initialPositions; +public class Cloud implements Elements<List<Position>> { + private List<Position> cloudPositions; + private final int initialCloudCount; + public Cloud(int initialCloudCount) { + this.initialCloudCount = initialCloudCount; + cloudPositions = new ArrayList<>(); } - /** - * Déplace chaque nuage vers une position aléatoire parmi les positions possibles. - * - * @param possiblePositions Ensemble des positions possibles. - * @return Liste des nouvelles positions des nuages. - */ - public List<Position> moveRandomly(Set<Position> possiblePositions) { - Random random = new Random(); - for (int i = 0; i < positions.size(); i++) { - // Choisir une position aléatoire dans l'ensemble des positions possibles - Position newPosition = possiblePositions.stream() - .skip(random.nextInt(possiblePositions.size())) - .findFirst() - .orElse(positions.get(i)); - positions.set(i, newPosition); - } - return positions; + @Override + public List<Position> getPositions() { + return this.cloudPositions; } - /** - * Éteint les feux situés sur les positions occupées par les nuages. - * - * @param fire L'objet Fire à modifier. - */ - public void extinguishFire(Fire fire) { - positions.forEach(fire::extinguish); + @Override + public void setPositions(List<Position> positions) { + this.cloudPositions = positions; } - public List<Position> getPositions() { - return positions; + @Override + public int getInitialCount() { + return initialCloudCount; } } diff --git a/src/main/java/model/CloudUpdater.java b/src/main/java/model/CloudUpdater.java new file mode 100644 index 0000000..aa6f851 --- /dev/null +++ b/src/main/java/model/CloudUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.*; + +public class CloudUpdater extends FireExtinguisherUpdater implements Updater { + private final Board board; + public CloudUpdater(Board board) { + super(board); + this.board = board; + } + + @Override + public List<Position> update() { + Neighbors neighbors = new Neighbors(board); + List<Position> modifiedPosition = new ArrayList<>(); + List<Position> cloudPositions = new ArrayList<>(); + RandomPositionsGenerator randomPositionsGenerator = new RandomPositionsGenerator(board); + + for (Position cloudPosition : board.getCloud().getPositions()) { + Position newCloudPosition = randomPositionsGenerator.randomPosition(); + cloudPositions.add(newCloudPosition); + extinguish(newCloudPosition); + modifiedPosition.add(cloudPosition); + modifiedPosition.add(newCloudPosition); + List<Position> neighborFirePositions = neighbors.neighbors(newCloudPosition,1).stream() + .filter(board.getFire().getPositions()::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + modifiedPosition.addAll(neighborFirePositions); + } + board.getCloud().setPositions(cloudPositions); + return modifiedPosition; + } +} diff --git a/src/main/java/model/Elements.java b/src/main/java/model/Elements.java new file mode 100644 index 0000000..781fb79 --- /dev/null +++ b/src/main/java/model/Elements.java @@ -0,0 +1,11 @@ +package model; + +import util.Position; + +import java.util.List; + +public interface Elements <T>{ + T getPositions(); + void setPositions(T positions); + int getInitialCount(); +} diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java index 28bc66b..4eeff26 100644 --- a/src/main/java/model/Fire.java +++ b/src/main/java/model/Fire.java @@ -2,36 +2,33 @@ package model; import util.Position; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; import java.util.Set; -public class Fire { - private Set<Position> positions; +public class Fire implements Elements<Set<Position>>{ - public Fire(Set<Position> initialPositions) { - this.positions = initialPositions; + private final int initialFireCount; + private Set<Position> firePositions; + + public Fire(int initialFireCount) { + this.initialFireCount = initialFireCount; + this.firePositions = new HashSet<>(); } + @Override public Set<Position> getPositions() { - return positions; + return firePositions; } - public List<Position> spread(Set<Position> allPositions, Set<Position> roadPositions) { - List<Position> newFirePositions = new ArrayList<>(); - for (Position position : positions) { - for (Position neighbor : allPositions) { - if (!roadPositions.contains(neighbor) && !positions.contains(neighbor)) { - newFirePositions.add(neighbor); - } - } - } - positions.addAll(newFirePositions); - return newFirePositions; - } + @Override + public void setPositions(Set<Position> positions) { + this.firePositions = positions; + } - public void extinguish(Position position) { - positions.remove(position); - }} \ No newline at end of file + @Override + public int getInitialCount() { + return initialFireCount; + } +} diff --git a/src/main/java/model/FireExtinguisher.java b/src/main/java/model/FireExtinguisher.java new file mode 100644 index 0000000..b1728f1 --- /dev/null +++ b/src/main/java/model/FireExtinguisher.java @@ -0,0 +1,32 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public abstract class FireExtinguisher implements Elements<List<Position>> { + + private final int initialCount; + private List<Position> Positions; + + public FireExtinguisher(int initialCount) { + this.initialCount = initialCount; + this.Positions = new ArrayList<>(); + } + @Override + public List<Position> getPositions() { + return this.Positions; + } + + @Override + public void setPositions(List<Position> positions) { + this.Positions = positions; + } + + @Override + public int getInitialCount() { + return initialCount; + } + +} diff --git a/src/main/java/model/FireExtinguisherUpdater.java b/src/main/java/model/FireExtinguisherUpdater.java new file mode 100644 index 0000000..a091589 --- /dev/null +++ b/src/main/java/model/FireExtinguisherUpdater.java @@ -0,0 +1,42 @@ +package model; + +import util.Position; + +import java.util.*; + +public abstract class FireExtinguisherUpdater implements Updater{ + private final Board board; + + public FireExtinguisherUpdater(Board board) { + this.board = board; + } + + public Position neighborClosestToFire(Position position,int step) { + Set<Position> seen = new HashSet<>(); + Neighbors neighborsOfPosition = new Neighbors(board); + HashMap<Position, Position> firstMove = new HashMap<>(); + Queue<Position> toVisit = new LinkedList<>(neighborsOfPosition.neighbors(position,step)); + for (Position initialMove : toVisit) + firstMove.put(initialMove, initialMove); + while (!toVisit.isEmpty()) { + Position current = toVisit.poll(); + if (board.getFire().getPositions().contains(current)) + return firstMove.get(current); + for (Position adjacent : neighborsOfPosition.neighbors(current,step)) { + if (seen.contains(adjacent)) continue; + toVisit.add(adjacent); + seen.add(adjacent); + firstMove.put(adjacent, firstMove.get(current)); + } + } + return position; + } + public void extinguish(Position position) { + board.getFire().getPositions().remove(position); + } + public void restraintFireExtinguisher(List<Position> positions){ + for (Position moutainPosition : board.getMountain().getPositions()) + if (positions.contains(moutainPosition)) + positions.remove(moutainPosition); + } +} diff --git a/src/main/java/model/FireUpdater.java b/src/main/java/model/FireUpdater.java new file mode 100644 index 0000000..4e830dd --- /dev/null +++ b/src/main/java/model/FireUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class FireUpdater implements Updater{ + + private final Board board; + + + public FireUpdater(Board board) { + this.board = board; + } + + @Override + public List<Position> update() { + Neighbors neighborsPosition = new Neighbors(board); + + List<Position> modifiedPositions = new ArrayList<>(); + if (board.stepNumber() % 2 == 0) { + List<Position> newFirePositions = new ArrayList<>(); + for (Position fire : board.getFire().getPositions()) { + for(Position neighborsPositions : neighborsPosition.neighbors(fire , 1)) { + if (!board.getRoad().getPositions().contains(neighborsPositions) && !board.getMountain().getPositions().equals(neighborsPositions)) { + newFirePositions.add(neighborsPositions); + } + } + } + board.getFire().getPositions().addAll(newFirePositions); + modifiedPositions.addAll(newFirePositions); + } + return modifiedPositions; + } +} diff --git a/src/main/java/model/Firefighter.java b/src/main/java/model/Firefighter.java index 0538a32..0dcc893 100644 --- a/src/main/java/model/Firefighter.java +++ b/src/main/java/model/Firefighter.java @@ -1,65 +1,11 @@ package model; import util.Position; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import util.TargetStrategy; - -public class Firefighter { - private List<Position> positions; - private TargetStrategy targetStrategy; - - // Constructor - public Firefighter(List<Position> initialPositions, TargetStrategy targetStrategy) { - this.positions = initialPositions; - this.targetStrategy = targetStrategy; - } - - public boolean canFireSpreadToRock(Position position, int currentStepNumber, FirefighterBoard board) { - List<ModelElement> elements = board.getState(position); - if (elements.contains(ModelElement.ROCK)) { - return currentStepNumber >= 4; - } - return false; - } - - public List<Position> moveToClosestFire(Set<Position> firePositions, - Map<Position, List<Position>> neighbors, - Set<Position> roadPositions) { - List<Position> modifiedPositions = new ArrayList<>(); - List<Position> newPositions = new ArrayList<>(); - - for (Position position : getPositions()) { - Position firstStep = getTargetStrategy().neighborClosestToFire(position, firePositions, neighbors, roadPositions); - - Position secondStep = (firstStep != null) - ? getTargetStrategy().neighborClosestToFire(firstStep, firePositions, neighbors, roadPositions) - : null; - Position newPosition = (secondStep != null) ? secondStep : firstStep; - - modifiedPositions.add(position); - if (firstStep != null) modifiedPositions.add(firstStep); - if (secondStep != null) modifiedPositions.add(secondStep); - - newPositions.add(newPosition); - } - - setPositions(newPositions); - return modifiedPositions; - } - - public TargetStrategy getTargetStrategy() { - return targetStrategy; - } - - public List<Position> getPositions() { - return positions; - } +import java.util.List; - protected void setPositions(List<Position> positions) { - this.positions = positions; +public class Firefighter extends FireExtinguisher implements Elements<List<Position>> { + public Firefighter(int initialFirefighterCount) { + super(initialFirefighterCount); } } diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java deleted file mode 100644 index 6b72729..0000000 --- a/src/main/java/model/FirefighterBoard.java +++ /dev/null @@ -1,147 +0,0 @@ -package model; - -import util.Position; -import java.util.*; -import util.TargetStrategy; - -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 Position[][] positions; - private final Map<Position, List<Position>> neighbors = new HashMap<>(); - private Cloud clouds; - private Firefighter motorizedFirefighter; - private Set<Position> mountainPositions = new HashSet<>(); - private Set<Position> roadPositions = new HashSet<>(); - - private Fire fire; - private Firefighter firefighter; - private int step = 0; - - public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { - this.columnCount = columnCount; - this.rowCount = rowCount; - this.initialFireCount = initialFireCount; - this.initialFirefighterCount = initialFirefighterCount; - this.positions = new Position[rowCount][columnCount]; - initializePositions(); - initializeNeighbors(); - initializeElements(); - } - - private boolean canFireSpreadToRock(Position position, int currentStepNumber) { - List<ModelElement> elements = getState(position); - if (elements.contains(ModelElement.ROCK)) { - return currentStepNumber >= 4; - } - return false; - } - - private void initializePositions() { - for (int column = 0; column < columnCount; column++) - for (int row = 0; row < rowCount; row++) - positions[row][column] = new Position(row, column); - } - - private void initializeNeighbors() { - 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); - } - } - - private void initializeElements() { - Set<Position> initialFirePositions = new HashSet<>(); - List<Position> initialFirefighterPositions = new ArrayList<>(); - Random random = new Random(); - - for (int i = 0; i < initialFireCount; i++) { - initialFirePositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); - } - for (int i = 0; i < initialFirefighterCount; i++) { - initialFirefighterPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); - } - - for (int i = 0; i < 10; i++) { - roadPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); - } - - fire = new Fire(initialFirePositions); - firefighter = new Firefighter(initialFirefighterPositions, new TargetStrategy()); - } - - @Override - public List<ModelElement> getState(Position position) { - List<ModelElement> elements = new ArrayList<>(); - if (mountainPositions.contains(position)) elements.add(ModelElement.MOUNTAIN); - if (fire.getPositions().contains(position)) elements.add(ModelElement.FIRE); - if (firefighter.getPositions().contains(position)) elements.add(ModelElement.FIREFIGHTER); - return elements; - } - - @Override - public List<Position> updateToNextGeneration() { - List<Position> modifiedPositions = new ArrayList<>(); - Set<Position> newFires = new HashSet<>(); - - for (int row = 0; row < rowCount; row++) { - for (int column = 0; column < columnCount; column++) { - Position position = positions[row][column]; - List<ModelElement> elements = getState(position); - - if (elements.contains(ModelElement.ROCK)) { - for (Position adj : neighbors.get(position)) { - List<ModelElement> adjElements = getState(adj); - if (adjElements.contains(ModelElement.FIRE) && canFireSpreadToRock(position, step)) { - newFires.add(position); - } - } - } - } - } - - for (Position firePos : newFires) { - List<ModelElement> elements = getState(firePos); - elements.add(ModelElement.FIRE); - setState(elements, firePos); - modifiedPositions.add(firePos); - } - - step++; - return modifiedPositions; - } - - @Override - public void setState(List<ModelElement> state, Position position) { - if (state.contains(ModelElement.FIRE)) fire.getPositions().add(position); - if (state.contains(ModelElement.FIREFIGHTER)) firefighter.getPositions().add(position); - } - - @Override - public int rowCount() { - return rowCount; - } - - @Override - public int columnCount() { - return columnCount; - } - - @Override - public int stepNumber() { - return step; - } - - @Override - public void reset() { - step = 0; - initializeElements(); - } -} diff --git a/src/main/java/model/FirefighterUpdater.java b/src/main/java/model/FirefighterUpdater.java new file mode 100644 index 0000000..aafda36 --- /dev/null +++ b/src/main/java/model/FirefighterUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class FirefighterUpdater extends FireExtinguisherUpdater implements Updater{ + private final Board board; + public FirefighterUpdater(Board board){ + super(board); + this.board = board; + } + @Override + public List<Position> update() { + Neighbors neighbors = new Neighbors(board); + List<Position> modifiedPosition = new ArrayList<>(); + List<Position> firefighterNewPositions = new ArrayList<>(); + + for (Position firefighterPosition : board.getFirefighter().getPositions()) { + Position newFirefighterPosition = neighborClosestToFire(firefighterPosition,1); + firefighterNewPositions.add(newFirefighterPosition); + extinguish(newFirefighterPosition); + modifiedPosition.add(firefighterPosition); + modifiedPosition.add(newFirefighterPosition); + List<Position> neighborFirePositions = neighbors.neighbors(newFirefighterPosition,1).stream() + .filter(board.getFire().getPositions()::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + modifiedPosition.addAll(neighborFirePositions); + } + this.restraintFireExtinguisher(modifiedPosition); + board.getFirefighter().setPositions(firefighterNewPositions); + return modifiedPosition; + } +} diff --git a/src/main/java/model/FirefightingBoard.java b/src/main/java/model/FirefightingBoard.java new file mode 100644 index 0000000..fc470fb --- /dev/null +++ b/src/main/java/model/FirefightingBoard.java @@ -0,0 +1,111 @@ +package model; + +import util.Position; + +import java.util.*; + + +public class FirefightingBoard implements Board { + + private final Elements<Set<Position>> fire; + private final FireExtinguisher firefighter; + private final Elements<List<Position>> cloud; + private final Elements<List<Position>> road; + private final FireExtinguisher motorizedFirefighter; + private final Elements<List<Position>> mountain; + private final int columnCount; + private final int rowCount; + private int step = 0; + private final RandomPositionsGenerator randomPositionsGenerator; + + + public FirefightingBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount, int initialCloudCount , int initialRoadscount, int initialMotorizedFirefighterCount, int initialMountainCount) { + this.columnCount = columnCount; + this.rowCount = rowCount; + this.road = new Road(initialRoadscount); + this.fire = new Fire(initialFireCount); + this.firefighter = new Firefighter(initialFirefighterCount); + this.cloud = new Cloud(initialCloudCount); + this.motorizedFirefighter = new MotorizedFirefighter(initialMotorizedFirefighterCount); + this.mountain = new Mountain(initialMountainCount); + this.randomPositionsGenerator = new RandomPositionsGenerator(this); + initializeElements(); + } + + public void initializeElements() { + fire.setPositions(new HashSet<>()); + firefighter.setPositions(new ArrayList<>()); + cloud.setPositions(new ArrayList<>()); + road.setPositions(new ArrayList<>()); + motorizedFirefighter.setPositions(new ArrayList<>()); + mountain.setPositions(new ArrayList<>()); + for (int index = 0; index < fire.getInitialCount(); index++) + fire.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < firefighter.getInitialCount(); index++) + firefighter.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < motorizedFirefighter.getInitialCount(); index++) + motorizedFirefighter.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < mountain.getInitialCount(); index++) + mountain.getPositions().add(randomPositionsGenerator.randomPosition()); + for (int index = 0; index < cloud.getInitialCount(); index++) + cloud.getPositions().add(randomPositionsGenerator.randomPosition()); + for(int index = 0;index<road.getInitialCount();index++) + road.getPositions().add(randomPositionsGenerator.randomPosition()); + } + + @Override + public int rowCount() { + return rowCount; + } + + @Override + public int columnCount() { + return columnCount; + } + + @Override + public Elements<Set<Position>> getFire() { + return fire; + } + + @Override + public FireExtinguisher getMotorizedFirefighter() { + return motorizedFirefighter; + } + + + @Override + public FireExtinguisher getFirefighter() { + return firefighter; + } + + @Override + public Elements<List<Position>> getCloud() { + return cloud; + } + + public Elements<List<Position>> getRoad() { + return road; + } + + @Override + public Elements<List<Position>> getMountain() { + return mountain; + } + + @Override + public int stepNumber() { + return step; + } + @Override + public void setStep(int step) { + this.step = step; + } + + @Override + public void reset() { + step = 0; + initializeElements(); + } + +} \ No newline at end of file diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index e5f5417..f4be716 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, CLOUD, MOUNTAIN,ROCK + FIREFIGHTER, FIRE, CLOUD, MOTORIZEDFIREFIGHTER , MOUNTAIN, ROAD } diff --git a/src/main/java/model/MotorizedFirefighter.java b/src/main/java/model/MotorizedFirefighter.java index c88a823..ac01df3 100644 --- a/src/main/java/model/MotorizedFirefighter.java +++ b/src/main/java/model/MotorizedFirefighter.java @@ -2,40 +2,10 @@ package model; import util.Position; -import java.util.*; -import util.TargetStrategy; +import java.util.List; -public class MotorizedFirefighter extends Firefighter { - - public MotorizedFirefighter(List<Position> initialPositions, TargetStrategy targetStrategy) { - super(initialPositions, targetStrategy); - } - - @Override - public List<Position> moveToClosestFire(Set<Position> firePositions, - Map<Position, List<Position>> neighbors, - Set<Position> roadPositions) { - List<Position> modifiedPositions = new ArrayList<>(); - List<Position> newPositions = new ArrayList<>(); - - for (Position position : getPositions()) { - Position firstStep = getTargetStrategy().neighborClosestToFire(position, firePositions, neighbors, roadPositions); - - Position secondStep = (firstStep != null) - ? getTargetStrategy().neighborClosestToFire(firstStep, firePositions, neighbors, roadPositions) - : null; - - Position newPosition = (secondStep != null) ? secondStep : firstStep; - - modifiedPositions.add(position); - if (firstStep != null) modifiedPositions.add(firstStep); - if (secondStep != null) modifiedPositions.add(secondStep); - - newPositions.add(newPosition); - } - - setPositions(newPositions); - return modifiedPositions; +public class MotorizedFirefighter extends FireExtinguisher implements Elements<List<Position>> { + public MotorizedFirefighter(int initialMotorizedFirefighterCount) { + super(initialMotorizedFirefighterCount); } - } diff --git a/src/main/java/model/MotorizedFirefighterUpdater.java b/src/main/java/model/MotorizedFirefighterUpdater.java new file mode 100644 index 0000000..fa748b5 --- /dev/null +++ b/src/main/java/model/MotorizedFirefighterUpdater.java @@ -0,0 +1,36 @@ +package model; + +import util.Position; + +import java.util.*; + +public class MotorizedFirefighterUpdater extends FireExtinguisherUpdater implements Updater{ + private final Board board; + public MotorizedFirefighterUpdater(Board board) { + super(board); + this.board = board; + } + + @Override + public List<Position> update() { + Neighbors neighbors = new Neighbors(board); + List<Position> modifiedPosition = new ArrayList<>(); + List<Position> motorizedFirefighterNewPositions = new ArrayList<>(); + + for (Position motorizedFirefighterPosition : board.getMotorizedFirefighter().getPositions()) { + Position newMotorizedFirefighterPosition = this.neighborClosestToFire(motorizedFirefighterPosition,2); + motorizedFirefighterNewPositions.add(newMotorizedFirefighterPosition); + extinguish(newMotorizedFirefighterPosition); + modifiedPosition.add(motorizedFirefighterPosition); + modifiedPosition.add(newMotorizedFirefighterPosition); + List<Position> neighborFirePositions = neighbors.neighbors(newMotorizedFirefighterPosition,2).stream() + .filter(board.getFire().getPositions()::contains).toList(); + for(Position firePosition : neighborFirePositions) + extinguish(firePosition); + modifiedPosition.addAll(neighborFirePositions); + } + this.restraintFireExtinguisher(modifiedPosition); + board.getMotorizedFirefighter().setPositions(motorizedFirefighterNewPositions); + return modifiedPosition; + } +} diff --git a/src/main/java/model/Mountain.java b/src/main/java/model/Mountain.java new file mode 100644 index 0000000..6eb06f3 --- /dev/null +++ b/src/main/java/model/Mountain.java @@ -0,0 +1,31 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Mountain implements Elements<List<Position>>{ + private final int initialMountainCount; + private List<Position> mountainPositions; + + public Mountain(int initialMountainCount) { + this.initialMountainCount = initialMountainCount; + this.mountainPositions = new ArrayList<>(); + } + + @Override + public List<Position> getPositions() { + return mountainPositions; + } + + @Override + public void setPositions(List<Position> positions) { + mountainPositions = positions; + } + + @Override + public int getInitialCount() { + return initialMountainCount; + } +} diff --git a/src/main/java/model/Neighbors.java b/src/main/java/model/Neighbors.java new file mode 100644 index 0000000..8268f54 --- /dev/null +++ b/src/main/java/model/Neighbors.java @@ -0,0 +1,24 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Neighbors { + + private final Board board; + + public Neighbors(Board board) { + this.board = board; + } + + public List<Position> neighbors(Position position,int step) { + List<Position> list = new ArrayList<>(); + if (position.row() > 0) list.add(new Position(position.row() - step, position.column())); + if (position.column() > 0) list.add(new Position(position.row(), position.column() - step)); + if (position.row() < board.rowCount() - step) list.add(new Position(position.row() + step, position.column())); + if (position.column() < board.columnCount() - step) list.add(new Position(position.row(), position.column() + step)); + return list; + } +} diff --git a/src/main/java/model/RandomPositionsGenerator.java b/src/main/java/model/RandomPositionsGenerator.java new file mode 100644 index 0000000..fa7b175 --- /dev/null +++ b/src/main/java/model/RandomPositionsGenerator.java @@ -0,0 +1,20 @@ +package model; + +import util.Position; + +import java.util.Random; + +public class RandomPositionsGenerator { + private final Board board; + private final Random randomGenerator ; + + public RandomPositionsGenerator(Board board) { + this.board = board; + this.randomGenerator = new Random(); + } + + public Position randomPosition() { + return new Position(randomGenerator.nextInt(board.rowCount()), randomGenerator.nextInt(board.columnCount())); + } + +} diff --git a/src/main/java/model/Road.java b/src/main/java/model/Road.java new file mode 100644 index 0000000..fd8bc2b --- /dev/null +++ b/src/main/java/model/Road.java @@ -0,0 +1,31 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Road implements Elements<List<Position>> { + private List<Position> roadsPositions; + private int initialRoadsCount; + + public Road (int initialRoadsCount) { + this.initialRoadsCount=initialRoadsCount; + roadsPositions= new ArrayList<>(); + } + + @Override + public List<Position> getPositions() { + return roadsPositions; + } + + @Override + public void setPositions(List<Position> positions) { + this.roadsPositions = positions; + } + + @Override + public int getInitialCount() { + return initialRoadsCount; + } +} diff --git a/src/main/java/model/State.java b/src/main/java/model/State.java new file mode 100644 index 0000000..d7b7069 --- /dev/null +++ b/src/main/java/model/State.java @@ -0,0 +1,29 @@ +package model; + +import util.Position; + +/** + * Represents a state manager for a board at specific positions. + * Implementations of this interface provide methods to retrieve and set the state + * of a position on the board. + * + * @param <S> The type of state represented on the board. + */ + +public interface State<S>{ + /** + * Get the state of the board at a specific position. + * + * @param position The position on the board for which to retrieve the state. + * @return The state at the specified position. + */ + S getState(Position position); + + /** + * Set the state of a specific position on the board to the specified state. + * + * @param state The state to set for the given position. + * @param position The position on the board for which to set the state. + */ + void setState(S state, Position position); +} diff --git a/src/main/java/model/StateManager.java b/src/main/java/model/StateManager.java new file mode 100644 index 0000000..8aeb8b4 --- /dev/null +++ b/src/main/java/model/StateManager.java @@ -0,0 +1,59 @@ +package model; + +import util.Position; + +import java.util.ArrayList; +import java.util.List; + +public class StateManager implements State<List<ModelElement>>{ + + private final Board board; + + public StateManager(Board board) { + this.board = board; + } + + @Override + public List<ModelElement> getState(Position position) { + List<ModelElement> result = new ArrayList<>(); + for (Position firefighterPosition : board.getFirefighter().getPositions()) + if (firefighterPosition.equals(position)) + result.add(ModelElement.FIREFIGHTER); + for (Position cloudPosition : board.getCloud().getPositions()) + if (cloudPosition.equals(position)) + result.add(ModelElement.CLOUD); + for (Position motorizedFirefighterPosition : board.getMotorizedFirefighter().getPositions()) + if (motorizedFirefighterPosition.equals(position)) + result.add(ModelElement.MOTORIZEDFIREFIGHTER); + for (Position mountainPosition : board.getMountain().getPositions()) + if (mountainPosition.equals(position)) + result.add(ModelElement.MOUNTAIN); + if (board.getFire().getPositions().contains(position)) + result.add(ModelElement.FIRE); + if(board.getRoad().getPositions().contains(position)) + result.add(ModelElement.ROAD); + return result; + } + + @Override + public void setState(List<ModelElement> state, Position position) { + board.getFire().getPositions().remove(position); + for (; ; ) { + if (!board.getFirefighter().getPositions().remove(position)) break; + if (!board.getCloud().getPositions().remove(position)) break; + if (!board.getMotorizedFirefighter().getPositions().remove(position)) break; + if (!board.getRoad().getPositions().remove(position)) break; + } + for (ModelElement element : state) { + switch (element) { + case FIRE -> board.getFire().getPositions().add(position); + case FIREFIGHTER -> board.getFirefighter().getPositions().add(position); + case CLOUD -> board.getCloud().getPositions().add(position); + case MOUNTAIN -> board.getMountain().getPositions().add(position); + case MOTORIZEDFIREFIGHTER -> board.getMotorizedFirefighter().getPositions().add(position); + case ROAD -> board.getRoad().getPositions().add(position); + + } + } + } +} diff --git a/src/main/java/model/Updater.java b/src/main/java/model/Updater.java new file mode 100644 index 0000000..3ade6c6 --- /dev/null +++ b/src/main/java/model/Updater.java @@ -0,0 +1,9 @@ +package model; + +import util.Position; + +import java.util.List; + +public interface Updater { + List<Position> update(); +} diff --git a/src/main/java/util/Position.java b/src/main/java/util/Position.java index 5220fa0..31dc4c1 100644 --- a/src/main/java/util/Position.java +++ b/src/main/java/util/Position.java @@ -1,47 +1,5 @@ package util; -import java.util.Objects; +public record Position(int row, int column) { -public class Position { - private final int row; - private final int column; - - public Position(int row, int column) { - this.row = row; - this.column = column; - } - - public int row() { - return row; - } - - public int column() { - return column; - } - - public int getRow() { - return row; - } - - public int getColumn() { - return column; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Position position = (Position) o; - return row == position.row && column == position.column; - } - - @Override - public int hashCode() { - return Objects.hash(row, column); - } - - @Override - public String toString() { - return "Position{" + "row=" + row + ", column=" + column + '}'; - } } diff --git a/src/main/java/util/TargetStrategy.java b/src/main/java/util/TargetStrategy.java deleted file mode 100644 index 629b6f6..0000000 --- a/src/main/java/util/TargetStrategy.java +++ /dev/null @@ -1,53 +0,0 @@ -package util; - -import util.Position; - -import java.util.*; - -public class TargetStrategy { - - /** - * Trouve la case adjacente la plus proche du feu en respectant les routes. - * - * @param position Position actuelle. - * @param targets Positions des feux. - * @param neighbors Carte des voisins pour chaque position. - * @param roadPositions Positions représentant les routes. - * @return La position voisine qui se rapproche le plus d'un feu, respectant les routes. - */ - public Position neighborClosestToFire(Position position, Collection<Position> targets, - Map<Position, List<Position>> neighbors, - Set<Position> roadPositions) { - Set<Position> seen = new HashSet<>(); - Map<Position, Position> firstMove = new HashMap<>(); - Queue<Position> toVisit = new LinkedList<>(neighbors.get(position)); - - // Initialisation des mouvements possibles - for (Position initialMove : toVisit) { - if (roadPositions.contains(initialMove)) { - firstMove.put(initialMove, initialMove); - } - } - - // Parcours en largeur (BFS) pour trouver le feu le plus proche - while (!toVisit.isEmpty()) { - Position current = toVisit.poll(); - - // Si la position actuelle est un feu, on retourne le premier mouvement vers cette position - if (targets.contains(current)) { - return firstMove.get(current); - } - - // Ajout des voisins non visités qui sont sur les routes - for (Position adjacent : neighbors.get(current)) { - if (seen.contains(adjacent) || !roadPositions.contains(adjacent)) continue; - toVisit.add(adjacent); - seen.add(adjacent); - firstMove.put(adjacent, firstMove.get(current)); - } - } - - // Si aucun feu n'est trouvé, retourner la position actuelle - return position; - } -} diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java index ffb7611..accd977 100644 --- a/src/main/java/view/ViewElement.java +++ b/src/main/java/view/ViewElement.java @@ -1,9 +1,10 @@ package view; import javafx.scene.paint.Color; +import model.Road; public enum ViewElement { - FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE), CLOUD(Color.GRAY),MOTORIZEDFIREFIGHTER(Color.AQUA), ROAD(Color.BLACK), MOUNTAIN(Color.BROWN); final Color color; ViewElement(Color color) { this.color = color; -- GitLab