From 529d5e95b5b5f0f6eee01447fc3e71b0fdb3970b Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Mon, 20 May 2024 22:38:41 +0800 Subject: [PATCH] =?UTF-8?q?Adjust=20the=20map=20generator.=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E5=9C=B0=E5=9B=BE=E7=94=9F=E6=88=90=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/loader/sceneLoader/GameSceneLoader.cs | 10 +-- scripts/map/MapGenerator.cs | 28 +++++-- scripts/map/MapGeneratorConfig.cs | 46 ---------- scripts/map/RoomProvider/RoomProvider.cs | 53 ------------ scripts/map/dateBean/RoomPlacementData.cs | 4 +- scripts/map/interfaces/IMapGeneratorConfig.cs | 36 -------- scripts/map/interfaces/IRoom.cs | 35 -------- scripts/map/interfaces/IRoomHolder.cs | 8 +- .../map/interfaces/IRoomPlacementStrategy.cs | 31 +++---- scripts/map/interfaces/IRoomProvider.cs | 28 ------- scripts/map/interfaces/IRoomSlotsMatcher.cs | 3 +- scripts/map/room/Room.cs | 3 +- scripts/map/room/RoomFactory.cs | 57 ++++++++++++- scripts/map/roomHolder/RoomHolder.cs | 7 +- .../PatchworkRoomPlacementStrategy.cs | 84 +++++++++++++++++-- scripts/map/slotsMatcher/RoomSlotsMatcher.cs | 3 +- 16 files changed, 191 insertions(+), 245 deletions(-) delete mode 100644 scripts/map/MapGeneratorConfig.cs delete mode 100644 scripts/map/RoomProvider/RoomProvider.cs delete mode 100644 scripts/map/interfaces/IMapGeneratorConfig.cs delete mode 100644 scripts/map/interfaces/IRoom.cs delete mode 100644 scripts/map/interfaces/IRoomProvider.cs diff --git a/scripts/loader/sceneLoader/GameSceneLoader.cs b/scripts/loader/sceneLoader/GameSceneLoader.cs index 66dd8cf..2e6e057 100644 --- a/scripts/loader/sceneLoader/GameSceneLoader.cs +++ b/scripts/loader/sceneLoader/GameSceneLoader.cs @@ -1,22 +1,15 @@ using System.Threading.Tasks; -using ColdMint.scripts.character; -using ColdMint.scripts.debug; using ColdMint.scripts.inventory; using ColdMint.scripts.map; using ColdMint.scripts.map.LayoutParsingStrategy; using ColdMint.scripts.map.layoutStrategy; -using ColdMint.scripts.map.room; -using ColdMint.scripts.map.roomHolder; using ColdMint.scripts.map.RoomPlacer; -using ColdMint.scripts.map.RoomProvider; -using ColdMint.scripts.map.slotsMatcher; using Godot; namespace ColdMint.scripts.loader.sceneLoader; public partial class GameSceneLoader : SceneLoaderTemplate { - public override Task InitializeData() { //加载血条场景 @@ -36,7 +29,10 @@ public partial class GameSceneLoader : SceneLoaderTemplate public override async Task LoadScene() { + MapGenerator.MapRoot = GetNode("MapRoot"); MapGenerator.LayoutStrategy = new TestLayoutStrategy(); MapGenerator.LayoutParsingStrategy = new SequenceLayoutParsingStrategy(); + MapGenerator.RoomPlacementStrategy = new PatchworkRoomPlacementStrategy(); + await MapGenerator.GenerateMap(); } } \ No newline at end of file diff --git a/scripts/map/MapGenerator.cs b/scripts/map/MapGenerator.cs index 1fa5497..f78599b 100644 --- a/scripts/map/MapGenerator.cs +++ b/scripts/map/MapGenerator.cs @@ -4,6 +4,8 @@ using ColdMint.scripts.debug; using ColdMint.scripts.map.interfaces; using ColdMint.scripts.map.LayoutParsingStrategy; using ColdMint.scripts.map.layoutStrategy; +using ColdMint.scripts.map.room; +using Godot; namespace ColdMint.scripts.map; @@ -23,6 +25,12 @@ public static class MapGenerator /// private static ILayoutStrategy? _layoutStrategy; + /// + /// Map root node + /// 地图根节点 + /// + private static Node? _mapRoot; + /// /// Room placement strategy /// 房间的放置策略 @@ -36,6 +44,12 @@ public static class MapGenerator /// private static ILayoutParsingStrategy? _layoutParsingStrategy; + public static Node? MapRoot + { + get => _mapRoot; + set => _mapRoot = value; + } + public static ILayoutParsingStrategy? LayoutParsingStrategy { get => _layoutParsingStrategy; @@ -60,7 +74,8 @@ public static class MapGenerator /// public static async Task GenerateMap() { - if (_layoutStrategy == null || _roomPlacementStrategy == null || _layoutParsingStrategy == null) + if (_layoutStrategy == null || _roomPlacementStrategy == null || _layoutParsingStrategy == null || + _mapRoot == null) { LogCat.LogError("map_generator_missing_parameters"); return; @@ -79,7 +94,7 @@ public static class MapGenerator _layoutParsingStrategy.SetLevelGraph(levelGraphEditorSaveData); //Save the dictionary, put the ID in the room data, corresponding to the successful placement of the room. //保存字典,将房间数据内的ID,对应放置成功的房间。 - var roomDictionary = new Dictionary(); + var roomDictionary = new Dictionary(); while (await _layoutParsingStrategy.HasNext()) { //When a new room needs to be placed @@ -91,12 +106,15 @@ public static class MapGenerator } var nextParentNodeId = await _layoutParsingStrategy.GetNextParentNodeId(); - IRoom? parentRoomNode = null; + Room? parentRoomNode = null; if (nextParentNodeId != null) { //If the new room has the parent's ID, then we pass the parent's room into the compute function. //如果新房间有父节点的ID,那么我们将父节点的房间传入到计算函数内。 - parentRoomNode = roomDictionary[nextParentNodeId]; + if (roomDictionary.TryGetValue(nextParentNodeId, out var value)) + { + parentRoomNode = value; + } } var roomPlacementData = @@ -106,7 +124,7 @@ public static class MapGenerator continue; } - if (!await _roomPlacementStrategy.PlaceRoom(roomPlacementData)) + if (!await _roomPlacementStrategy.PlaceRoom(_mapRoot, roomPlacementData)) { continue; } diff --git a/scripts/map/MapGeneratorConfig.cs b/scripts/map/MapGeneratorConfig.cs deleted file mode 100644 index e81be61..0000000 --- a/scripts/map/MapGeneratorConfig.cs +++ /dev/null @@ -1,46 +0,0 @@ -using ColdMint.scripts.debug; -using ColdMint.scripts.map.interfaces; -using Godot; - -namespace ColdMint.scripts.map; - -public class MapGeneratorConfig : IMapGeneratorConfig -{ - /// - /// At least how many rooms are generated - /// 至少生成多少个房间 - /// - public const int MinRoomCount = 15; - - /// - /// Maximum number of rooms generated - /// 最多生成多少个房间 - /// - public const int MaxRoomCount = 30; - - - public const int MinBranchCount = 3; - - public const int MaxBranchCount = 5; - - private int _roomCount; - private int _branchCount; - - public MapGeneratorConfig(Node2D mapRoot, ulong seed) - { - MapRoot = mapRoot; - Seed = seed; - RandomNumberGenerator = new RandomNumberGenerator(); - RandomNumberGenerator.Seed = seed; - _roomCount = RandomNumberGenerator.RandiRange(MinRoomCount, MaxRoomCount); - _branchCount = RandomNumberGenerator.RandiRange(MinBranchCount, MaxBranchCount); - LogCat.Log("Seed:" + seed + " RoomCount:" + _roomCount); - } - - public Node2D MapRoot { get; } - public int RoomCount => _roomCount; - public int BranchCount => _branchCount; - - public ulong Seed { get; } - public RandomNumberGenerator RandomNumberGenerator { get; } -} \ No newline at end of file diff --git a/scripts/map/RoomProvider/RoomProvider.cs b/scripts/map/RoomProvider/RoomProvider.cs deleted file mode 100644 index 706ccba..0000000 --- a/scripts/map/RoomProvider/RoomProvider.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using ColdMint.scripts.map.interfaces; -using ColdMint.scripts.map.room; - -namespace ColdMint.scripts.map.RoomProvider; - -public class RoomProvider : IRoomProvider -{ - private List _roomTemplates; - - public RoomProvider() - { - _roomTemplates = new List(); - } - - /// - /// AddRoom - /// 添加房间 - /// - /// - ///If the initial room is not set, the first room added will be automatically set as the initial room - ///若未设置初始房间,那么第一次添加的房间将被自动设置为初始房间 - /// - /// - public void AddRoom(RoomTemplate roomTemplate) - { - if (InitialRoom == null) - { - InitialRoom = roomTemplate; - return; - } - - _roomTemplates.Add(roomTemplate); - } - - - public IRoomTemplate? InitialRoom { get; set; } - - public IRoomTemplate GetRoomRes(int index, IMapGeneratorConfig config) - { - var indexInList = config.RandomNumberGenerator.RandiRange(0, _roomTemplates.Count - 1); - IRoomTemplate result = _roomTemplates[indexInList]; - - //添加一次使用次数,当模板不能再次使用时,从列表内移除。 - result.AddUsedNumber(); - if (!result.CanUse) - { - _roomTemplates.RemoveAt(indexInList); - } - - return result; - } -} \ No newline at end of file diff --git a/scripts/map/dateBean/RoomPlacementData.cs b/scripts/map/dateBean/RoomPlacementData.cs index 60b1040..3895d16 100644 --- a/scripts/map/dateBean/RoomPlacementData.cs +++ b/scripts/map/dateBean/RoomPlacementData.cs @@ -1,4 +1,4 @@ -using ColdMint.scripts.map.interfaces; +using ColdMint.scripts.map.room; using Godot; namespace ColdMint.scripts.map.dateBean; @@ -18,5 +18,5 @@ public class RoomPlacementData /// Place the room template /// 放置的房间模板 /// - public IRoom? Room { get; set; } + public Room? Room { get; set; } } \ No newline at end of file diff --git a/scripts/map/interfaces/IMapGeneratorConfig.cs b/scripts/map/interfaces/IMapGeneratorConfig.cs deleted file mode 100644 index 6444f97..0000000 --- a/scripts/map/interfaces/IMapGeneratorConfig.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Godot; - -namespace ColdMint.scripts.map.interfaces; - -/// -/// IMapGeneratorConfig -/// 房间生成器配置 -/// -public interface IMapGeneratorConfig -{ - Node2D MapRoot { get; } - - /// - /// How many rooms do we need to generate - /// 我们需要生成多少个房间 - /// - int RoomCount { get; } - - /// - /// The number of forks in this map - /// 这个地图的分叉数量 - /// - int BranchCount { get; } - - /// - /// seed - /// 种子 - /// - ulong Seed { get; } - - /// - /// RandomNumberGenerator - /// 随机数生成器 - /// - RandomNumberGenerator RandomNumberGenerator { get; } -} \ No newline at end of file diff --git a/scripts/map/interfaces/IRoom.cs b/scripts/map/interfaces/IRoom.cs deleted file mode 100644 index ac10671..0000000 --- a/scripts/map/interfaces/IRoom.cs +++ /dev/null @@ -1,35 +0,0 @@ -using ColdMint.scripts.map.dateBean; -using Godot; - -namespace ColdMint.scripts.map.interfaces; - -/// -/// IRoom -/// 表示房间 -/// -public interface IRoom -{ - /// - /// Set room scene - /// 设置房间场景 - /// - PackedScene? RoomScene { get; set; } - - /// - /// Tile map - /// 瓦片地图 - /// - TileMap? TileMap { get; set; } - - /// - /// Gets the root node of the room - /// 获取房间的根节点 - /// - Node2D? RootNode { get; } - - /// - /// The room holds the corresponding slot data - /// 房间持有对应的插槽数据 - /// - RoomSlot?[]? RoomSlots { get; } -} \ No newline at end of file diff --git a/scripts/map/interfaces/IRoomHolder.cs b/scripts/map/interfaces/IRoomHolder.cs index 1185876..d0e86a1 100644 --- a/scripts/map/interfaces/IRoomHolder.cs +++ b/scripts/map/interfaces/IRoomHolder.cs @@ -1,4 +1,6 @@ -namespace ColdMint.scripts.map.interfaces; +using ColdMint.scripts.map.room; + +namespace ColdMint.scripts.map.interfaces; /// /// Room holder @@ -10,13 +12,13 @@ /// public interface IRoomHolder { - bool AddRoom(IRoom room); + bool AddRoom(Room room); /// /// LastRoom /// 最后添加的房间 /// - IRoom? LastRoom { get; } + Room? LastRoom { get; } /// /// Number of rooms that have been placed diff --git a/scripts/map/interfaces/IRoomPlacementStrategy.cs b/scripts/map/interfaces/IRoomPlacementStrategy.cs index e90ad20..4b48d53 100644 --- a/scripts/map/interfaces/IRoomPlacementStrategy.cs +++ b/scripts/map/interfaces/IRoomPlacementStrategy.cs @@ -1,6 +1,8 @@ using System.Threading.Tasks; using ColdMint.scripts.levelGraphEditor; using ColdMint.scripts.map.dateBean; +using ColdMint.scripts.map.room; +using Godot; namespace ColdMint.scripts.map.interfaces; @@ -10,19 +12,20 @@ namespace ColdMint.scripts.map.interfaces; /// public interface IRoomPlacementStrategy { - /// - /// Place the room in the designated location - /// 在指定的位置放置房间 - /// - /// - ///Room placement information - ///房间放置信息 - /// - /// - ///Placement success or not - ///是否放置成功 - /// - public Task PlaceRoom(RoomPlacementData roomPlacementData); + /// + /// Place the room in the designated location + /// 在指定的位置放置房间 + /// + /// + /// + /// Room placement information + /// 房间放置信息 + /// + /// + /// Placement success or not + /// 是否放置成功 + /// + public Task PlaceRoom(Node mapRoot, RoomPlacementData roomPlacementData); /// /// Calculate new room placement information @@ -37,5 +40,5 @@ public interface IRoomPlacementStrategy ///欲放置的新房间数据 /// /// - public Task CalculateNewRoomPlacementData(IRoom? parentRoomNode, RoomNodeData newRoomNodeData); + public Task CalculateNewRoomPlacementData(Room? parentRoomNode, RoomNodeData newRoomNodeData); } \ No newline at end of file diff --git a/scripts/map/interfaces/IRoomProvider.cs b/scripts/map/interfaces/IRoomProvider.cs deleted file mode 100644 index ec2b8f9..0000000 --- a/scripts/map/interfaces/IRoomProvider.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace ColdMint.scripts.map.interfaces; - -/// -/// Room provider -/// 房间提供者 -/// -/// -///Responsible for providing room templates for map generator. -///负责为地图生成器提供房间模板。 -/// -public interface IRoomProvider -{ - /// - /// Initial room - /// 初始房间 - /// - IRoomTemplate? InitialRoom { get; set; } - - - /// - /// Acquire room assets - /// 获取房间资产 - /// - /// - /// - /// - IRoomTemplate? GetRoomRes(int index, IMapGeneratorConfig config); -} \ No newline at end of file diff --git a/scripts/map/interfaces/IRoomSlotsMatcher.cs b/scripts/map/interfaces/IRoomSlotsMatcher.cs index 91d550a..29b0140 100644 --- a/scripts/map/interfaces/IRoomSlotsMatcher.cs +++ b/scripts/map/interfaces/IRoomSlotsMatcher.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using ColdMint.scripts.map.dateBean; +using ColdMint.scripts.map.room; namespace ColdMint.scripts.map.interfaces; @@ -16,7 +17,7 @@ public interface IRoomSlotsMatcher /// /// /// - Task IsMatch(IRoom? mainRoom, IRoom newRoom); + Task IsMatch(Room? mainRoom, Room newRoom); /// diff --git a/scripts/map/room/Room.cs b/scripts/map/room/Room.cs index dd1f5e7..445d716 100644 --- a/scripts/map/room/Room.cs +++ b/scripts/map/room/Room.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using ColdMint.scripts.debug; using ColdMint.scripts.map.dateBean; -using ColdMint.scripts.map.interfaces; using ColdMint.scripts.utils; using Godot; @@ -16,7 +15,7 @@ namespace ColdMint.scripts.map.room; ///The room template is like a jigsaw puzzle and participates in the map building process. ///房间模板就像一个拼图,参与到地图的构建过程中。 /// -public class Room : IRoom +public class Room { private Node2D? _rootNode; private RoomSlot?[]? _roomSlots; diff --git a/scripts/map/room/RoomFactory.cs b/scripts/map/room/RoomFactory.cs index ac7bd83..8a47653 100644 --- a/scripts/map/room/RoomFactory.cs +++ b/scripts/map/room/RoomFactory.cs @@ -1,4 +1,4 @@ -using ColdMint.scripts.map.interfaces; +using System.Collections.Generic; using Godot; namespace ColdMint.scripts.map.room; @@ -9,14 +9,67 @@ namespace ColdMint.scripts.map.room; /// public static class RoomFactory { + /// + /// A room template sets a path to a room resource + /// 房间模板集转房间资源路径 + /// + /// + /// + /// Returned value Checked for the existence of the file. + /// 返回值已检验文件是否存在。 + /// + public static string[] RoomTemplateSetToRoomRes(string[] roomTemplateSet) + { + var resList = new List(); + foreach (var roomTemplate in roomTemplateSet) + { + //Detects whether it is a folder + //检测是否为文件夹 + if (DirAccess.DirExistsAbsolute(roomTemplate)) + { + using var dir = DirAccess.Open(roomTemplate); + if (dir != null) + { + dir.ListDirBegin(); + var fileName = dir.GetNext(); + while (!string.IsNullOrEmpty(fileName)) + { + if (!dir.CurrentIsDir()) + { + resList.Add(fileName); + } + + fileName = dir.GetNext(); + } + } + } + + if (FileAccess.FileExists(roomTemplate)) + { + resList.Add(roomTemplate); + } + } + + return resList.ToArray(); + } + + /// /// CreateRoom /// 创建房间模板 /// /// /// - public static IRoom CreateRoom(string resPath) + public static Room? CreateRoom(string resPath) { + //If the file does not exist, null is returned + //如果文件不存在,则返回null + var exists = FileAccess.FileExists(resPath); + if (!exists) + { + return null; + } + var room = new Room { RoomScene = GD.Load(resPath) diff --git a/scripts/map/roomHolder/RoomHolder.cs b/scripts/map/roomHolder/RoomHolder.cs index 4b6a665..aba133e 100644 --- a/scripts/map/roomHolder/RoomHolder.cs +++ b/scripts/map/roomHolder/RoomHolder.cs @@ -1,19 +1,20 @@ using System.Collections.Generic; using ColdMint.scripts.map.interfaces; +using ColdMint.scripts.map.room; namespace ColdMint.scripts.map.roomHolder; public class RoomHolder : IRoomHolder { - private readonly List _rooms = new List(); + private readonly List _rooms = new List(); - public bool AddRoom(IRoom room) + public bool AddRoom(Room room) { _rooms.Add(room); return true; } - public IRoom? LastRoom + public Room? LastRoom { get { diff --git a/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs b/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs index 9e91a2b..502beb6 100644 --- a/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs +++ b/scripts/map/roomPlacer/PatchworkRoomPlacementStrategy.cs @@ -2,6 +2,7 @@ using ColdMint.scripts.levelGraphEditor; using ColdMint.scripts.map.dateBean; using ColdMint.scripts.map.interfaces; +using ColdMint.scripts.map.room; using Godot; namespace ColdMint.scripts.map.RoomPlacer; @@ -16,19 +17,88 @@ namespace ColdMint.scripts.map.RoomPlacer; /// public class PatchworkRoomPlacementStrategy : IRoomPlacementStrategy { - public Task PlaceRoom(RoomPlacementData roomPlacementData) + private readonly Vector2 _halfCell = new Vector2(Config.CellSize / 2f, Config.CellSize / 2f); + + public Task PlaceRoom(Node mapRoot, RoomPlacementData roomPlacementData) { - throw new System.NotImplementedException(); + if (roomPlacementData.Room == null || roomPlacementData.Position == null) + { + return Task.FromResult(false); + } + + if (roomPlacementData.Room.RootNode == null) + { + return Task.FromResult(false); + } + + var rootNode = roomPlacementData.Room.RootNode; + rootNode.Reparent(mapRoot); + rootNode.Position = roomPlacementData.Position.Value; + return Task.FromResult(true); } - public Task GetStartRoomPlacementData(RoomNodeData startRoomNodeData) + public Task CalculateNewRoomPlacementData(Room? parentRoomNode, RoomNodeData newRoomNodeData) { - throw new System.NotImplementedException(); + if (newRoomNodeData.RoomTemplateSet == null || newRoomNodeData.RoomTemplateSet.Length == 0) + { + return Task.FromResult(null); + } + + var roomResArray = RoomFactory.RoomTemplateSetToRoomRes(newRoomNodeData.RoomTemplateSet); + if (parentRoomNode == null) + { + //No parent node is set, which we think is the starting room. + //没有设置父节点,我们认为是起点房间。 + //TODO:在这里兼容世界种子。 + var roomPlacementData = new RoomPlacementData + { + Room = RoomFactory.CreateRoom(roomResArray[0]), + Position = Vector2.Zero + }; + return Task.FromResult(roomPlacementData); + } + else + { + //TODO:在这里实现房间的放置策略。 + return Task.FromResult(null); + } } - - public Task CalculateNewRoomPlacementData(IRoom parentRoomNode, RoomNodeData newRoomNodeData) + private Task CalculatedPosition(Room mainRoom, Room newRoom, RoomSlot? mainRoomSlot, + RoomSlot? newRoomSlot,bool roomSlotOverlap) { - throw new System.NotImplementedException(); + if (mainRoom.RootNode == null || mainRoom.TileMap == null || newRoom.TileMap == null || mainRoomSlot == null || + newRoomSlot == null) + { + return Task.FromResult(null); + } + + //计算主插槽中点在世界中的位置。 + //mainRoom.RootNode.Position意为房间所在的世界位置 + //mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition)意为主插槽在房间中的位置 + var result = mainRoom.RootNode.Position + mainRoom.TileMap.MapToLocal(mainRoomSlot.StartPosition); + if (roomSlotOverlap) + { + //执行减法,从槽中点偏移到左上角 + result -= _halfCell; + } + else + { + //执行减法,从槽中点偏移到右下角 + result += _halfCell; + } + //我们不能将新房间的原点设置在主房间槽的左上角或右下角,这会导致插槽不对应。 + + //竖直槽,我们需要在同一水平上。 + if (mainRoomSlot.IsHorizontal) + { + result += newRoom.TileMap.MapToLocal(new Vector2I(newRoomSlot.EndPosition.X, 0)) - _halfCell; + } + else + { + result -= newRoom.TileMap.MapToLocal(new Vector2I(0, newRoomSlot.EndPosition.Y)) - _halfCell; + } + + return Task.FromResult(result); } } \ No newline at end of file diff --git a/scripts/map/slotsMatcher/RoomSlotsMatcher.cs b/scripts/map/slotsMatcher/RoomSlotsMatcher.cs index 9f7406d..910165d 100644 --- a/scripts/map/slotsMatcher/RoomSlotsMatcher.cs +++ b/scripts/map/slotsMatcher/RoomSlotsMatcher.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using ColdMint.scripts.map.dateBean; using ColdMint.scripts.map.interfaces; +using ColdMint.scripts.map.room; namespace ColdMint.scripts.map.slotsMatcher; @@ -9,7 +10,7 @@ public class RoomSlotsMatcher : IRoomSlotsMatcher private RoomSlot? _lastMatchedMainSlot; private RoomSlot? _lastMatchedMinorSlot; - public Task IsMatch(IRoom? mainRoom, IRoom newRoom) + public Task IsMatch(Room? mainRoom, Room newRoom) { if (mainRoom == null) {