示例#1
0
        public void GetShortestPath_ShouldBeAbleToFindingShortestPath()
        {
            // Note: this method uses AStarSearch class inside.
            // AStarSerach has its own comprehensive tests, so this test is only to ensure that this method exists and
            // returns something meaningful.
            var graph = GraphFactory.CreateRectangularGraph(3,
                                                            3, MovementTypesFixture.GetMovementTypes(), MovementTypesFixture.Ground);
            var start2d        = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight);
            var start          = start2d.To3D();
            var goal2d         = new Coordinate2D(2, 2, OffsetTypes.OddRowsRight);
            var goal           = goal2d.To3D();
            var expectedPath2d = new List <Coordinate2D>
            {
                new Coordinate2D(1, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 1, OffsetTypes.OddRowsRight),
                goal2d
            };
            var expectedShortestPath = Coordinate2D.To3D(expectedPath2d);

            var shortestPath2d = graph.GetShortestPath(start2d, goal2d, MovementTypesFixture.Walking);
            var shortestPath   = graph.GetShortestPath(start, goal, MovementTypesFixture.Walking);

            Assert.That(shortestPath2d, Is.EqualTo(expectedPath2d));
            Assert.That(shortestPath, Is.EqualTo(expectedShortestPath));
        }
示例#2
0
        public void GetPassableNeighbors_ShouldExcludeBlockedNeighbors()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var center2d = new Coordinate2D(1, 1, OffsetTypes.OddRowsRight);
            var center   = center2d.To3D();

            graph.BlockCells(new List <Coordinate2D>
            {
                new Coordinate2D(2, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight)
            });

            var expectedPassableNeighbors2d = new List <Coordinate2D>
            {
                new Coordinate2D(1, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(0, 1, OffsetTypes.OddRowsRight)
            };
            var expectedPassableNeighbors = Coordinate2D.To3D(expectedPassableNeighbors2d);

            Assert.That(graph.GetPassableNeighbors(center2d), Is.EqualTo(expectedPassableNeighbors2d));
            Assert.That(graph.GetPassableNeighbors(center), Is.EqualTo(expectedPassableNeighbors));
        }
示例#3
0
        public void UnblockCells_ShouldUnblockCells_WhenCellListIsPassed()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            var cellsToBlock = new List <Coordinate2D>
            {
                new Coordinate2D(2, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight)
            };

            Assert.That(graph.IsCellBlocked(cellsToBlock[0]), Is.False);
            Assert.That(graph.IsCellBlocked(cellsToBlock[1]), Is.False);

            graph.BlockCells(cellsToBlock);

            Assert.That(graph.IsCellBlocked(cellsToBlock[0]), Is.True);
            Assert.That(graph.IsCellBlocked(cellsToBlock[1]), Is.True);

            graph.UnblockCells(cellsToBlock);

            Assert.That(graph.IsCellBlocked(cellsToBlock[0]), Is.False);
            Assert.That(graph.IsCellBlocked(cellsToBlock[1]), Is.False);

            graph.BlockCells(cellsToBlock);

            Assert.That(graph.IsCellBlocked(cellsToBlock[0]), Is.True);
            Assert.That(graph.IsCellBlocked(cellsToBlock[1]), Is.True);

            graph.UnblockCells(Coordinate2D.To3D(cellsToBlock));

            Assert.That(graph.IsCellBlocked(cellsToBlock[0]), Is.False);
            Assert.That(graph.IsCellBlocked(cellsToBlock[1]), Is.False);
        }
示例#4
0
        public void ConvertsOffsetCoordinatesToCubeCoordinatesCorrectly()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var cubeCoordinates = graph.GetAllCellsCoordinates();
            //For odd rows right:
            //Down and right: Y - 1, Z + 1
            //Down and left:  X - 1, Z + 1
            //Right: X + 1, Y - 1;
            var expectedCubeCoordinates = new List <Coordinate3D>
            {
                new Coordinate3D(0, 0, 0),
                // Down right:
                new Coordinate3D(0, -1, 1),
                // Down left:
                new Coordinate3D(-1, -1, 2),
                // Back to top, right from start position:
                new Coordinate3D(1, -1, 0),
                // Down right:
                new Coordinate3D(1, -2, 1),
                // Down left:
                new Coordinate3D(0, -2, 2),
                // Back to top, right from previous top point:
                new Coordinate3D(2, -2, 0),
                // Down right:
                new Coordinate3D(2, -3, 1),
                // Down and left:
                new Coordinate3D(1, -3, 2)
            };

            Assert.That(cubeCoordinates, Is.EqualTo(expectedCubeCoordinates));
        }
示例#5
0
        public void GetNeighbours_ShouldGetCorrectNeighbors()
        {
            var graph = GraphFactory.CreateRectangularGraph(6, 7, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            // Column 2, row 1
            var offsetTarget = new Coordinate2D(2, 1, OffsetTypes.OddRowsRight);
            var cubeTarget   = offsetTarget.To3D();
            var neighbors    = graph.GetNeighbors(cubeTarget, false).ToList();
            // Neighbors for cube coordinates should be:
            // Cube(+1, -1, 0), Cube(+1, 0, -1), Cube(0, +1, -1), Cube(-1, +1, 0), Cube(-1, 0, +1), Cube(0, -1, +1),
            var expectedNeighbors = new List <Coordinate3D>
            {
                new Coordinate3D(2, -2, 0),
                new Coordinate3D(3, -3, 0),
                new Coordinate3D(3, -4, 1),
                new Coordinate3D(2, -4, 2),
                new Coordinate3D(1, -3, 2),
                new Coordinate3D(1, -2, 1)
            };

            Assert.That(neighbors, Is.EqualTo(expectedNeighbors));

            Assert.That(
                graph.GetNeighbors(offsetTarget, false).ToList(),
                Is.EquivalentTo(Coordinate3D.To2D(expectedNeighbors, OffsetTypes.OddRowsRight))
                );
        }
示例#6
0
        public void FindShortestPath_ShouldFindShortestPathWithoutObstacles()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            // Cube coordinates are not so intuitive when it comes to visualizing them in your head, so let's use
            // offset ones and convert them to cube. Cube coordinate are used by the algorythm because it's
            // much easier to operate them when in comes to actual algorythms

            // From bottom right
            var start = new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D();
            // To top left
            var goal = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight).To3D();

            var expectedPath = new List <Coordinate3D>
            {
                // From 2, 2 we move to 1,1, which is central
                new Coordinate2D(1, 1, OffsetTypes.OddRowsRight).To3D(),
                // From 1,1 we move to 1,0, since there is no direct connection between 1,1 and 0,0
                new Coordinate2D(1, 0, OffsetTypes.OddRowsRight).To3D(),
                goal
            };

            // For the simplest test we assume that all cells have type ground, as well as a unit
            var path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));
        }
示例#7
0
        public void FindShortestPath_ShouldFindShortestPath_WhenThereArePenaltiesAndObstacles()
        {
            // Now let's make 1,1 water and block 1,2
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            graph.BlockCells(new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D());
            graph.SetCellsTerrainType(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight).To3D(),
                                      MovementTypesFixture.Water);

            var start = new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D();
            var goal  = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight).To3D();

            // Now we have two shortest paths - 1,1, 1,0, 0,0 costs 4, since there is a penalty on 1,1
            // And 2,1, 2,0, 1,0 0,0, costs 4 too. It's 1 cell longer, but there is no penalties.
            // We are expecting to take path 1 because of the heuristics - it's leades to our goal a bit more stright.
            var expectedPath = new List <Coordinate3D>
            {
                new Coordinate2D(1, 1, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(1, 0, OffsetTypes.OddRowsRight).To3D(),
                goal
            };

            var path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));
        }
示例#8
0
        public void SetManyCellsTerrainType_ShouldSetTerrainTypesToCells()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            var coordinateToSet = new Coordinate2D(2, 1, OffsetTypes.OddRowsRight);

            graph.SetCellsTerrainType(coordinateToSet, MovementTypesFixture.Water);
            Assert.That(graph.GetCellState(coordinateToSet).TerrainType, Is.EqualTo(MovementTypesFixture.Water));

            var coordinatesToSet = Coordinate2D.To3D(new List <Coordinate2D>
            {
                new Coordinate2D(0, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(0, 2, OffsetTypes.OddRowsRight)
            });

            graph.SetCellsTerrainType(coordinatesToSet, MovementTypesFixture.Water);
            foreach (var coordinate in coordinatesToSet)
            {
                Assert.That(graph.GetCellState(coordinate).TerrainType, Is.EqualTo(MovementTypesFixture.Water));
            }

            graph.SetCellsTerrainType(new List <Coordinate2D>
            {
                new Coordinate2D(0, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(0, 2, OffsetTypes.OddRowsRight)
            }, MovementTypesFixture.Air);
            foreach (var coordinate in coordinatesToSet)
            {
                Assert.That(graph.GetCellState(coordinate).TerrainType, Is.EqualTo(MovementTypesFixture.Air));
            }
        }
示例#9
0
        /// <summary>
        /// Generate Hex map with cells of 25cm X 25cm
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public HexMap(int x, int y)
        {
            //Set Offset Type for 2d -> 3d conversion
            OffsetType = OffsetTypes.OddRowsRight;

            Height = y;
            Width  = x;

            UnclearedTerrain = new TerrainType(1, "uncleared");
            ClearedTerrain   = new TerrainType(2, "cleared");

            DefaultMovement = new MovementType(1, "default");
            var movementTypes = new MovementTypes(
                new ITerrainType[] { UnclearedTerrain, ClearedTerrain },
                new Dictionary <IMovementType, Dictionary <ITerrainType, int> >
            {
                [DefaultMovement] = new Dictionary <ITerrainType, int>
                {
                    [UnclearedTerrain] = 1,
                    [ClearedTerrain]   = 2
                }
            }
                );

            Graph = GraphFactory.CreateRectangularGraph(Width, Height, movementTypes, UnclearedTerrain);
        }
示例#10
0
        public static Board GenerateBlankMap(int cols, int rows)
        {
            Graph g = GraphFactory.CreateRectangularGraph(cols, rows, Movement.AllMovementTypes, Terrain.Ground, OffsetTypes.OddRowsRight);

            return(new Board {
                MapGraph = g
            });
        }
示例#11
0
        public void ResizeSquareGraph_ShouldMaintainCellStatesOnResize()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            Assert.False(graph.IsCellBlocked(new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D()));
            graph.BlockCells(new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D());
            Assert.True(graph.IsCellBlocked(new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D()));
            GraphUtils.ResizeSquareGraph(graph, OffsetTypes.OddRowsRight, 2, 2, MovementTypesFixture.Ground);
            Assert.True(graph.IsCellBlocked(new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D()));
        }
示例#12
0
        public void GetLine_ShouldThrowIfCoordinateIsNotDirection()
        {
            var graph = GraphFactory.CreateRectangularGraph(10, 10, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var start = new Coordinate3D(1, -3, 2);

            var exception = Assert.Throws <InvalidOperationException>(() =>
            {
                var dir = graph.GetLine(start, new Coordinate3D(-2, 3, -1), 2);
                dir.ToList();
            });

            Assert.That(exception.Message, Is.EqualTo("Invalid direction"));
        }
示例#13
0
        public void IsInBounds_ShouldReturnTrueIfThePositionIsWithinTheGraphBounds()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var position = new Coordinate3D(0, -1, 1);

            Assert.That(graph.Contains(position), Is.True);

            position = new Coordinate3D(-1, 2, -1);
            Assert.That(graph.Contains(position), Is.False);

            Assert.That(graph.Contains(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight)), Is.True);
            Assert.That(graph.Contains(new Coordinate2D(10, 10, OffsetTypes.OddRowsRight)), Is.False);
        }
示例#14
0
        public void ResizeSquareGraph_AllCellsShouldHaveCorrectPositionsAfterResize()
        {
            var width  = 6;
            var height = 7;
            var graph  = GraphFactory.CreateRectangularGraph(width, height, MovementTypesFixture.GetMovementTypes(),
                                                             MovementTypesFixture.Ground);

            Assert.That(graph.GetAllCellsCoordinates().Count, Is.EqualTo(width * height));

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.That(
                        graph.GetAllCellsCoordinates()
                        .Contains(new Coordinate2D(x, y, OffsetTypes.OddRowsRight).To3D()), Is.True);
                }
            }

            width  = 4;
            height = 5;
            GraphUtils.ResizeSquareGraph(graph, OffsetTypes.OddRowsRight, width, height, MovementTypesFixture.Ground);

            Assert.That(graph.GetAllCellsCoordinates().Count, Is.EqualTo(width * height));
            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.That(
                        graph.GetAllCellsCoordinates()
                        .Contains(new Coordinate2D(x, y, OffsetTypes.OddRowsRight).To3D()), Is.True);
                }
            }

            width  = 7;
            height = 8;
            GraphUtils.ResizeSquareGraph(graph, OffsetTypes.OddRowsRight, width, height, MovementTypesFixture.Ground);

            Assert.That(graph.GetAllCellsCoordinates().Count, Is.EqualTo(width * height));
            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.That(
                        graph.GetAllCellsCoordinates()
                        .Contains(new Coordinate2D(x, y, OffsetTypes.OddRowsRight).To3D()), Is.True);
                }
            }
        }
示例#15
0
        public void GetLine_ShouldNotIncludeCoordinatesOutsideOfGraph()
        {
            var graph = GraphFactory.CreateRectangularGraph(10, 10, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var start = new Coordinate3D(1, -3, 2);

            var direction         = graph.GetLine(start, new Coordinate3D(0, 1, -1), 5);
            var expectedDirection = new List <Coordinate3D>
            {
                new Coordinate3D(1, -2, 1),
                new Coordinate3D(1, -1, 0)
            };

            Assert.That(direction.ToList(), Is.EqualTo(expectedDirection));
        }
示例#16
0
        public void FindShortestPath_ShouldFindShortestPathWithObstacles()
        {
            // Now let's block center, 1,1
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            graph.BlockCells(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight).To3D());

            // Same as in prevoius test
            var start = new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D();
            var goal  = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight).To3D();

            var expectedPath = new List <Coordinate3D>
            {
                // But this time we can't go to 1,1, since it's blocked. Instead, we are going to the left - 1,2 first
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D(),
                // From there we can move up and right
                new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D(),
                // And from there we can go to our final goal.
                goal
            };

            var path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));

            // Let's block 0,1 and move our starting point to bottom left
            graph.BlockCells(new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D());
            start = new Coordinate2D(0, 2, OffsetTypes.OddRowsRight).To3D();

            expectedPath = new List <Coordinate3D>
            {
                // Now we need to go through all corners - first let's go to the bottom right
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D(),
                // Up to the top right
                new Coordinate2D(2, 1, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(2, 0, OffsetTypes.OddRowsRight).To3D(),
                // And from there we can go left until we reach our goal
                new Coordinate2D(1, 0, OffsetTypes.OddRowsRight).To3D(),
                goal
            };

            path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));
        }
示例#17
0
        public void FindShortestPath_ShouldFindShortestPath_OnAGraphWithDifferentTerrainTypes()
        {
            // Everything is like before, but now instead of blocking 1,1 let's make it water to apply some penalties
            // to our ground moving type
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            graph.SetCellsTerrainType(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight).To3D(),
                                      MovementTypesFixture.Water);
            // And we expect to achieve same result - even through 1,1 is not blocked

            var start = new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D();
            var goal  = new Coordinate2D(0, 0, OffsetTypes.OddRowsRight).To3D();

            var expectedPath = new List <Coordinate3D>
            {
                // But this time we can't go to 1,1, since there is movement penalty. Instead, we are going to the left - 1,2 first
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D(),
                // From there we can move up and right
                new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D(),
                // And from there we can go to our final goal.
                goal
            };

            var path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));

            // Let's make 0,1 water too and move our starting point to bottom left
            graph.SetCellsTerrainType(new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D(),
                                      MovementTypesFixture.Water);
            start = new Coordinate2D(0, 2, OffsetTypes.OddRowsRight).To3D();

            // What's different from previous test - even if 0,1 is water, if we go from the bottom left
            // to the top left - go through water still we preferable - path length will be only two cells, but because
            // of penalty it'll cost 3 movement point. Going through all corners will take 6 points - 6 cells, 1 point each.
            expectedPath = new List <Coordinate3D>
            {
                // Going up to the water
                new Coordinate2D(0, 1, OffsetTypes.OddRowsRight).To3D(),
                goal
            };

            path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));
        }
示例#18
0
        public void UnblockCell_ShouldUnblockCell()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            Assert.That(graph.IsCellBlocked(new Coordinate3D(0, 0, 0)), Is.False);
            graph.BlockCells(new Coordinate3D(0, 0, 0));
            Assert.That(graph.IsCellBlocked(new Coordinate3D(0, 0, 0)), Is.True);
            graph.UnblockCells(new Coordinate3D(0, 0, 0));
            Assert.That(graph.IsCellBlocked(new Coordinate3D(0, 0, 0)), Is.False);

            Assert.That(graph.IsCellBlocked(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight)), Is.False);
            graph.BlockCells(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight));
            Assert.That(graph.IsCellBlocked(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight)), Is.True);
            graph.UnblockCells(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight));
            Assert.That(graph.IsCellBlocked(new Coordinate2D(1, 1, OffsetTypes.OddRowsRight)), Is.False);
        }
示例#19
0
        public void CreateRectangularGraph_ShouldCreateSquareGraphWithoutOptionalParameters()
        {
            const int width  = 4;
            const int height = 3;
            var       graph  = GraphFactory.CreateRectangularGraph(width, height, MovementTypesFixture.GetMovementTypes(),
                                                                   MovementTypesFixture.Ground);

            Assert.That(graph.GetAllCellsCoordinates().Count, Is.EqualTo(width * height));

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.That(
                        graph.GetAllCellsCoordinates()
                        .Contains(new Coordinate2D(x, y, OffsetTypes.OddRowsRight).To3D()), Is.True);
                }
            }
        }
示例#20
0
        public void ResizeSquareGraph_ShouldNotResizeIfNothingChanged()
        {
            var width  = 3;
            var height = 3;
            var graph  = GraphFactory.CreateRectangularGraph(width, height, MovementTypesFixture.GetMovementTypes(),
                                                             MovementTypesFixture.Ground);

            GraphUtils.ResizeSquareGraph(graph, OffsetTypes.OddRowsRight, width, height, MovementTypesFixture.Ground);
            Assert.That(graph.GetAllCellsCoordinates().Count, Is.EqualTo(width * height));
            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    Assert.That(
                        graph.GetAllCellsCoordinates()
                        .Contains(new Coordinate2D(x, y, OffsetTypes.OddRowsRight).To3D()), Is.True);
                }
            }
        }
示例#21
0
        public void AddCells_ShouldThrow_WhenAddingCellWithAnUnknownType()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var unexpectedTerrainType = new TerrainType(10, "Some Unexpected Terrain");

            Assert.That(() =>
            {
                graph.AddCells(new List <CellState>
                {
                    new CellState(
                        false,
                        new Coordinate2D(),
                        unexpectedTerrainType
                        )
                });
            },
                        Throws.ArgumentException.With.Message.EqualTo(
                            "One of the cells in graph has an unknown terrain type: 'Some Unexpected Terrain'"));
        }
示例#22
0
        public void RemoveCells_ShouldRemoveAListOfCells()
        {
            var graph = GraphFactory.CreateRectangularGraph(3, 3, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            var cellsToRemove = new List <Coordinate2D>
            {
                new Coordinate2D(1, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 0, OffsetTypes.OddRowsRight)
            }.ToList();
            var cellsToRemove3d = Coordinate2D.To3D(cellsToRemove);

            Assert.That(graph.GetAllCellsCoordinates(), Does.Contain(cellsToRemove3d[0]));
            Assert.That(graph.GetAllCellsCoordinates(), Does.Contain(cellsToRemove3d[1]));

            graph.RemoveCells(cellsToRemove);

            Assert.That(graph.GetAllCellsCoordinates(), Does.Not.Contain(cellsToRemove3d[0]));
            Assert.That(graph.GetAllCellsCoordinates(), Does.Not.Contain(cellsToRemove3d[1]));
        }
示例#23
0
        public void GetRange_ShouldGetCorrectRange()
        {
            var graph = GraphFactory.CreateRectangularGraph(6, 7, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var center2d = new Coordinate2D(3, 2, OffsetTypes.OddRowsRight);
            var center   = center2d.To3D();

            var expectedRange2D = new List <Coordinate2D>
            {
                // Closest circle
                new Coordinate2D(4, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 3, OffsetTypes.OddRowsRight),
                // Second circle
                new Coordinate2D(5, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 4, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 4, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 4, OffsetTypes.OddRowsRight)
            };
            var expectedMovementRange =
                Coordinate2D.To3D(expectedRange2D);

            var range = graph.GetRange(center, 2);

            Assert.That(range, Is.EquivalentTo(expectedMovementRange));

            Assert.That(graph.GetRange(center2d, 2), Is.EquivalentTo(expectedRange2D));
        }
示例#24
0
        public void FindShortestPath_ShouldFindShortestPathOnBiggerGraph()
        {
            // This test wouldn't be that different from previous ones, except size of the graph
            var graph = GraphFactory.CreateRectangularGraph(7, 10, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);

            // First, let's do simple test - from 5,6 to 1,2 without obstacles
            var start = new Coordinate2D(5, 6, OffsetTypes.OddRowsRight).To3D();
            var goal  = new Coordinate2D(1, 2, OffsetTypes.OddRowsRight).To3D();

            // We expect algo to go up by diagonal and then turn left
            var expectedPath = new List <Coordinate3D>
            {
                // Go up and left
                new Coordinate2D(4, 5, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(4, 4, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(3, 3, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(3, 2, OffsetTypes.OddRowsRight).To3D(),
                // And now just left until the goal is reached
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D(),
                goal
            };

            var path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));

            // Good! Now let's block some of them, and also let's add a lake in the middle.
            graph.BlockCells(Coordinate2D.To3D(new List <Coordinate2D>
            {
                new Coordinate2D(4, 6, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 5, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 7, OffsetTypes.OddRowsRight),
                new Coordinate2D(5, 5, OffsetTypes.OddRowsRight)
            }));
            graph.SetCellsTerrainType(Coordinate2D.To3D(new List <Coordinate2D>
            {
                new Coordinate2D(4, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 3, OffsetTypes.OddRowsRight)
            }), MovementTypesFixture.Water);

            expectedPath = new List <Coordinate3D>
            {
                // Avoiding obstacles
                new Coordinate2D(6, 6, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(6, 5, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(6, 4, OffsetTypes.OddRowsRight).To3D(),
                // Going parallel to the bank
                new Coordinate2D(5, 4, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(4, 4, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(3, 4, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(2, 4, OffsetTypes.OddRowsRight).To3D(),
                // Now we are going to cross the water, since it's shortest available solution from this point
                new Coordinate2D(1, 3, OffsetTypes.OddRowsRight).To3D(),
                // And we are here.
                goal
            };

            path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Walking);

            Assert.That(path, Is.EqualTo(expectedPath));

            // Now let's check water movement type - it should prefer going through the water rather than the ground
            path = AStarSearch.FindShortestPath(graph, start, goal, MovementTypesFixture.Swimming);

            expectedPath = new List <Coordinate3D>
            {
                // Avoiding obstacles
                new Coordinate2D(6, 6, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(6, 5, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(6, 4, OffsetTypes.OddRowsRight).To3D(),
                // Head right to the water
                new Coordinate2D(5, 3, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(5, 2, OffsetTypes.OddRowsRight).To3D(),
                // Swim
                new Coordinate2D(4, 2, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(3, 2, OffsetTypes.OddRowsRight).To3D(),
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight).To3D(),
                // And we are here.
                goal
            };

            Assert.That(path, Is.EqualTo(expectedPath));
        }
示例#25
0
        public void GetMovementRange_ShouldGetCorrectMovementRange()
        {
            var graph = GraphFactory.CreateRectangularGraph(6, 7, MovementTypesFixture.GetMovementTypes(),
                                                            MovementTypesFixture.Ground);
            var center2d = new Coordinate2D(3, 2, OffsetTypes.OddRowsRight);
            var center   = center2d.To3D();

            var expectedMovementRange2D = new List <Coordinate2D>
            {
                // Closest circle
                new Coordinate2D(2, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 2, OffsetTypes.OddRowsRight),
                // Second circle
                new Coordinate2D(2, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 0, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 1, OffsetTypes.OddRowsRight),
                new Coordinate2D(5, 2, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(4, 4, OffsetTypes.OddRowsRight),
                new Coordinate2D(3, 4, OffsetTypes.OddRowsRight),
                new Coordinate2D(2, 4, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 2, OffsetTypes.OddRowsRight)
            };
            var expectedMovementRange =
                Coordinate2D.To3D(expectedMovementRange2D);

            var movementRange2d = graph.GetMovementRange(center2d, 2, MovementTypesFixture.Walking);
            var movementRange   = graph.GetMovementRange(center, 2, MovementTypesFixture.Walking);

            Assert.That(movementRange2d, Is.EqualTo(expectedMovementRange2D));
            Assert.That(movementRange, Is.EqualTo(expectedMovementRange));

            // If 2,3 is water, we shouldn't be able to access 2,4. If we make 1,3 water - we just shouldn't be able to
            // access it, since going to 1,3 will cost more than movement points we have.
            graph.SetCellsTerrainType(Coordinate2D.To3D(new List <Coordinate2D>
            {
                new Coordinate2D(2, 3, OffsetTypes.OddRowsRight),
                new Coordinate2D(1, 3, OffsetTypes.OddRowsRight)
            }), MovementTypesFixture.Water);

            // Blocking 2,1 will prevent us from going to 2,1 and 2,0 at the same time
            graph.BlockCells(new Coordinate2D(2, 1, OffsetTypes.OddRowsRight).To3D());

            // 2,4 isn't accessible because the only path to it thorough the water
            expectedMovementRange2D.Remove(new Coordinate2D(2, 4, OffsetTypes.OddRowsRight));
            // 1,3 isn't accessible because it is water
            expectedMovementRange2D.Remove(new Coordinate2D(1, 3, OffsetTypes.OddRowsRight));
            // 2,1 and 2,0 isn't accessible because 2,1 is blocked
            expectedMovementRange2D.Remove(new Coordinate2D(2, 1, OffsetTypes.OddRowsRight));
            expectedMovementRange2D.Remove(new Coordinate2D(2, 0, OffsetTypes.OddRowsRight));

            expectedMovementRange = Coordinate2D.To3D(expectedMovementRange2D);

            movementRange2d = graph.GetMovementRange(center2d, 2, MovementTypesFixture.Walking);
            movementRange   = graph.GetMovementRange(center, 2, MovementTypesFixture.Walking);

            Assert.That(movementRange2d, Is.EquivalentTo(expectedMovementRange2D));
            Assert.That(movementRange, Is.EquivalentTo(expectedMovementRange));
        }