using System.Text.Json.Serialization; using SptCommon.Annotations; namespace Core.Helpers; [Injectable] public class ContainerHelper { /// /// Finds a slot for an item in a given 2D container map /// /// List of container with slots filled/free /// Width of item /// Height of item /// Location to place item in container public FindSlotResult FindSlotForItem(int[][] container2D, int itemWidth, int itemHeight) { var rotation = false; var minVolume = (itemWidth < itemHeight ? itemWidth : itemHeight) - 1; var containerY = container2D.Length; var containerX = container2D[0].Length; var limitY = containerY - minVolume; var limitX = containerX - minVolume; // Every x+y slot taken up in container, exit if (container2D.All((x) => x.All((y) =>y == 1))) { return new FindSlotResult(false); } // Down for (var y = 0; y < limitY; y++) { // Across if (container2D[y].All((x) => x == 1)) { // Every item in row is full, skip row continue; } for (var x = 0; x < limitX; x++) { var foundSlot = LocateSlot(container2D, containerX, containerY, x, y, itemWidth, itemHeight); // Failed to find slot, rotate item and try again if (!foundSlot && itemWidth * itemHeight > 1) { // Bigger than 1x1 foundSlot = LocateSlot(container2D, containerX, containerY, x, y, itemHeight, itemWidth); // Height/Width swapped if (foundSlot) { // Found a slot for it when rotated rotation = true; } } if (!foundSlot) { // Didn't fit this hole, try again continue; } return new FindSlotResult(true, x, y, rotation); } } // Tried all possible holes, nothing big enough for the item return new FindSlotResult(false); } /// /// Find a slot inside a container an item can be placed in /// /// Container to find space in /// Container x size /// Container y size /// ??? /// ??? /// Items width /// Items height /// True - slot found protected bool LocateSlot( int[][] container2D, int containerX, int containerY, int x, int y, int itemW, int itemH) { throw new NotImplementedException(); } /// /// Find a free slot for an item to be placed at /// /// Container to place item in /// Container x size /// Container y size /// Items width /// Items height /// is item rotated public void FillContainerMapWithItem( int[][] container2D, int x, int y, int itemW, int itemH, bool rotate) { throw new NotImplementedException(); } } public class FindSlotResult { public FindSlotResult(bool success) { Success = success; } public FindSlotResult(bool success, int x, int y, bool rotation) { Success = success; X = x; Y = y; Rotation = rotation; } public FindSlotResult() { } [JsonPropertyName("success")] public bool? Success { get; set; } [JsonPropertyName("x")] public int? X { get; set; } [JsonPropertyName("y")] public int? Y { get; set; } [JsonPropertyName("rotation")] public bool? Rotation { get; set; } }