public void Equals_SameReference_True() { Motility motility = Motility.Fly; Motility motility2 = motility; Assert.IsTrue(motility.Equals(motility2)); }
public void Equals_SameType_True() { Motility motility = Motility.Fly; Motility motility2 = Motility.Fly; Assert.IsTrue(motility.Equals(motility2)); }
public void Contains_SameType_True() { Motility motility = Motility.Fly; Motility motility2 = Motility.Fly; Assert.IsTrue(motility.Contains(motility2)); }
public void FilteredNeighbors_Unconstrained_EightWayNeighbors() { Vec2 vec2 = new Vec2(5, 5); PathfindingGrid grid = new PathfindingGrid(vec2); Vec2 tileCoordinates = new Vec2(3, 3); Motility agentMotility = Motility.Unconstrained | Motility.EightWayNeighbors; List <GridNode> nodes = new List <GridNode>(); grid.Fill(position => new GridNode(Tiles.Stone, position, grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(2, 2), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(3, 2), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(4, 2), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(2, 3), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(4, 3), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(2, 4), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(3, 4), grid)); nodes.Add(new GridNode(Tiles.Stone, new Vec2(4, 4), grid)); IReadOnlyCollection <GridNode> filteredNeighbors = grid.FilteredNeighbors(grid[tileCoordinates], agentMotility); CollectionAssert.AreEquivalent(nodes.AsReadOnly(), filteredNeighbors); }
public void Bitwise_OR() { Motility motility = Motility.Land | Motility.Swim; int landAndSwim = 3; Assert.AreEqual(motility.GetHashCode(), landAndSwim.GetHashCode()); }
public void Equals_DifferentType_False() { Motility motility = Motility.Fly; Motility motility2 = Motility.Climb; Assert.IsFalse(motility.Equals(motility2)); }
public void Bitwise_AND() { Motility motility = Motility.Land | Motility.Swim; int land = 1; motility &= Motility.Land; Assert.AreEqual(motility.GetHashCode(), land.GetHashCode()); }
public void Subtract() { Motility motility = Motility.Land | Motility.Swim; int land = 1; motility -= Motility.Swim; Assert.AreEqual(motility.GetHashCode(), land.GetHashCode()); }
public void IsTraversableTo_ContainsTraversable_True() { Motility traversable = Motility.Land | Motility.Burrow | Motility.Climb; //Assert.IsFalse(start.IsTraversableTo(end, Motility.Land)); //end.SetIncomingTraversableFlag(traversable); //Assert.IsTrue(start.IsTraversableTo(end, Motility.Land)); }
public void SetIncomingTravsersableFlag_SetMultipleTraversableFlags_True() { Motility traversable = Motility.Land | Motility.Fly; /*Assert.IsFalse(start.IsTraversableTo(end, traversable)); * * end.SetIncomingTraversableFlag(traversable); * * Assert.IsTrue(start.IsTraversableTo(end, Motility.Land)); * Assert.IsTrue(start.IsTraversableTo(end, Motility.Fly));*/ }
public void IsTraversible_DoesNotContainTraversability_False() { Motility traversable = Motility.Fly; Assert.IsFalse(edge.IsTraversable(Motility.Land)); Assert.IsFalse(edge.IsTraversable(Motility.Fly)); Assert.IsFalse(edge.IsTraversable(Motility.Burrow)); edge.SetMotilityFlag(Motility.Land); edge.SetMotilityFlag(Motility.Burrow); Assert.IsFalse(edge.IsTraversable(traversable)); }
public void IsTraversibleTo_DoesNotContainTraversability_False() { Motility traversable = Motility.Fly; /*Assert.IsFalse(start.IsTraversableTo(end, Motility.Land)); * Assert.IsFalse(start.IsTraversableTo(end, Motility.Fly)); * Assert.IsFalse(start.IsTraversableTo(end, Motility.Burrow)); * * end.SetIncomingTraversableFlag(Motility.Land); * end.SetIncomingTraversableFlag(Motility.Burrow); * * Assert.IsFalse(start.IsTraversableTo(end, traversable));*/ }
public void FilteredNeighbors_LandMotility_FourWayNeighbors() { Vec2 vec2 = new Vec2(5, 5); PathfindingGrid grid = new PathfindingGrid(vec2); Vec2 tileCoordinates = new Vec2(3, 3); Motility agentMotility = Motility.Land | Motility.FourWayNeighbors; List <GridNode> nodes = new List <GridNode>(); grid.Fill(position => new GridNode(Tiles.Stone, position, grid)); grid[2, 3] = new GridNode(Tiles.Floor, new Vec2(2, 3), grid); grid[3, 4] = new GridNode(Tiles.Floor, new Vec2(3, 4), grid); nodes.Add(new GridNode(Tiles.Floor, new Vec2(2, 3), grid)); nodes.Add(new GridNode(Tiles.Floor, new Vec2(3, 4), grid)); CollectionAssert.AreEquivalent(nodes.AsReadOnly(), grid.FilteredNeighbors(grid[tileCoordinates], agentMotility)); }
public override IList <GridNode> Search(GridNode start, GridNode goal, Motility motility, Func <GridNode, GridNode, float> heuristic) { Dictionary <GridNode, GridNode> parentMap = new Dictionary <GridNode, GridNode>(); SimplePriorityQueue <GridNode> frontier = new SimplePriorityQueue <GridNode>(); frontier.Enqueue(start, start.PathCost); while (frontier.Count > 0) { GridNode current = frontier.Dequeue(); if (current == goal) { break; } foreach (GridNode neighbor in current.Neighbors) { IPathfindingEdge edge = current.JoiningEdge(neighbor); //if (!IsTraversable(edge, motility)) continue; // TODO: This line should be made irrelevant float newCost = current.PathCost + edge.Weight; float neighborCost = neighbor.PathCost; bool containsKey = parentMap.ContainsKey(neighbor); if (containsKey && (newCost >= neighborCost)) { continue; } neighbor.PathCost = newCost; parentMap[neighbor] = current; // UPSERT dictionary function float priority = newCost + heuristic(goal, neighbor); frontier.Enqueue(neighbor, priority); } } IList <GridNode> path = ReconstructPath(parentMap, start, goal); return(path); }
/// <summary> /// Checks if a given edge is traversable given the motility flags passed in. Will check both movement /// motility as well as filter out edges based on the most permissive n-WayNeighbor's flag set. If no /// neighbor flag is set, it defaults to Motility.AllNeighbors. /// </summary> /// <param name="edge">The edge attempting traversal.</param> /// <param name="agentMotility">The agent's ability to traverse edges.</param> public static bool IsTraversable(GridNode edge, Motility agentMotility) { // Identify the graph structure for this agent and reject extraneous neighbors. if (agentMotility.Contains(Motility.AllNeighbors)) { // Most permissive option is true, so continue to next step, skipping the other checks. } else if (agentMotility.Contains(Motility.EightWayNeighbors)) { // Reject only special nodes (such as portals) //if (!Direction.Clockwise.Contains(edge.Direction)) { return(false); } } else if (agentMotility.Contains(Motility.FourWayNeighbors)) { // Reject the intercardinal directions (diagonals) as well as any special nodes (such as portals) //if (!Direction.CardinalDirections.Contains(edge.Direction)) { return(false); } } else { // This is an implicit "has no neighbors flag" flag, which is just a lack of any neighbor flag at all. // In this case we default to Motility.AllNeighbors and continue. } // If the agent has Motility.Unconstrained, then we return, no need to compare to edge Motility. if (agentMotility.Contains(Motility.Unconstrained)) { return(true); } // Check the agent's movement Motility compared to the edge Motility throw new NotImplementedException(); //return edge.IsTraversable(agentMotility); }
public override IList <GridNode> Search(GridNode start, GridNode goal, Motility motility) { Dictionary <GridNode, GridNode> parentMap = new Dictionary <GridNode, GridNode>(); Queue <GridNode> frontier = new Queue <GridNode>(); frontier.Enqueue(start); while (frontier.Count > 0) { GridNode current = frontier.Dequeue(); if (current == goal) { break; } foreach (GridNode neighbor in current.Neighbors) { IPathfindingEdge edge = current.JoiningEdge(neighbor); //if (!edge.IsTraversable(edge, motility)) continue; if (parentMap.ContainsKey(neighbor)) { continue; } frontier.Enqueue(neighbor); parentMap.Add(neighbor, current); } } IList <GridNode> path = ReconstructPath(parentMap, start, goal); return(path); }
public TileType _Motility(Motility motility) { return(new TileType(_name, motility, _spriteIndex)); }
public virtual IList <GridNode> Search(GridNode start, GridNode goal, Motility motility, Func <GridNode, GridNode, float> heuristic) { throw new NotImplementedException( "\"This algorithm does not use a heuristic. Use \"Search(IPathfindingNode start, IPathfindingNode end, Traversable traversability)\" instead."); }
public void Contains_SameReference_True() { Motility motility = Motility.Fly; Assert.IsTrue(motility.Contains(motility)); }
/* TODO: When multiple movement types are added, the pathfinding algorithms will have to account for the fact * that there are "preferences" for movement - i.e. if you have a land speed of 6 and a climb speed * of 3 the costs of climbing are twice as high as the cost of walking. This will probably need to have the * traversabilities given in a Dictionary format with the traversability as the key and the cost as the value. * This would also add another bonus: implicitly giving whether or not an agent has a particular movement * type by way of if they have a movement speed listed, instead of needing to explicitly define their movement * types! -- Cost = BaseMovementCost + FastestMovementSpeed / FastestMovementSpeedOnEdgeThatTheAgentCanUse * NOTE: A possible solution for the "cant end movement in a particular tile" problem would be to have a * traversability flag Traversable.CantEndMovementHere and if the (pathCost % (mod) moveSpeed == 0) then reject * that edge in the IsTraversable function, or alternatively in a separate check. */ public virtual IList <GridNode> Search(GridNode start, GridNode goal, Motility motility) { throw new NotImplementedException( "\"A heuristic is required for this algorithm. Use \"Search(IPathfindingNode start, IPathfindingNode end, Traversable traversability, Func<IPathfindingNode, IPathfindingNode, float> heuristic)\" instead."); }
public bool MakeHalls() { List <Vertex> vertices = new List <Vertex>(); // add a vertex at the center of each room foreach (Rect room in _rooms) { vertices.Add(new Vertex <Rect>(new Vector2(room.Center.x, room.Center.y), room)); } // Create a Delaunay triangulation of the rooms _delaunay = Delaunay2D.Triangulate(vertices); // Convert the Delaunay edges to Prim edges List <Prim.Edge> edges = new List <Prim.Edge>(); foreach (Delaunay2D.Edge edge in _delaunay.Edges) { edges.Add(new Prim.Edge(edge.U, edge.V)); } // Create a minimum spanning tree of the triangulation List <Prim.Edge> mst = Prim.MinimumSpanningTree(edges, edges[0].U); // Get the edges not part of the MST HashSet <Prim.Edge> selectedEdges = new HashSet <Prim.Edge>(mst); HashSet <Prim.Edge> remainingEdges = new HashSet <Prim.Edge>(edges); remainingEdges.ExceptWith(selectedEdges); // Create some loops, since MSTs make for boring maps foreach (Prim.Edge edge in remainingEdges) { if (Rng.Int(100) < _writer.Options.ChanceOfExtraHallway) { selectedEdges.Add(edge); } } // Drive a pathfinder to carve out the halls Motility motility = Motility.FourWayNeighbors | Motility.Unconstrained; foreach (Prim.Edge edge in selectedEdges) { Rect startRoom = (edge.U as Vertex <Rect>).Item; Rect endRoom = (edge.V as Vertex <Rect>).Item; GridNode start = _writer.GetTile(new Vec2(startRoom.Center.x, startRoom.Center.y)); GridNode goal = _writer.GetTile(new Vec2(endRoom.Center.x, endRoom.Center.y)); // Heuristic is Manhattan distance on a square grid IList <GridNode> path = _writer.Graph.FindPath <AStarSearchAlgorithm>(start, goal, motility, (a, b) => Math.Abs((float)(a.Position.x - b.Position.x)) + Math.Abs((float)(a.Position.y - b.Position.y))); // Bail if the pathfinder failed to find a path (NOTE: if it does, it seems like it should be a problem) if (path == null) { continue; } foreach (GridNode step in path) { _writer.SetTile(step.Position, Tiles.Floor); foreach (GridNode neighbor in step.Neighbors) { if ((_writer.GetTile(neighbor.Position)).Type == Tiles.Stone) { _writer.SetTile(neighbor.Position, Tiles.Wall); } } } } return(true); }
public IDictionary <GridNode, GridNode> Fill(GridNode start, float searchDepth, Motility motility) { Dictionary <GridNode, GridNode> parentMap = new Dictionary <GridNode, GridNode>(); SimplePriorityQueue <GridNode> frontier = new SimplePriorityQueue <GridNode>(); frontier.Enqueue(start, 0); while (frontier.Count > 0) { GridNode current = frontier.Dequeue(); foreach (GridNode neighbor in current.Neighbors) { IPathfindingEdge edge = current.JoiningEdge(neighbor); //if (!edge.IsTraversable(edge, motility)) continue; float newCost = current.PathCost + edge.Weight; float neighborCost = neighbor.PathCost; bool containsKey = parentMap.ContainsKey(neighbor); if (containsKey && (newCost >= neighborCost) || newCost > searchDepth) { continue; } neighbor.PathCost = newCost; parentMap[neighbor] = current; // UPSERT dictionary function float priority = newCost; frontier.Enqueue(neighbor, priority); } } return(parentMap); }