Bogatyri.Settlement.Placement (без Unity): сетка, зоны по Ратуше, река/скалы/деревья/валуны, отступ, уклон и фундамент, поворот 0/90/180/270, атомарный перенос с тем же id, расчистка один раз; 7 тестов. Сцена City3D (Tools -> Bogatyri -> 3D-город): местность, призрак, перенос, расчистка, камера 2.5D, второй рендерер URP (3D) только для её камеры -- 2D-сцены не тронуты. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
122 lines
6.5 KiB
C#
122 lines
6.5 KiB
C#
using System.Collections.Generic;
|
|
using Bogatyri.Settlement.Placement;
|
|
using NUnit.Framework;
|
|
|
|
// Тесты размещения зданий в 3D-поселении (ТЗ «Система строительства поселения» от 04.11.2026, раздел 11).
|
|
// Запуск: Window -> General -> Test Runner -> EditMode -> Run All.
|
|
public class PlacementTests
|
|
{
|
|
// Карта 20 x 20: всё открыто с Ратуши 1, кроме правой полосы (x >= 15 -- Ратуша 2);
|
|
// река по x = 10, скала в (2, 18), дерево "tree_1" в (5, 5), холм справа вверху
|
|
static SettlementMap Map()
|
|
{
|
|
var map = new SettlementMap(20, 20);
|
|
for (int y = 0; y < 20; y++)
|
|
for (int x = 0; x < 20; x++)
|
|
{
|
|
CellKind k = x == 10 ? CellKind.Water : x == 2 && y == 18 ? CellKind.Mountain : CellKind.Ground;
|
|
int height = x >= 16 && y >= 16 ? (x - 16) * 500 : 0; // склон: 0,5 м на клетку
|
|
map.SetCell(x, y, k, height, x >= 15 ? 2 : 1);
|
|
}
|
|
map.AddObstacle("tree_1", new[] { (5, 5) });
|
|
return map;
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_FlatGround_Ok_AndForbiddenPlaces()
|
|
{
|
|
var map = Map();
|
|
Assert.AreEqual(PlaceError.None, map.Place("hall", "Ратуша", 1, 1, 3, 3, 0, 1), "01: ровная земля");
|
|
Assert.AreEqual(PlaceError.Water, map.Validate(9, 2, 2, 2, 0, 1, null, out _), "02: река");
|
|
Assert.AreEqual(PlaceError.Mountain, map.Validate(1, 17, 2, 2, 0, 1, null, out _), "02: скала");
|
|
Assert.AreEqual(PlaceError.Obstacle, map.Validate(4, 4, 2, 2, 0, 1, null, out _), "дерево мешает");
|
|
Assert.AreEqual(PlaceError.OutOfMap, map.Validate(19, 19, 2, 2, 0, 1, null, out _), "за краем");
|
|
Assert.AreEqual(PlaceError.ZoneLocked, map.Validate(15, 2, 2, 2, 0, 1, null, out _), "зона Ратуши 2");
|
|
Assert.AreEqual(PlaceError.None, map.Validate(15, 2, 2, 2, 0, 2, null, out _), "11: Ратуша 2 открыла зону");
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_GapBetweenBuildings()
|
|
{
|
|
var map = Map();
|
|
map.Place("a", "Дом", 1, 1, 2, 2, 0, 1);
|
|
Assert.AreEqual(PlaceError.Occupied, map.Validate(2, 2, 2, 2, 0, 1, null, out _));
|
|
Assert.AreEqual(PlaceError.TooClose, map.Validate(3, 1, 2, 2, 0, 1, null, out _), "03: вплотную -- нарушен отступ");
|
|
Assert.AreEqual(PlaceError.None, map.Validate(4, 1, 2, 2, 0, 1, null, out _), "через клетку -- можно");
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_Rotation_SwapsFootprint()
|
|
{
|
|
var map = Map();
|
|
// 4 x 1 у реки: повёрнутое на 90 -- 1 x 4 -- помещается вдоль реки, без поворота -- упирается в неё
|
|
Assert.AreEqual(PlaceError.Water, map.Validate(7, 12, 4, 1, 0, 1, null, out _));
|
|
foreach (int rot in new[] { 90, 270 })
|
|
Assert.AreEqual(PlaceError.None, map.Validate(9, 12, 4, 1, rot, 1, null, out _), "04: поворот " + rot);
|
|
Assert.AreEqual(PlaceError.Water, map.Validate(7, 12, 4, 1, 180, 1, null, out _), "04: 180 -- как 0");
|
|
map.Place("long", "Склад", 9, 12, 4, 1, 90, 1);
|
|
Assert.IsTrue(map.TryGetBuilding("long", out var b));
|
|
Assert.AreEqual(1, b.W);
|
|
Assert.AreEqual(4, b.H);
|
|
Assert.AreEqual("long", map.BuildingAt(9, 15));
|
|
Assert.IsNull(map.BuildingAt(10, 12));
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_Slope_FoundationOrTooSteep()
|
|
{
|
|
var map = Map();
|
|
Assert.AreEqual(PlaceError.None, map.Validate(16, 16, 2, 2, 0, 2, null, out int f), "небольшой перепад");
|
|
Assert.AreEqual(500, f, "фундамент 0,5 м");
|
|
Assert.AreEqual(PlaceError.TooSteep, map.Validate(16, 16, 3, 2, 0, 2, null, out _), "1 м -- слишком круто");
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_Move_IsAtomic_KeepsId()
|
|
{
|
|
var map = Map();
|
|
map.Place("farm", "Ферма", 1, 1, 3, 3, 0, 1);
|
|
map.Place("mine", "Шахта", 12, 1, 2, 2, 0, 1);
|
|
|
|
Assert.AreEqual(PlaceError.None, map.Move("farm", 2, 1, 0, 1), "свой прежний след не мешает");
|
|
Assert.IsTrue(map.TryGetBuilding("farm", out var moved));
|
|
Assert.AreEqual(2, moved.X);
|
|
|
|
Assert.AreEqual(PlaceError.Water, map.Move("farm", 8, 1, 0, 1), "09: ошибка -- здание на месте");
|
|
map.TryGetBuilding("farm", out var same);
|
|
Assert.AreEqual(2, same.X);
|
|
Assert.AreEqual(2, map.Buildings.Count, "без дублей");
|
|
|
|
Assert.AreEqual(PlaceError.None, map.Move("mine", 12, 6, 90, 1), "05: шахту можно переносить и поворачивать");
|
|
Assert.AreEqual(PlaceError.OutOfMap, map.Move("nope", 1, 1, 0, 1));
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_ClearObstacle_OnceOnly_SurvivesReload()
|
|
{
|
|
var map = Map();
|
|
Assert.IsTrue(map.ClearObstacle("tree_1"), "10: расчищено -- одна награда");
|
|
Assert.IsFalse(map.ClearObstacle("tree_1"), "второй раз -- без награды");
|
|
Assert.IsNull(map.ObstacleAt(5, 5));
|
|
Assert.AreEqual(PlaceError.None, map.Validate(4, 4, 2, 2, 0, 1, null, out _));
|
|
|
|
// Загрузка: расчищенное не возвращается, даже если отмечено раньше, чем объект добавлен на карту
|
|
var copy = new SettlementMap(20, 20);
|
|
for (int y = 0; y < 20; y++) for (int x = 0; x < 20; x++) copy.SetCell(x, y, CellKind.Ground, 0, 1);
|
|
copy.RestoreCleared(new List<string>(map.Cleared));
|
|
copy.AddObstacle("tree_1", new[] { (5, 5) });
|
|
Assert.IsNull(copy.ObstacleAt(5, 5));
|
|
Assert.IsFalse(copy.ClearObstacle("tree_1"));
|
|
}
|
|
|
|
[Test]
|
|
public void Placement_Restore_NoOverlaps()
|
|
{
|
|
var map = Map();
|
|
Assert.IsTrue(map.Restore(new PlacedRect { Id = "a", Type = "Дом", X = 1, Y = 1, SizeW = 2, SizeH = 2, Rotation = 0 }));
|
|
Assert.IsFalse(map.Restore(new PlacedRect { Id = "b", Type = "Дом", X = 2, Y = 2, SizeW = 2, SizeH = 2, Rotation = 0 }), "12: наложение не восстанавливается");
|
|
Assert.IsFalse(map.Restore(new PlacedRect { Id = "a", Type = "Дом", X = 6, Y = 6, SizeW = 2, SizeH = 2, Rotation = 0 }), "тот же id -- не дубль");
|
|
Assert.AreEqual(270, SettlementMap.NormalizeRotation(-90));
|
|
}
|
|
}
|