Exemple #1
0
        public void NormalizePolygon_Polygon_ReturnsNormalizedPolygon()
        {
            var polygon = new PolygonGrid2DBuilder()
                          .AddPoint(0, 5)
                          .AddPoint(5, 5)
                          .AddPoint(5, 0)
                          .AddPoint(2, 0)
                          .AddPoint(2, 3)
                          .AddPoint(0, 3)
                          .Build();

            var normalized     = utils.NormalizePolygon(polygon);
            var squarePoints   = normalized.GetPoints();
            var expectedPoints = new List <Vector2Int>()
            {
                new Vector2Int(0, 3),
                new Vector2Int(0, 5),
                new Vector2Int(5, 5),
                new Vector2Int(5, 0),
                new Vector2Int(2, 0),
                new Vector2Int(2, 3),
            };

            Assert.IsTrue(expectedPoints.SequenceEqual(squarePoints));
        }
Exemple #2
0
        public void GetConfigurationSpaceOverCorridor_RoomShapesThatCannotBeCorrectlyConnected()
        {
            var roomShape1     = PolygonGrid2D.GetSquare(5);
            var roomDoorsMode1 = new SimpleDoorMode(1, 0);

            var roomShape2 = new PolygonGrid2DBuilder()
                             .AddPoint(0, 1)
                             .AddPoint(0, 2)
                             .AddPoint(2, 2)
                             .AddPoint(2, 0)
                             .AddPoint(1, 0)
                             .AddPoint(1, 1)
                             .Build();
            var roomDoorsMode2 = new ManualDoorMode(new List <OrthogonalLineGrid2D>()
            {
                new OrthogonalLineGrid2D(new Vector2Int(1, 1), new Vector2Int(0, 1)),
            });

            var corridor          = PolygonGrid2D.GetSquare(2);
            var corridorDoorsMode = new ManualDoorMode(new List <OrthogonalLineGrid2D>()
            {
                new OrthogonalLineGrid2D(new Vector2Int(0, 0), new Vector2Int(1, 0)),
                new OrthogonalLineGrid2D(new Vector2Int(0, 2), new Vector2Int(1, 2)),
            });

            var configurationSpace = generator.GetConfigurationSpaceOverCorridor(roomShape2, roomDoorsMode2, roomShape1,
                                                                                 roomDoorsMode1, corridor, corridorDoorsMode);

            Assert.That(configurationSpace.Lines.SelectMany(x => x.GetPoints()), Is.Empty);
        }
        public void OverlapAlongLine_ComplexCase()
        {
            var p1 = GetPlusShape();
            var p2 = new PolygonGrid2DBuilder()
                     .AddPoint(0, 0)
                     .AddPoint(0, 8)
                     .AddPoint(8, 8)
                     .AddPoint(8, 2)
                     .AddPoint(6, 2)
                     .AddPoint(6, 6)
                     .AddPoint(2, 6)
                     .AddPoint(2, 0)
                     .Build();

            var line = new OrthogonalLineGrid2D(new Vector2Int(0, -2), new Vector2Int(15, -2));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <Vector2Int, bool> >()
            {
                Tuple.Create(new Vector2Int(0, -2), true),
                Tuple.Create(new Vector2Int(2, -2), false),
                Tuple.Create(new Vector2Int(3, -2), true),
                Tuple.Create(new Vector2Int(6, -2), false),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
        public void Constructor_CounterClockwise_Throws()
        {
            {
                // Square
                var p = new PolygonGrid2DBuilder()
                        .AddPoint(3, 0)
                        .AddPoint(3, 3)
                        .AddPoint(0, 3)
                        .AddPoint(0, 0);

                Assert.Throws <ArgumentException>(() => p.Build());
            }

            {
                // L Shape
                var p = new PolygonGrid2DBuilder()
                        .AddPoint(6, 0)
                        .AddPoint(6, 3)
                        .AddPoint(3, 3)
                        .AddPoint(3, 6)
                        .AddPoint(0, 6)
                        .AddPoint(0, 0);

                Assert.Throws <ArgumentException>(() => p.Build());
            }
        }
        public void BoudingRectangle_ReturnsBoundingBox()
        {
            {
                var p = PolygonGrid2D.GetRectangle(2, 4);

                var boundingRectangle = p.BoundingRectangle;
                var expected          = new RectangleGrid2D(new Vector2Int(0, 0), new Vector2Int(2, 4));

                Assert.AreEqual(expected, boundingRectangle);
            }

            {
                var p = new PolygonGrid2DBuilder()
                        .AddPoint(0, 0)
                        .AddPoint(0, 6)
                        .AddPoint(3, 6)
                        .AddPoint(3, 3)
                        .AddPoint(7, 3)
                        .AddPoint(7, 0)
                        .Build();

                var boundingRectangle = p.BoundingRectangle;
                var expected          = new RectangleGrid2D(new Vector2Int(0, 0), new Vector2Int(7, 6));

                Assert.AreEqual(expected, boundingRectangle);
            }
        }
Exemple #6
0
        public void GetPolygons_PlusShape()
        {
            var polygon = new PolygonGrid2DBuilder()
                          .AddPoint(0, 2)
                          .AddPoint(0, 4)
                          .AddPoint(2, 4)
                          .AddPoint(2, 6)
                          .AddPoint(4, 6)
                          .AddPoint(4, 4)
                          .AddPoint(6, 4)
                          .AddPoint(6, 2)
                          .AddPoint(4, 2)
                          .AddPoint(4, 0)
                          .AddPoint(2, 0)
                          .AddPoint(2, 2)
                          .Build();

            var partitions = partitioner.GetPartitions(polygon);
            var expected   = new List <List <RectangleGrid2D> >()
            {
                new List <RectangleGrid2D>()
                {
                    new RectangleGrid2D(new Vector2Int(2, 0), new Vector2Int(4, 2)),
                    new RectangleGrid2D(new Vector2Int(0, 2), new Vector2Int(6, 4)),
                    new RectangleGrid2D(new Vector2Int(2, 4), new Vector2Int(4, 6)),
                },
                new List <RectangleGrid2D>()
                {
                    new RectangleGrid2D(new Vector2Int(0, 2), new Vector2Int(2, 4)),
                    new RectangleGrid2D(new Vector2Int(2, 0), new Vector2Int(4, 6)),
                    new RectangleGrid2D(new Vector2Int(4, 2), new Vector2Int(6, 4)),
                }
            };

            var matched = false;

            foreach (var rectangles in expected)
            {
                foreach (var r in rectangles)
                {
                    if (!partitions.Contains(r))
                    {
                        break;
                    }
                }

                matched = true;
            }

            Assert.AreEqual(expected[0].Count, partitions.Count);
            Assert.AreEqual(true, matched);

            foreach (var p in polygon.GetAllRotations().Select(x => utils.NormalizePolygon(x)))
            {
                var rotated = partitioner.GetPartitions(p);
                Assert.AreEqual(expected[0].Count, rotated.Count);
            }
        }
        public void Constructor_EdgesNotOrthogonal_Trows()
        {
            var polygon1 = new PolygonGrid2DBuilder()
                           .AddPoint(0, 0)
                           .AddPoint(0, 5)
                           .AddPoint(3, 4)
                           .AddPoint(4, 0);

            Assert.Throws <ArgumentException>(() => polygon1.Build());
        }
        public void Constructor_OverlappingEdges_Throws()
        {
            var polygon1 = new PolygonGrid2DBuilder()
                           .AddPoint(0, 0)
                           .AddPoint(3, 0)
                           .AddPoint(3, 2)
                           .AddPoint(0, 2)
                           .AddPoint(0, 4);

            Assert.Throws <ArgumentException>(() => polygon1.Build());
        }
        public void Constructor_TooFewPoints_Throws()
        {
            var polygon1 = new PolygonGrid2DBuilder()
                           .AddPoint(0, 0)
                           .AddPoint(0, 5);

            var polygon2 = new PolygonGrid2DBuilder()
                           .AddPoint(0, 0)
                           .AddPoint(0, 5)
                           .AddPoint(5, 5);

            Assert.Throws <ArgumentException>(() => polygon1.Build());
            Assert.Throws <ArgumentException>(() => polygon2.Build());
        }
Exemple #10
0
        public void GetConfigurationSpaceOverCorridor_SquareRoomLShapedCorridor()
        {
            var roomShape     = PolygonGrid2D.GetSquare(5);
            var roomDoorsMode = new SimpleDoorMode(1, 0);

            var corridor = new PolygonGrid2DBuilder()
                           .AddPoint(0, 1)
                           .AddPoint(0, 2)
                           .AddPoint(2, 2)
                           .AddPoint(2, 0)
                           .AddPoint(1, 0)
                           .AddPoint(1, 1)
                           .Build();

            var corridorDoorsMode = new ManualDoorMode(new List <OrthogonalLineGrid2D>()
            {
                new OrthogonalLineGrid2D(new Vector2Int(0, 1), new Vector2Int(0, 2)),
                new OrthogonalLineGrid2D(new Vector2Int(2, 0), new Vector2Int(1, 0)),
            });

            var expectedLines = new List <OrthogonalLineGrid2D>()
            {
                new OrthogonalLineGrid2D(new Vector2Int(-6, 2), new Vector2Int(-6, 6)), // Left side
                new OrthogonalLineGrid2D(new Vector2Int(-5, 2), new Vector2Int(-5, 6)),
                new OrthogonalLineGrid2D(new Vector2Int(-6, 6), new Vector2Int(-2, 6)), // Top side
                new OrthogonalLineGrid2D(new Vector2Int(-6, 5), new Vector2Int(-2, 5)),
                new OrthogonalLineGrid2D(new Vector2Int(2, -6), new Vector2Int(6, -6)), // Bottom side
                new OrthogonalLineGrid2D(new Vector2Int(2, -5), new Vector2Int(6, -5)),
                new OrthogonalLineGrid2D(new Vector2Int(5, -2), new Vector2Int(5, -6)), // Right side
                new OrthogonalLineGrid2D(new Vector2Int(6, -2), new Vector2Int(6, -6)),
            };

            var expectedPoints = expectedLines
                                 .SelectMany(x => x.GetPoints())
                                 .Distinct()
                                 .ToList();

            var configurationSpace = generator.GetConfigurationSpaceOverCorridor(roomShape, roomDoorsMode, roomShape,
                                                                                 roomDoorsMode, corridor, corridorDoorsMode);

            var configurationSpacePoints = configurationSpace
                                           .Lines
                                           .SelectMany(x => x.GetPoints())
                                           .ToList();

            Assert.That(configurationSpacePoints, Is.EquivalentTo(expectedPoints));
        }
        public void Constructor_ValidPolygons()
        {
            var square = new PolygonGrid2DBuilder()
                         .AddPoint(0, 0)
                         .AddPoint(0, 3)
                         .AddPoint(3, 3)
                         .AddPoint(3, 0);

            var lPolygon = new PolygonGrid2DBuilder()
                           .AddPoint(0, 0)
                           .AddPoint(0, 6)
                           .AddPoint(3, 6)
                           .AddPoint(3, 3)
                           .AddPoint(6, 3)
                           .AddPoint(6, 0);

            Assert.DoesNotThrow(() => square.Build());
            Assert.DoesNotThrow(() => lPolygon.Build());
        }
        public void Equals_WhenNotEqual_ReturnsFalse()
        {
            {
                var p1 = new PolygonGrid2DBuilder()
                         .AddPoint(0, 0)
                         .AddPoint(0, 3)
                         .AddPoint(3, 3)
                         .AddPoint(3, 0)
                         .Build();

                var p2 = new PolygonGrid2DBuilder()
                         .AddPoint(3, 0)
                         .AddPoint(0, 0)
                         .AddPoint(0, 3)
                         .AddPoint(3, 3)
                         .Build();

                Assert.IsFalse(p1.Equals(p2));
            }
        }
        public void OverlapAlongLine_LAndL2()
        {
            var p1 = GetLShape();
            var p2 = new PolygonGrid2DBuilder()
                     .AddPoint(0, 0)
                     .AddPoint(0, 9)
                     .AddPoint(3, 9)
                     .AddPoint(3, 3)
                     .AddPoint(6, 3)
                     .AddPoint(6, 0)
                     .Build();
            var line = new OrthogonalLineGrid2D(new Vector2Int(3, 8), new Vector2Int(3, -2));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <Vector2Int, bool> >()
            {
                Tuple.Create(new Vector2Int(3, 2), true),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
        public void OverlapAlongLine_SquareAndL3()
        {
            var p1 = PolygonGrid2D.GetSquare(6);
            var p2 = new PolygonGrid2DBuilder()
                     .AddPoint(0, 0)
                     .AddPoint(0, 6)
                     .AddPoint(6, 6)
                     .AddPoint(6, 3)
                     .AddPoint(3, 3)
                     .AddPoint(3, 0)
                     .Build();
            var line = new OrthogonalLineGrid2D(new Vector2Int(3, 2), new Vector2Int(3, -5));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <Vector2Int, bool> >()
            {
                Tuple.Create(new Vector2Int(3, 2), true),
                Tuple.Create(new Vector2Int(3, -3), false),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
            protected override RoomTemplateGrid2D GetRectangleRoomTemplate(int width, int height, SimpleDoorModeGrid2D doorMode)
            {
                if (doorMode.CornerDistance >= 2)
                {
                    var polygon = new PolygonGrid2DBuilder()
                                  .AddPoint(2, 0)
                                  .AddPoint(2, 1)
                                  .AddPoint(1, 1)
                                  .AddPoint(1, 2)
                                  .AddPoint(0, 2)
                                  .AddPoint(0, height - 2)
                                  .AddPoint(1, height - 2)
                                  .AddPoint(1, height - 1)
                                  .AddPoint(2, height - 1)
                                  .AddPoint(2, height)
                                  .AddPoint(width - 2, height)
                                  .AddPoint(width - 2, height - 1)
                                  .AddPoint(width - 1, height - 1)
                                  .AddPoint(width - 1, height - 2)
                                  .AddPoint(width, height - 2)
                                  .AddPoint(width, 2)
                                  .AddPoint(width - 1, 2)
                                  .AddPoint(width - 1, 1)
                                  .AddPoint(width - 2, 1)
                                  .AddPoint(width - 2, 0)
                                  .Build();

                    return(GetRoomTemplate(polygon,
                                           new SimpleDoorModeGrid2D(doorMode.DoorLength, doorMode.CornerDistance - 2),
                                           $"Deformed {width}x{height}"));
                }
                else
                {
                    return(base.GetRectangleRoomTemplate(width, height, doorMode));
                }
            }
Exemple #16
0
        /// <summary>
        /// Prepare level description.
        /// </summary>
        public LevelDescriptionGrid2D <int> GetLevelDescription()
        {
            //md In this example, we will generate a very simple level consisting of 5 rooms with rectangular shapes.

            //md ## Room templates
            //md First, we will create our room templates. To do that, we need to create a *polygon* that defines the outline of the room template and also provide a list of possible door positions.

            //md ### Outline
            //md In the *Grid2D* setting, the outline of a room template is an orthogonal polygon where each point has integer coordinates. In other words, it is a polygon that we can draw on an integer grid using 1x1 square tiles.

            //md The first outline that we create is a 6x10 rectangle:

            var squareRoomOutline = new PolygonGrid2DBuilder()
                                    .AddPoint(0, 0)
                                    .AddPoint(0, 10)
                                    .AddPoint(6, 10)
                                    .AddPoint(6, 0)
                                    .Build();

            //md > **Note:** Orthogonal (or rectilinear) polygon is a polygon of whose edge intersections are at right angles. When on an integer grid, each side of an orthogonal polygon is aligned with one of the axes.

            //md > **Note:** There are several ways of constructing polygons:
            //md    - `PolygonGrid2D.GetSquare(width)` for squares
            //md    - `PolygonGrid2D.GetRectangle(width, height)` for rectangles
            //md    - `PolygonGrid2DBuilder` with the `.AddPoint(x, y)` method
            //md    - or the `PolygonGrid2D(IEnumerable<Vector2Int> points)` constructor

            //md ### Doors
            //md In order to tell the generator how it can connect individual room templates, we need to specify all the available door positions. The main idea is that the more door positions we provide, the easier it is for the generator to find a valid layout. To define door positions, we use the `IDoorModeGrid2D` interface. The most simple *door mode* is the `SimpleDoorModeGrid2D` - it lets us specify the length of doors and how far from corners of the outline they must be. In this tutorial, we will use doors with length of 1 tile and at least 1 tile away from corners.

            var doors = new SimpleDoorModeGrid2D(doorLength: 1, cornerDistance: 1);

            //md > **Note:** There is also an additional door mode available - `ManualDoorModeGrid2D`. This mode lets you specify exactly which door positions are available. It is useful for example when we want to have doors only on the two opposite sides of a corridor.

            //md ### Allowed transformations
            //md Optionally, it is also possible to let the generator apply some transformations to the room, e.g. rotate it by 90 degrees or mirror it by the X axis. An advantage of this approach is that the algorithm automatically handles door positions and we do not have to manually define all the variations of the room template.

            var transformations = new List <TransformationGrid2D>()
            {
                TransformationGrid2D.Identity,
                TransformationGrid2D.Rotate90
            };

            //md ### Putting it all together
            //md We can now combine the *outline*, *door mode* and *allowed transformations* together to create our first room template. We also provide a *name* which is optional but it may come in handy if we need to debug something.

            var rectangleRoomTemplate = new RoomTemplateGrid2D(
                squareRoomOutline,
                doors,
                allowedTransformations: transformations,
                name: "Rectangle 6x10"
                );

            //md We can also create a room template in-place with a single expression.

            var squareRoomTemplate = new RoomTemplateGrid2D(
                PolygonGrid2D.GetSquare(8),
                new SimpleDoorModeGrid2D(doorLength: 1, cornerDistance: 1),
                name: "Square 8x8"
                );

            //md Below we can see a visualization of the two room templates. Individual door positions are shown in red.

            //md ![](./basics/room_templates.png)

            //md ## Room description
            //md When we have our room templates ready, we need to create an instance of the `RoomDescriptionGrid2D` class which describes the properties of individual rooms in the level. In this tutorial, all the rooms use the same pool of room templates, so we can create only a single room description and reuse it. However, it is also possible to use different room description for different types of rooms. For example, we may want to have a boss room and a spawn room that should use different room templates than normal rooms.

            var roomDescription = new RoomDescriptionGrid2D
                                  (
                isCorridor: false,
                roomTemplates: new List <RoomTemplateGrid2D>()
            {
                rectangleRoomTemplate, squareRoomTemplate
            }
                                  );

            //md ## Level description
            //md The final step is to describe the structure of the level. We will use a very simple graph of rooms that we can see below:

            //md ![](./basics/graph.png)

            //md First, we have to create an instance of the `LevelDescriptionGrid2D<TRoom>` class. For simplicity, We will use `integers` to identify individual rooms. But it is also possible to use a custom room type by using a different generic type parameter.

            var levelDescription = new LevelDescriptionGrid2D <int>();

            //md Next, we add individual rooms to the level description.

            levelDescription.AddRoom(0, roomDescription);
            levelDescription.AddRoom(1, roomDescription);
            levelDescription.AddRoom(2, roomDescription);
            levelDescription.AddRoom(3, roomDescription);
            levelDescription.AddRoom(4, roomDescription);

            //md And lastly, we describe how should individual rooms be connected.

            levelDescription.AddConnection(0, 1);
            levelDescription.AddConnection(0, 3);
            levelDescription.AddConnection(0, 4);
            levelDescription.AddConnection(1, 2);
            levelDescription.AddConnection(2, 3);


            //md_sc method_content:Run

            return(levelDescription);
        }