diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ContainerExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ContainerExtensions.cs
index 47fd23e2..7ef4183d 100644
--- a/Libraries/SPTarkov.Server.Core/Extensions/ContainerExtensions.cs
+++ b/Libraries/SPTarkov.Server.Core/Extensions/ContainerExtensions.cs
@@ -48,8 +48,8 @@ namespace SPTarkov.Server.Core.Extensions
if (
CanItemBePlacedInContainerAtPosition(
container2D,
- column,
row,
+ column,
itemWidthX.Value,
itemHeightY.Value
)
@@ -69,8 +69,8 @@ namespace SPTarkov.Server.Core.Extensions
if (
CanItemBePlacedInContainerAtPosition(
container2D,
- column,
row,
+ column,
itemHeightY.Value, // Swapped
itemWidthX.Value // Swapped
)
@@ -112,12 +112,21 @@ namespace SPTarkov.Server.Core.Extensions
var itemWidth = isRotated ? itemYHeight : itemXWidth;
var itemHeight = isRotated ? itemXWidth : itemYHeight;
- var itemRowEndPosition = rowStartPositionY + itemHeight;
- var itemColumnEndPosition = columnStartPositionX + itemWidth;
+ var itemRowEndPosition = rowStartPositionY + (itemHeight - 1);
+ var itemColumnEndPosition = columnStartPositionX + (itemWidth - 1);
- for (var y = rowStartPositionY; y < itemRowEndPosition; y++)
+ //Item is a 1x1, flag slot as taken and exit early
+ if (itemXWidth == 1 && itemYHeight == 1)
{
- for (var x = columnStartPositionX; x < itemColumnEndPosition; x++)
+ container2D[rowStartPositionY, columnStartPositionX] = 1;
+
+ return;
+ }
+
+ // Loop over rows and columns and flag each as taken by item
+ for (var y = rowStartPositionY; y <= itemRowEndPosition; y++)
+ {
+ for (var x = columnStartPositionX; x <= itemColumnEndPosition; x++)
{
if (container2D[y, x] == 0)
{
@@ -127,7 +136,7 @@ namespace SPTarkov.Server.Core.Extensions
else
{
throw new Exception(
- $"Slot at({containerX}, {containerY}) is already filled. Cannot fit a {itemXWidth} by {itemYHeight} item"
+ $"Slot at: ({containerX}, {containerY}) is already filled. Cannot fit: {itemXWidth} by {itemYHeight} item"
);
}
}
@@ -200,45 +209,49 @@ namespace SPTarkov.Server.Core.Extensions
/// Can an item of specified size be placed inside a 2d container at a specific position
///
/// Container to find space in
- /// Starting x position for item
- /// Starting y position for item
- /// Items width
- /// Items height
+ /// Starting y position for item
+ /// Starting x position for item
+ /// Items width (y)
+ /// Items height (x)
/// True - slot found
public static bool CanItemBePlacedInContainerAtPosition(
this int[,] container,
- int startXPos,
- int startYPos,
- int itemXWidth,
- int itemYHeight
+ int itemStartVerticalPos,
+ int itemStartHorizontalPos,
+ int itemWidth,
+ int itemHeight
)
{
- var containerHeight = container.GetLength(1); // Rows
- var containerWidth = container.GetLength(0); // Columns
+ var containerHeight = container.GetLength(0); // Rows
+ var containerWidth = container.GetLength(1); // Columns
+
+ var itemEndColPosition = itemStartHorizontalPos + itemWidth - 1;
+ var itemEndRowPosition = itemStartVerticalPos + itemHeight - 1;
// Check item isn't bigger than container when at position
- if (
- startXPos + itemXWidth > containerWidth
- || startYPos + itemYHeight > containerHeight
- )
+ if (itemEndColPosition > containerWidth - 1 || itemEndRowPosition > containerHeight - 1)
{
// Item is bigger than container, will never fit
return false;
}
- // Single slot item, do direct check
- if (itemXWidth == 1 && itemYHeight == 1)
+ // Early exit if exact spot is taken
+ if (container[itemStartVerticalPos, itemStartHorizontalPos] == 1)
{
- return container[startXPos, startYPos] == 0;
+ return false;
}
- var itemEndColPosition = startXPos + itemXWidth;
- var itemEndRowPosition = startYPos + itemYHeight;
- for (var y = startYPos; y < itemEndColPosition; y++)
+ // Single slot item, do direct check
+ if (itemWidth == 1 && itemHeight == 1)
{
- for (var x = startXPos; x < itemEndRowPosition; x++)
+ return container[itemStartVerticalPos, itemStartHorizontalPos] == 0;
+ }
+
+ for (var row = itemStartVerticalPos; row <= itemEndRowPosition; row++)
+ {
+ for (var column = itemStartHorizontalPos; column <= itemEndColPosition; column++)
{
- if (container[y, x] == 1)
+ if (container[row, column] == 1)
{
// Occupied by something
return false;
diff --git a/UnitTests/Tests/Extensions/ContainerExtensionsTests.cs b/UnitTests/Tests/Extensions/ContainerExtensionsTests.cs
index 460d3509..97707962 100644
--- a/UnitTests/Tests/Extensions/ContainerExtensionsTests.cs
+++ b/UnitTests/Tests/Extensions/ContainerExtensionsTests.cs
@@ -50,7 +50,7 @@ public partial class ContainerExtensionsTests
[TestMethod]
public void CanItemBePlacedInContainerAtPosition_1x2_Item_Fits_1x2_Container_At_0x0()
{
- var container = new int[1, 2];
+ var container = new int[2, 1];
var itemStartXPos = 0;
var itemStartYPos = 0;
var itemWidth = 1;
@@ -109,8 +109,8 @@ public partial class ContainerExtensionsTests
public void CanItemBePlacedInContainerAtPosition_1x2_Item_Fits_2x2_Container_At_0x1()
{
var container = new int[2, 2];
- var itemStartXPos = 1;
- var itemStartYPos = 0;
+ var itemStartXPos = 0;
+ var itemStartYPos = 1;
var itemWidth = 1;
var itemHeight = 2;
@@ -142,6 +142,31 @@ public partial class ContainerExtensionsTests
Assert.AreEqual(result.Y, 0);
}
+ [TestMethod]
+ public void FindSlotForItem_1x2_item_fits_3x3_container_rotated_with_items()
+ {
+ /// |1|1|1|
+ /// |1|0|0|
+ /// |1|1|1|
+ var container = new int[3, 3];
+ container[0, 0] = 1;
+ container[0, 1] = 1;
+ container[0, 2] = 1;
+ container[1, 0] = 1;
+ container[2, 0] = 1;
+ container[2, 1] = 1;
+ container[2, 2] = 1;
+ var itemWidth = 1;
+ var itemHeight = 2;
+
+ var result = container.FindSlotForItem(itemWidth, itemHeight);
+
+ Assert.IsTrue(result.Success);
+ Assert.IsTrue(result.Rotation);
+ Assert.AreEqual(result.X, 1);
+ Assert.AreEqual(result.Y, 1);
+ }
+
[TestMethod]
public void FindSlotForItem_1x1_item_fails_1x1_container_no_space()
{
@@ -158,7 +183,7 @@ public partial class ContainerExtensionsTests
[TestMethod]
public void FindSlotForItem_1x2_item_fits_1x2_container_no_rotation()
{
- var container = new int[1, 2];
+ var container = new int[2, 1];
var itemWidth = 1;
var itemHeight = 2;