Пример #1
0
        public void CompletePathTest()
        {
            var graph = new Algorithms.AStar <TestGraphElement> .LazyGraph();

            Func <TestGraphElement, TestGraphElement, float> costFunc = (TestGraphElement lhs, TestGraphElement rhs) => { return(TestGraphElement.DistanceBetween(lhs, rhs)); };

            IDictionary <Vector2, TestGraphElement> graphElements = new Dictionary <Vector2, TestGraphElement> ();

            Func <Vector2, TestGraphElement> getGraphElementFunc = (Vector2 position) => {
                if (!graphElements.ContainsKey(position))
                {
                    graphElements[position] = TestGraphElement.At(position);
                }
                Assert.IsTrue(graphElements[position] != null && graphElements[position].position == position);
                return(graphElements[position]);
            };


            graph.getElementsConnectedToElementFunc = (TestGraphElement testPos) => {
                IList <TestGraphElement> connectedElems = new List <TestGraphElement> ();
                connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, Vector2.right)));
                connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, -Vector2.right)));
                connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, Vector2.up)));
                connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, -Vector2.up)));
                return(connectedElems);
            };

            graph.getActualCostForMovementBetweenElementsFunc         = costFunc;
            graph.getLowestCostEstimateForMovementBetweenElementsFunc = costFunc;

            Assert.IsTrue(graph.GetIsValid());

            var aStarSearch = new Algorithms.AStar <TestGraphElement>(graph);

            // Calculate a route...
            Vector2 startPos = Vector2.zero;
            Vector2 endPos   = new Vector2(5, 0);
            int     xOffset  = Mathf.RoundToInt(Mathf.Abs(startPos.x - endPos.x));
            int     yOffset  = Mathf.RoundToInt(Mathf.Abs(startPos.y - endPos.y));
            int     shortestRouteNumElements = xOffset + yOffset + 1;
            IList <TestGraphElement> route   = aStarSearch.Calculate(getGraphElementFunc(startPos), getGraphElementFunc(endPos));

            Assert.IsNotNull(route);
            Assert.AreEqual(route.Count, shortestRouteNumElements);
            Assert.AreEqual(route.First().position, startPos);
            Assert.AreEqual(route.Last().position, endPos);

            for (int currTestIndex = 1; currTestIndex < route.Count; ++currTestIndex)
            {
                TestGraphElement prevElem = route[currTestIndex - 1];
                TestGraphElement currElem = route[currTestIndex];
                Assert.IsTrue(TestGraphElement.AreAdjacent(prevElem, currElem));
            }
        }
Пример #2
0
        public void TestStructGraphElement()
        {
            var graph = new Algorithms.AStar <Vector2> .LazyGraph();

            Func <Vector2, Vector2, float> costFunc = (Vector2 lhs, Vector2 rhs) => {
                return((rhs - lhs).magnitude);
            };

            graph.getActualCostForMovementBetweenElementsFunc         = costFunc;
            graph.getLowestCostEstimateForMovementBetweenElementsFunc = costFunc;

            IList <Vector2> connectedOffsets = (new List <Vector2> {
                Vector2.right, Vector2.left, Vector2.up, Vector2.down
            }).AsReadOnly();

            // Connect a grid of all integer positions in both axes up to 100.0f away from the origin.
            graph.getElementsConnectedToElementFunc = (Vector2 startPos) => {
                IList <Vector2> connectedPositions = new List <Vector2> ();

                foreach (Vector2 currConnectedOffset in connectedOffsets)
                {
                    Vector2 currConnectedPos = OffsetPos(startPos, currConnectedOffset);
                    if (currConnectedPos.magnitude < 10.0f)
                    {
                        connectedPositions.Add(currConnectedPos);
                    }
                }

                return(connectedPositions);
            };

            Assert.IsTrue(graph.GetIsValid());

            var aStarSearch = new Algorithms.AStar <Vector2>(graph);

            IList <Vector2> resultPath = aStarSearch.Calculate(new Vector2(-5.0f, 0.0f), new Vector2(5.0f, 0.0f));

            // The expected path is a straight path along the y-axis from x = -5.0f to x = 5.0f.
            IList <Vector2> expectedResultPath = new List <Vector2> ();

            for (int i = -5; i <= 5; ++i)
            {
                expectedResultPath.Add(new Vector2((float)i, 0.0f));
            }

            Assert.IsTrue(resultPath.SequenceEqual(expectedResultPath));
        }
Пример #3
0
        public void GraphReuseTest()
        {
            var graph = new Algorithms.AStar <Vector2> .LazyGraph();

            graph.getElementsConnectedToElementFunc = (Vector2 testPos) => {
                return(new List <Vector2> {
                    testPos + Vector2.right,
                    testPos + Vector2.up,
                    testPos + Vector2.left,
                    testPos + Vector2.down
                });
            };
            Func <Vector2, Vector2, float> costFunc = (Vector2 lhs, Vector2 rhs) => { return((rhs - lhs).magnitude); };

            graph.getActualCostForMovementBetweenElementsFunc         = costFunc;
            graph.getLowestCostEstimateForMovementBetweenElementsFunc = costFunc;
            Assert.IsTrue(graph.GetIsValid());

            var aStarSearch = new Algorithms.AStar <Vector2>(graph);

            // Try a search...
            {
                IList <Vector2> result = aStarSearch.Calculate(new Vector2(0, 0), new Vector2(2, 0));
                Assert.IsTrue(Enumerable.SequenceEqual(result, new List <Vector2> {
                    new Vector2(0, 0), new Vector2(1, 0), new Vector2(2, 0)
                }));
            }

            // Try a search with a different target...
            {
                IList <Vector2> result = aStarSearch.Calculate(new Vector2(-2, 0), new Vector2(2, 0));
                Assert.IsTrue(Enumerable.SequenceEqual(result, new List <Vector2> {
                    new Vector2(-2, 0), new Vector2(-1, 0), new Vector2(0, 0), new Vector2(1, 0), new Vector2(2, 0)
                }));
            }

            // Try a search with a different start point...
            {
                IList <Vector2> result = aStarSearch.Calculate(new Vector2(-2, 0), new Vector2(3, 0));
                Assert.IsTrue(Enumerable.SequenceEqual(result, new List <Vector2> {
                    new Vector2(-2, 0), new Vector2(-1, 0), new Vector2(0, 0), new Vector2(1, 0), new Vector2(2, 0), new Vector2(3, 0)
                }));
            }
        }
Пример #4
0
        public void PartialPathTest()
        {
            var graph = new Algorithms.AStar <TestGraphElement> .LazyGraph();

            Func <TestGraphElement, TestGraphElement, float> costFunc = (TestGraphElement lhs, TestGraphElement rhs) => {
                return(TestGraphElement.DistanceBetween(lhs, rhs));
            };

            IDictionary <Vector2, TestGraphElement> graphElements = new Dictionary <Vector2, TestGraphElement> ();

            Func <Vector2, TestGraphElement> getGraphElementFunc = (Vector2 position) => {
                if (!graphElements.ContainsKey(position))
                {
                    graphElements[position] = TestGraphElement.At(position);
                }
                Assert.IsTrue(graphElements[position] != null && graphElements[position].position == position);
                return(graphElements[position]);
            };

            graph.getElementsConnectedToElementFunc = (TestGraphElement testPos) => {
                // Add a gap in the graph between x=2 and x=3 so we cannot do a complete path.
                float graphBreakXPos = 2.0f;

                IList <TestGraphElement> connectedElems = new List <TestGraphElement> ();
                if (testPos.position.x != graphBreakXPos)
                {
                    connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, Vector2.right)));
                }
                if (testPos.position.x != graphBreakXPos + 1.0f)
                {
                    connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, -Vector2.right)));
                }
                connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, Vector2.up)));
                connectedElems.Add(getGraphElementFunc(OffsetPos(testPos.position, -Vector2.up)));
                return(connectedElems);
            };

            graph.getActualCostForMovementBetweenElementsFunc         = costFunc;
            graph.getLowestCostEstimateForMovementBetweenElementsFunc = costFunc;

            Assert.IsTrue(graph.GetIsValid());

            var aStarSearch = new Algorithms.AStar <TestGraphElement>(graph);

            // Calculate a route...
            Vector2 startPos = Vector2.zero;
            Vector2 endPos   = new Vector2(5, 0);

            // Check that we can't find a complete route between the two points (as there is a break in the graph).
            // Note: As we have an non-finite graph and there is no complete path, we MUST give a worst acceptable route cost as otherwise the
            // calculation will never terminate (as it can never be sure there isn't a viable solution in the parts of the graph it hasn't reached yet).
            IList <TestGraphElement> completeRoute = aStarSearch.Calculate(getGraphElementFunc(startPos), getGraphElementFunc(endPos), false, 100.0f);

            Assert.IsNull(completeRoute);

            IList <TestGraphElement> partialRoute = aStarSearch.Calculate(getGraphElementFunc(startPos), getGraphElementFunc(endPos), true, 100.0f);

            Assert.IsNotNull(partialRoute);

            // Check the best partial route we found is what we would expect...
            Assert.AreEqual(partialRoute.Count, 3);
            Assert.AreEqual(partialRoute[0].position, startPos);
            Assert.AreEqual(partialRoute[1].position, new Vector2(1, 0));
            Assert.AreEqual(partialRoute[2].position, new Vector2(2, 0));
        }