public override void Solve(Map _map) { currentNode = _map.grid[_map.seekerX, _map.seekerY].GetComponent<Node>(); targetNode = _map.grid[_map.targetX, _map.targetY].GetComponent<Node>(); currentNode.distanceFromCharacter = 0; mapToSolve = _map; solvedNodeList = new List<Node>(); unsolvedNodeList = new List<Node>(); solvedKeyNodes = new List<Node>(); for (int x = 0; x < mapToSolve.mapWidth; x++) { for (int y = 0; y < mapToSolve.mapHeight; y++) { unsolvedNodeList.Add(mapToSolve.grid[x, y].GetComponent<Node>()); } } while (!(solvedNodeList.Contains(targetNode)) && currentNode != null) { AnalyseNeighbors(currentNode); unsolvedNodeList.Remove(currentNode); solvedNodeList.Add(currentNode); if (currentNode.nodeType == Node.Type.KEY) { solvedKeyNodes.Add(currentNode); } FindClosestUnsolvedNode(); } _map.nbrOfAnalysedTile.text = solvedNodeList.Count.ToString(); ShowShortestPath(); }
public ControlNode(Vector3 position, bool active, float squareSize) : base(position) { Active = active; Above = new Node(position + Vector3.forward * squareSize / 2f); Right = new Node(position + Vector3.right * squareSize / 2f); }
public Node(Move move, Node parent, State state) { this.random = new Random(); this.state = state; this.generatingMove = move; this.parent = parent; this.results = 0; this.visits = 0; this.children = new List<Node>(); this.untriedMoves = state.GetMoves(); }
void AssignVertices(Node[] points) { for (int i = 0; i < points.Length; i++) { if (points[i].vertexIndex == -1) { points[i].vertexIndex = vertices.Count; vertices.Add(points[i].position); } } }
// Runs a Monte Carlo Tree Search limited by a given time limit public Node TimeLimited(State rootState, int timeLimit, Stopwatch timer) { Node rootNode = new Node(null, null, rootState); while (true) { if (timer.ElapsedMilliseconds > timeLimit) { if (FindBestChild(rootNode.Children) == null && !rootNode.state.IsGameOver()) { timeLimit += 10; timer.Reset(); timer.Start(); } else { return rootNode; } } Node node = rootNode; State state = rootState.Clone(); // 1: Select while (node.UntriedMoves.Count == 0 && node.Children.Count != 0) { node = node.SelectChild(); state = state.ApplyMove(node.GeneratingMove); } // 2: Expand if (node.UntriedMoves.Count != 0) { Move randomMove = node.UntriedMoves[random.Next(0, node.UntriedMoves.Count)]; state = state.ApplyMove(randomMove); node = node.AddChild(randomMove, state); } // 3: Simulation while (state.GetMoves().Count != 0) { state = state.ApplyMove(state.GetRandomMove()); } // 4: Backpropagation while (node != null) { node.Update(state.GetResult()); node = node.Parent; } } }
protected override void AnalyseNeighbors(Node nodeToAnalyse) { foreach (Node neighbor in nodeToAnalyse.neighbors) { if (unsolvedNodeList.Contains(neighbor)) { if (neighbor.nodeType != Node.Type.OBSTACLE) { if (neighbor.nodeType != Node.Type.DOOR) { if (neighbor.nodeType == Node.Type.PUDDLE) { neighbor.distanceFromCharacter = nodeToAnalyse.distanceFromCharacter + Node.PUDDLE_VALUE; } else if (neighbor.nodeType == Node.Type.SWAMP) { neighbor.distanceFromCharacter = nodeToAnalyse.distanceFromCharacter + Node.SWAMP_VALUE; } else if (neighbor.nodeType == Node.Type.ROCKY) { neighbor.distanceFromCharacter = nodeToAnalyse.distanceFromCharacter + Node.ROCKY_VALUE; } else { neighbor.distanceFromCharacter = nodeToAnalyse.distanceFromCharacter + Node.WALKABLE_VALUE; } } if (neighbor.nodeType == Node.Type.DOOR && solvedKeyNodes.Count > 0) { neighbor.distanceFromCharacter = (solvedKeyNodes[0].distanceFromCharacter * 2) + (nodeToAnalyse.distanceFromCharacter + 1); } } } } }
public Square(ControlNode topLeft, ControlNode topRight, ControlNode bottomLeft, ControlNode bottomRight) { TopLeft = topLeft; TopRight = topRight; BottomLeft = bottomLeft; BottomRight = bottomRight; CenterTop = topLeft.Right; CenterRight = bottomRight.Above; CenterBottom = bottomLeft.Right; CenterLeft = bottomLeft.Above; Configuration += Convert.ToInt32(TopLeft.Active) << 3; Configuration += Convert.ToInt32(TopRight.Active) << 2; Configuration += Convert.ToInt32(BottomRight.Active) << 1; Configuration += Convert.ToInt32(BottomLeft.Active); }
void CreateTriangle(Node a, Node b, Node c) { Triangles.Add(a.VertexIndex); Triangles.Add(b.VertexIndex); Triangles.Add(c.VertexIndex); var triangle = new Triangle(a.VertexIndex, b.VertexIndex, c.VertexIndex); AddTriangleToDictionary(triangle.vertexIndexA, triangle); AddTriangleToDictionary(triangle.vertexIndexB, triangle); AddTriangleToDictionary(triangle.vertexIndexC, triangle); }
private void AssigneVertices(Node[] points) { foreach (var point in points) { if (point.VertexIndex == -1) { point.VertexIndex = Vertices.Count; Vertices.Add(point.Position); } } }
protected override void AnalyseNeighbors(Node nodeToAnalyse) { throw new NotImplementedException(); }
private int GetDistance(Node nodeA, Node nodeB) { int disX = nodeB.x - nodeA.x; int disY = nodeB.y - nodeA.y; int handicap = 0; if (disX < 0) { disX *= -1; } if (disY < 0) { disY *= -1; } switch (nodeB.nodeType) { case Node.Type.PUDDLE: handicap = Node.PUDDLE_VALUE * 5; break; case Node.Type.SWAMP: handicap = Node.SWAMP_VALUE * 5; break; case Node.Type.ROCKY: handicap = Node.ROCKY_VALUE * 5; break; } return 10 * (disX + disY) + handicap; }
public override void Solve(Node _start, Node _target, Map _map, bool _realSolve) { openSet = new List<Node>(); closedSet = new HashSet<Node>(); openSet.Add(_start); while (openSet.Count > 0) { currentNode = openSet[0]; for (int i = 1; i < openSet.Count; i++) { if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost) { currentNode = openSet[i]; } } openSet.Remove((currentNode)); closedSet.Add(currentNode); if (currentNode == _target) { if (_target.nodeType == Node.Type.KEY) { if (_realSolve) { nbrOfKeysAcquired++; } } else if (_target.nodeType == Node.Type.TARGET) { if (!_realSolve) { nbrOfKeysNeeded = GetNbrOfDoors(GetPath(_start, _target, false)); doorsToReachEndNode = GetDoorsToReachEndNode(GetPath(_start, _target, false)); } else { numberOfTileAnalysed += closedSet.Count; } } if (_realSolve) { finalPath.AddRange(GetPath(_start, _target, true)); } return; } foreach (Node neighbor in currentNode.neighbors) { if (neighbor.nodeType == Node.Type.OBSTACLE || closedSet.Contains(neighbor)) { continue; } int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbor); if (newMovementCostToNeighbour < neighbor.gCost || !openSet.Contains(neighbor)) { neighbor.gCost = newMovementCostToNeighbour; neighbor.hCost = GetDistance(neighbor, _target); neighbor.parent = currentNode; if (!openSet.Contains(neighbor)) { openSet.Add(neighbor); } } } } numberOfTileAnalysed += openSet.Count; }
private void FindClosestUnsolvedNode() { int shortestDistance = 1000000; Node closestNode = null; foreach (Node node in unsolvedNodeList) { if (node.distanceFromCharacter < shortestDistance) { shortestDistance = node.distanceFromCharacter; closestNode = node; } } currentNode = closestNode; }
//For demo public void initializeLists(Node[] arrayOfNodes) { foreach (var n in arrayOfNodes) { addNode(n); } }
public void addNode(Node n) { //mapGraph.InsertNewVertex(n); poiList.Add(n); storypointList.Add(n); }
protected abstract void AnalyseNeighbors(Node nodeToAnalyse);
public Square(ControlNode _topLeft, ControlNode _topRight, ControlNode _bottomRight, ControlNode _bottomLeft) { topLeft = _topLeft; topRight = _topRight; bottomRight = _bottomRight; bottomLeft = _bottomLeft; centreTop = topLeft.right; centreRight = bottomRight.above; centreBottom = bottomLeft.right; centreLeft = bottomLeft.above; if (topLeft.active) configuration += 8; if (topRight.active) configuration += 4; if (bottomRight.active) configuration += 2; if (bottomLeft.active) configuration += 1; }
public ControlNode(Vector3 _pos, bool _active, float squareSize) : base(_pos) { active = _active; above = new Node(position + Vector3.forward * squareSize / 2f); right = new Node(position + Vector3.right * squareSize / 2f); }
private void FindClosestNeighborToStart() { int shortestDistance = 1000000; Node closestNode = null; foreach (Node neighbor in currentNode.neighbors) { if (neighbor.distanceFromCharacter < shortestDistance) { shortestDistance = neighbor.distanceFromCharacter; closestNode = neighbor; } } currentNode = closestNode; }
// adds a child node to the list of children // after exploring a move - removes the move from untried public Node AddChild(Move move, State state) { Node child = new Node(move, this, state); this.untriedMoves.Remove(move); this.children.Add(child); return child; }
private void ShowShortestPath() { solvedPath = new List<Node>(); currentNode = mapToSolve.grid[mapToSolve.targetX, mapToSolve.targetY].GetComponent<Node>(); while (currentNode != mapToSolve.grid[mapToSolve.seekerX, mapToSolve.seekerY].GetComponent<Node>()) { FindClosestNeighborToStart(); if (currentNode.nodeType == Node.Type.DOOR) { numberOfDoorsPassed++; } solvedPath.Add(currentNode); } while (numberOfDoorsPassed > 0) { int largestDistance = 1000000000; for (int i = 0; i < solvedKeyNodes.Count;i++) { if (solvedKeyNodes[i].distanceFromCharacter + (targetNode.distanceFromCharacter - solvedKeyNodes[i].distanceFromCharacter) < largestDistance) { largestDistance = solvedKeyNodes[i].distanceFromCharacter - (targetNode.distanceFromCharacter - solvedKeyNodes[i].distanceFromCharacter); currentNode = solvedKeyNodes[i]; } } while (currentNode != mapToSolve.grid[mapToSolve.seekerX, mapToSolve.seekerY].GetComponent<Node>()) { FindClosestNeighborToStart(); solvedPath.Add(currentNode); } solvedKeyNodes.RemoveAt(0); numberOfDoorsPassed--; } solvedPath.Reverse(); StartCoroutine(DisplayPath(solvedPath)); }
public virtual void Solve(Node _start, Node _target, Map _map, bool _firstSolve) { }
List<Node> GetPath(Node _start, Node _target, bool _removedKeyOnDoor) { List<Node> path = new List<Node>(); Node currentNode = _target; while (currentNode != _start) { if (currentNode.nodeType == Node.Type.DOOR && _removedKeyOnDoor) { nbrOfKeysAcquired--; if (doorsToReachEndNode != null && doorsToReachEndNode.Contains(currentNode)) { nbrOfKeysNeeded--; } } path.Add(currentNode); currentNode = currentNode.parent; } path.Reverse(); return path; }