|
|
|
|
@@ -36,29 +36,20 @@ static Port eastPort(QPoint tile)
|
|
|
|
|
// Placement
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
TEST_CASE("BeltSystem: tryPutItem succeeds on registered belt with matching direction", "[belt]")
|
|
|
|
|
TEST_CASE("BeltSystem: tryPutItem succeeds on registered belt", "[belt]")
|
|
|
|
|
{
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
|
|
|
|
|
REQUIRE(bs.tryPutItem(eastPort(tile), makeItem("iron_ore")));
|
|
|
|
|
REQUIRE(bs.tryPutItem(tile, makeItem("iron_ore")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("BeltSystem: tryPutItem fails on unregistered tile", "[belt]")
|
|
|
|
|
{
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(eastPort(QPoint(0, 0)), makeItem("iron_ore")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("BeltSystem: tryPutItem fails on direction mismatch", "[belt]")
|
|
|
|
|
{
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::North);
|
|
|
|
|
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(eastPort(tile), makeItem("iron_ore")));
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(QPoint(0, 0), makeItem("iron_ore")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("BeltSystem: tryPutItem fails after removeTile", "[belt]")
|
|
|
|
|
@@ -68,7 +59,7 @@ TEST_CASE("BeltSystem: tryPutItem fails after removeTile", "[belt]")
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.removeTile(tile);
|
|
|
|
|
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(eastPort(tile), makeItem("iron_ore")));
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(tile, makeItem("iron_ore")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
@@ -81,8 +72,8 @@ TEST_CASE("BeltSystem: two items fit in one tile", "[belt]")
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
|
|
|
|
|
REQUIRE(bs.tryPutItem(eastPort(tile), makeItem("iron_ore")));
|
|
|
|
|
REQUIRE(bs.tryPutItem(eastPort(tile), makeItem("copper_ore")));
|
|
|
|
|
REQUIRE(bs.tryPutItem(tile, makeItem("iron_ore")));
|
|
|
|
|
REQUIRE(bs.tryPutItem(tile, makeItem("copper_ore")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("BeltSystem: third tryPutItem on full tile returns false", "[belt]")
|
|
|
|
|
@@ -91,10 +82,10 @@ TEST_CASE("BeltSystem: third tryPutItem on full tile returns false", "[belt]")
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("a"));
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("b"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("a"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("b"));
|
|
|
|
|
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(eastPort(tile), makeItem("c")));
|
|
|
|
|
REQUIRE_FALSE(bs.tryPutItem(tile, makeItem("c")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
@@ -106,7 +97,7 @@ TEST_CASE("BeltSystem: tryTakeItem returns placed item after reaching output edg
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("iron_ore"));
|
|
|
|
|
bs.tick(); // advance to output edge
|
|
|
|
|
|
|
|
|
|
const std::optional<Item> taken = bs.tryTakeItem(eastPort(tile));
|
|
|
|
|
@@ -120,7 +111,7 @@ TEST_CASE("BeltSystem: tryTakeItem requires item to reach output edge before yie
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("iron_ore"));
|
|
|
|
|
|
|
|
|
|
// Item placed but not yet at output edge — must not be available.
|
|
|
|
|
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tile)).has_value());
|
|
|
|
|
@@ -136,8 +127,8 @@ TEST_CASE("BeltSystem: tryTakeItem with two items returns both after each reache
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("first"));
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("second"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("first"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("second"));
|
|
|
|
|
|
|
|
|
|
// Front item reaches output edge after one tick.
|
|
|
|
|
bs.tick();
|
|
|
|
|
@@ -160,16 +151,6 @@ TEST_CASE("BeltSystem: tryTakeItem returns nullopt on empty tile", "[belt]")
|
|
|
|
|
REQUIRE_FALSE(bs.tryTakeItem(eastPort(QPoint(0, 0))).has_value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("BeltSystem: tryTakeItem returns nullopt on direction mismatch", "[belt]")
|
|
|
|
|
{
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::North);
|
|
|
|
|
bs.tryPutItem(Port{tile, Rotation::North}, makeItem("x"));
|
|
|
|
|
|
|
|
|
|
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tile)).has_value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// tick() — item advancement
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
@@ -182,7 +163,7 @@ TEST_CASE("BeltSystem: item transfers from tile A to tile B and becomes availabl
|
|
|
|
|
bs.placeBelt(tileA, Rotation::East);
|
|
|
|
|
bs.placeBelt(tileB, Rotation::East);
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tileA), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tileA, makeItem("iron_ore"));
|
|
|
|
|
bs.tick(); // item reaches output edge of A, moves to B at progress 0
|
|
|
|
|
bs.tick(); // item reaches output edge of B
|
|
|
|
|
|
|
|
|
|
@@ -198,7 +179,7 @@ TEST_CASE("BeltSystem: item stays at progress 1.0 when next tile is absent", "[b
|
|
|
|
|
const QPoint tileA(0, 0);
|
|
|
|
|
bs.placeBelt(tileA, Rotation::East);
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tileA), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tileA, makeItem("iron_ore"));
|
|
|
|
|
bs.tick();
|
|
|
|
|
|
|
|
|
|
// Item should still be on tileA (no registered tile to the east).
|
|
|
|
|
@@ -215,7 +196,7 @@ TEST_CASE("BeltSystem: item traverses 3-tile chain in 3 ticks (one per tile)", "
|
|
|
|
|
bs.placeBelt(tileB, Rotation::East);
|
|
|
|
|
bs.placeBelt(tileC, Rotation::East);
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tileA), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tileA, makeItem("iron_ore"));
|
|
|
|
|
bs.tick(); // A output edge → moves to B at progress 0
|
|
|
|
|
bs.tick(); // B output edge → moves to C at progress 0
|
|
|
|
|
bs.tick(); // C output edge → available for pickup
|
|
|
|
|
@@ -234,11 +215,11 @@ TEST_CASE("BeltSystem: item stays blocked when next tile is full", "[belt]")
|
|
|
|
|
bs.placeBelt(tileB, Rotation::East);
|
|
|
|
|
|
|
|
|
|
// Fill tileB to capacity.
|
|
|
|
|
bs.tryPutItem(eastPort(tileB), makeItem("b1"));
|
|
|
|
|
bs.tryPutItem(eastPort(tileB), makeItem("b2"));
|
|
|
|
|
bs.tryPutItem(tileB, makeItem("b1"));
|
|
|
|
|
bs.tryPutItem(tileB, makeItem("b2"));
|
|
|
|
|
|
|
|
|
|
// Place item in tileA — should be blocked.
|
|
|
|
|
bs.tryPutItem(eastPort(tileA), makeItem("a1"));
|
|
|
|
|
bs.tryPutItem(tileA, makeItem("a1"));
|
|
|
|
|
bs.tick();
|
|
|
|
|
|
|
|
|
|
// Item in tileA must still be there.
|
|
|
|
|
@@ -254,8 +235,8 @@ TEST_CASE("BeltSystem: clearTiles removes all items from specified tiles", "[bel
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("copper_ore"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("copper_ore"));
|
|
|
|
|
|
|
|
|
|
bs.clearTiles({tile});
|
|
|
|
|
|
|
|
|
|
@@ -271,7 +252,7 @@ TEST_CASE("BeltSystem: forEachVisualItem visits items inside viewport", "[belt]"
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(5, 5);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("iron_ore"));
|
|
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
bs.forEachVisualItem(QRect(0, 0, 20, 20), [&count](VisualItem) { ++count; });
|
|
|
|
|
@@ -284,7 +265,7 @@ TEST_CASE("BeltSystem: forEachVisualItem skips items outside viewport", "[belt]"
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(50, 50);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("iron_ore"));
|
|
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
bs.forEachVisualItem(QRect(0, 0, 20, 20), [&count](VisualItem) { ++count; });
|
|
|
|
|
@@ -297,7 +278,7 @@ TEST_CASE("BeltSystem: forEachVisualItem reports correct ItemType", "[belt]")
|
|
|
|
|
BeltSystem bs(kFastBeltSpeed);
|
|
|
|
|
const QPoint tile(0, 0);
|
|
|
|
|
bs.placeBelt(tile, Rotation::East);
|
|
|
|
|
bs.tryPutItem(eastPort(tile), makeItem("copper_ingot"));
|
|
|
|
|
bs.tryPutItem(tile, makeItem("copper_ingot"));
|
|
|
|
|
|
|
|
|
|
std::vector<ItemType> seen;
|
|
|
|
|
bs.forEachVisualItem(QRect(-1, -1, 10, 10), [&seen](VisualItem vi)
|
|
|
|
|
@@ -329,10 +310,10 @@ TEST_CASE("BeltSystem: splitter alternates between outputA and outputB", "[belt]
|
|
|
|
|
bs.placeBelt(tileA, Rotation::North);
|
|
|
|
|
bs.placeBelt(tileB, Rotation::South);
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tileIn), makeItem("item1"));
|
|
|
|
|
bs.tryPutItem(tileIn, makeItem("item1"));
|
|
|
|
|
bs.tick(); // item moves: tileIn -> splitter held
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tileIn), makeItem("item2"));
|
|
|
|
|
bs.tryPutItem(tileIn, makeItem("item2"));
|
|
|
|
|
bs.tick(); // item1 routes to outputA (North=tileA); item2 moves to splitter
|
|
|
|
|
|
|
|
|
|
bs.tick(); // item2 routes to outputB (South=tileB)
|
|
|
|
|
@@ -366,7 +347,7 @@ TEST_CASE("BeltSystem: splitter routes filtered item to matching output", "[belt
|
|
|
|
|
// Filter: outputA = iron_ore only; outputB = accept all.
|
|
|
|
|
bs.setSplitterFilters(tileSpl, {ItemType{"iron_ore"}}, {});
|
|
|
|
|
|
|
|
|
|
bs.tryPutItem(eastPort(tileIn), makeItem("iron_ore"));
|
|
|
|
|
bs.tryPutItem(tileIn, makeItem("iron_ore"));
|
|
|
|
|
bs.tick(); // tileIn -> splitter held
|
|
|
|
|
bs.tick(); // routed to outputA (filter match)
|
|
|
|
|
|
|
|
|
|
|