From ea1ca7a0cd0833263c5ca47921652d199666ec1c Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 14 Feb 2025 09:37:51 +0100 Subject: [PATCH] Fixed room overlaps --- .../Debug/net9.0/DungeonMapConsolePrinter.dll | Bin 5632 -> 5632 bytes .../Debug/net9.0/DungeonMapConsolePrinter.exe | Bin 145920 -> 145920 bytes .../bin/Debug/net9.0/DungeonMapGenerator.dll | Bin 25600 -> 25600 bytes .../DungeonMapGenerator/DungeonGenerator.cs | 28 +- .../netstandard2.0/DungeonMapGenerator.dll | Bin 25600 -> 25600 bytes Dungeons/dungeon.json | 1620 ++ Dungeons/dungeon01.json | 1861 +++ Dungeons/dungeon02.json | 1570 ++ .../Assets/Scenes/TestDungeons/Test_03.unity | 12612 ++++++++++++++ .../Scenes/TestDungeons/Test_03.unity.meta | 7 + .../Assets/Scenes/TestDungeons/Test_04.unity | 13873 ++++++++++++++++ .../Scenes/TestDungeons/Test_04.unity.meta | 7 + 12 files changed, 31564 insertions(+), 14 deletions(-) create mode 100644 Dungeons/dungeon.json create mode 100644 Dungeons/dungeon01.json create mode 100644 Dungeons/dungeon02.json create mode 100644 PuzzleGameProject/Assets/Scenes/TestDungeons/Test_03.unity create mode 100644 PuzzleGameProject/Assets/Scenes/TestDungeons/Test_03.unity.meta create mode 100644 PuzzleGameProject/Assets/Scenes/TestDungeons/Test_04.unity create mode 100644 PuzzleGameProject/Assets/Scenes/TestDungeons/Test_04.unity.meta diff --git a/DungeonMapGenerator/DungeonMapConsolePrinter/bin/Debug/net9.0/DungeonMapConsolePrinter.dll b/DungeonMapGenerator/DungeonMapConsolePrinter/bin/Debug/net9.0/DungeonMapConsolePrinter.dll index 10ed87e8d892bc9dced203e7748069dddccc900e..ae9c7e23800a096ab4fbbcd91dcde61ac175f846 100644 GIT binary patch delta 235 zcmZqBY0#O_!NSCS?9#>_84iKqLnm)kHyv|YopouZ!J^GZn|E-;Flty>m>HWJBpDeS zSSDGdni-oInj5E>r&^eqCmI=;8yQ%dCmI_XCM8X_;gVqypTs+Hatv31z&n>YR@&BT z-fisBlQPR@@l4*s)v5p$eC-Am1gaLSbNkUR{V!y1px1_(n-jUiS^O;+EEvofj2X-s z3>cCajDRcy21_8zf*}f%o!5FVjyu#ptvc6F%X*r#S(#}F+&Ov8v$8qKoKLbXbMowWHYnl@RvJ*m2rQZc6f@cW-IR%w1prlt6U_hs diff --git a/DungeonMapGenerator/DungeonMapConsolePrinter/bin/Debug/net9.0/DungeonMapGenerator.dll b/DungeonMapGenerator/DungeonMapConsolePrinter/bin/Debug/net9.0/DungeonMapGenerator.dll index c96440939056946ff1e5c99b49bea377080686a1..89765e91a53461f50b3c35cbfa000d0a9430fdae 100644 GIT binary patch delta 4999 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 Vhk9MFTfrp_k7)H@lP%en{{n9R)R_PP delta 4986 zcmai1dwdkt6+U-fJ2U&5*-ds6NFXngg@iN-gd`A!2pC9!JP0v?AS5Q?6$lU%d36&) zc_=7hfKr=cK-vbuqAqHof>r|}YONM4YE<~)4-2ITDp3o)bL!4s zH%-?}w_S8Cyd1BdJQzG4G}d*?%ww8)buTmX^qT2trsE-6*Vf<-)5Dluayjz~r(Ql> zOb@rbe5RLQ_cJeFuU9yFh3nzHUfu{j!nCq49uKgv=`QTYa@{cquhW|*z)Qw+>O(4h zPnRpa3L$Z6fWaSJ4%t(Y`7{7hS@DTQ=I|raXiIb~o8-C|(P` z8;$WstRrfSLw5{^+qZ8k0Xwz9ZlxrFVpAGZaaQ9P3S$wxE?$y!R}%`77aQ%>lEp9t z(6vEeEOZR;&?={g52RxSFZnAQ#~Och#P`Z+Kg!*X^TY1N>g7$iyHvHwhiGrYov04* z`5N)|RT$v!2_kxeNDPesI-?Q`upr`=z&1~Rka3GBUWabi*=VF$e??=VG2Atb6c~$K z#}KpJClNXAO;QkgTT3K)6R;{d&jZ*|pwK)rz@$_rHNV1iQ|fCRorDRON_JmjSKHNzLx9T+ckwy7pqS|HwCNCz76c9morsrNyo2Fe!hTfN zuo#@r;$r*6mwMeij$_Q9;x{VAGVPdc7>wrMv;}=|0N%0r;3T2=G)K|LQ@p|S?@*WE zY2}}Y735>Y!`gl}`5e~d!Ny z%qg(mVuzG_WED0inw7O;f$V_JfXUucr^{{#HsHsZntmxSmc0;>Y_i`;zm&tF*kZfX zHFyUd7Te<7B=>=>zc4FvrQgWWaL{7Q>>Y9pl;QK5dQK8vkQ3mv#imQI%Sq6UTa@PB zSN<*!gww$xl&*!X+P~#gD8XkJvWPPV+So(<&MML zDT@tf>|2YyBhMEzVZ(6h*#g6bWUTyy#bS{SgD%F_!U^=uf|wCN*Ix_i&P=3X_{~Zu zW|A?;CNQ=ge9|N(8_rmalggD5kcMC7J$=fBoL*L?6NY$A-JEQog>C+<{=U=F3Yyr%9^ zieZt(`m1}9Ew|VV?J6mO)fStpiBJNMS}aVtN=m`7SU*L?ACB!7>#H45Cc_?!rE3R~ zJ;PXVt$YpdunbU#6F)&Fk2Xsmbe&V~hY1$rv`l0T z7Tf2(L~~p8N^h$C&xqngItHYlYw;*s08bBNjbHb}BRB zxWx`~JC$m9*J3gJPNfD;Ta3rb2jHy52v*j@MaIk}>fjqIx0pz39RU88>)EpPfV&Tm zR+tea4z(WqjGEUy3*zr6odqdYX$g4LSuoUMc4V_5*J95Tk2(j&SZoXDQRl)0i?u?u zIuFViGcT$lFJ4)w6vsF46Qq}p;dPi;nY_xK1Wxh=mMGl5b=;>H$R6h*3PhmoDo+GZ?jn?q+H)2 zOkny1wtND-iXX%TcDbim4V^WKOzy^0rC7%9z8n174Dkk=)(!pK_2M!@9}3mvE%zeS zC2^_PLNb+Degl~=trFWvg5HAJ_ucEnInY!2m@z#odfINjirxJswpaAouNBFm&j z;$G6_4wIfEAGsr?y~MA_N`$;8&KLhmCQC`E*!3*TUU271?GP=TgLZc5C1imj@ZX}_ zZsUWj_{h_efL-UgDpcIIq3oK+u&kc#4;I*D{6#$%QHDlD2SW{(U>pX^5X<0~h!xO^ zSjDn4VLisPncl$kg-l<<^me9qFntfxJ5i4TJ1VIbdZAEFg}zW0#8W&pAtu90#39gy zI08OJ91Z_MEQD)_lbJpZaWu0aqzMMvV-bhi<4G&*w&!6y%3h6FYHvZTv$v9Yxa2O3 zAF@Bi;@26TW5{zf8;obCJPTLA8vAG#S6fJxvpg+5%hQ+$G$sO#V_6)_;yf1TvACMW z)huoinqZUt3{$$q2Vk({j7S|oq8Jl2Pc}+MF`UV;nPCURR~epR2r`?-a1_IVPz?{l z70}2NZb?Kz^t^~FyTb|8^KmSzV@p1MVe;58;IKePp&BJ(sMwK{) zVy1R4VjtlyqiOiO=nY&a_XGC?uL`;_OV}vf5K6?Y;sx zKYd4Fmv{|hk&Kq?gzDEq$430ts|{Ekc7C_EJpaYViWh8dt~(G~SX9Be(`=F9o{2<{ zGSN6)GH&1?n=X6C-YLr_;q)kc#pp2{hoL86gfSskMLh94*Yuu9hmDdu1$;AYS%u$P2YDtf1UPF=4}XQzdk$p9XY6H;>R@;)jHI(Fs{Xsfl)mw8BDE3ZKz>XKgdOm2 unoccupiedPointsOnSide = new List(); var roomPoints = room.GetPointsInRoom(); + int sideOverHang = SIDE_LENGTH_OF_NORMAL / 2; int minX = roomPoints.Min(p => p.X); int maxX = roomPoints.Max(p => p.X); int minY = roomPoints.Min(p => p.Y); @@ -200,7 +201,7 @@ namespace DungeonMapGenerator switch (side) { case RoomSide.Top: - for (int x = minX - SIDE_LENGTH_OF_NORMAL; x <= maxX + SIDE_LENGTH_OF_NORMAL; x++) + for (int x = minX - sideOverHang; x <= maxX + sideOverHang; x++) { Point point = new Point(x, minY - SIDE_LENGTH_OF_NORMAL); if (unoccupiedPoints.Contains(point)) @@ -210,7 +211,7 @@ namespace DungeonMapGenerator } return unoccupiedPointsOnSide; case RoomSide.Bottom: - for (int x = minX - SIDE_LENGTH_OF_NORMAL; x <= maxX + SIDE_LENGTH_OF_NORMAL; x++) + for (int x = minX - sideOverHang; x <= maxX + sideOverHang; x++) { Point point = new Point(x, maxY + SIDE_LENGTH_OF_NORMAL); if (unoccupiedPoints.Contains(point)) @@ -221,7 +222,7 @@ namespace DungeonMapGenerator return unoccupiedPointsOnSide; case RoomSide.Left: - for (int y = minY - SIDE_LENGTH_OF_NORMAL; y <= maxY + SIDE_LENGTH_OF_NORMAL; y++) + for (int y = minY - sideOverHang; y <= maxY + sideOverHang; y++) { Point point = new Point(minX - SIDE_LENGTH_OF_NORMAL, y); if (unoccupiedPoints.Contains(point)) @@ -232,7 +233,7 @@ namespace DungeonMapGenerator return unoccupiedPointsOnSide; case RoomSide.Right: - for (int y = minY - SIDE_LENGTH_OF_NORMAL; y <= maxY + SIDE_LENGTH_OF_NORMAL; y++) + for (int y = minY - sideOverHang; y <= maxY + sideOverHang; y++) { Point point = new Point(maxX + SIDE_LENGTH_OF_NORMAL, y); if (unoccupiedPoints.Contains(point)) @@ -258,7 +259,7 @@ namespace DungeonMapGenerator : unoccupiedPointsOnSide.OrderBy(p => p.X).ToList(); // List to store possible valid room placements (top-left points of the room) - List validPlacements = new List(); + List validRooms = new List(); // Iterate over the ordered points to find potential placements for (int i = 0; i < orderedPoints.Count - sizeOfNewRoom + 1; i++) @@ -292,23 +293,22 @@ namespace DungeonMapGenerator break; } - if (!potentialPoints.Any(occupiedPoints.Contains)) + Room testRoom = new Room(type, sizeOfNewRoom, sizeOfNewRoom, adjustedPoint); + if (!testRoom.GetPointsInRoom().Any(occupiedPoints.Contains)) { - validPlacements.Add(adjustedPoint); // First point is the top-left point of the room + validRooms.Add(testRoom); // First point is the top-left point of the room } } } - // If there are valid placements, select a random one and create the room - if (validPlacements.Any()) + // If there are valid room placements, select a random one and create the room + if (validRooms.Any()) { - Point randomPlacement = validPlacements[random.Next(validPlacements.Count)]; - Room newRoom = new Room(type, sizeOfNewRoom, sizeOfNewRoom, randomPlacement); - - return newRoom; + // Pick one of the valid rooms at random + return validRooms[random.Next(validRooms.Count)]; } - // If no valid placements are found, return null or handle it as necessary + // If no valid rooms are found, return null or handle it as necessary return null; } diff --git a/DungeonMapGenerator/DungeonMapGenerator/bin/Debug/netstandard2.0/DungeonMapGenerator.dll b/DungeonMapGenerator/DungeonMapGenerator/bin/Debug/netstandard2.0/DungeonMapGenerator.dll index c96440939056946ff1e5c99b49bea377080686a1..89765e91a53461f50b3c35cbfa000d0a9430fdae 100644 GIT binary patch delta 4999 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 Vhk9MFTfrp_k7)H@lP%en{{n9R)R_PP delta 4986 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