public override SearchDetails GetPathTick() { // If there are still nodes on the queue and the destination hasn't been found, evaluate the next node. if (_q.Count > 0 && !_destinationFound) { // Get the next node in the queue and check it hasn't already been visited CurrentNode = _q.Dequeue(); if (AlreadyVisited(CurrentNode.Coord)) { return(GetSearchDetails()); } // Add node to those already visited Closed.Add(CurrentNode); Grid.SetCell(CurrentNode.Coord.X, CurrentNode.Coord.Y, Enums.CellType.Closed); // Go through the neighbours of this node and add the new ones to the queue var neighbours = GetNeighbours(CurrentNode); foreach (var neighbour in neighbours) { if (AlreadyVisited(neighbour)) { continue; } var neighbourNode = new Node(Id++, CurrentNode.Id, neighbour.X, neighbour.Y, 0, 0); _q.Enqueue(neighbourNode); Grid.SetCell(neighbour, Enums.CellType.Open); if (!CoordsMatch(neighbour, Destination)) { continue; } // Check if we've found the destination Closed.Add(neighbourNode); _destinationFound = true; } } else { // The path has been found, reconstruct it be following back via the parentId's and reverse the order so it goes from A to B Path = new List <Coord>(); var step = Closed.First(x => CoordsMatch(x.Coord, Destination)); while (!CoordsMatch(step.Coord, Origin)) { Path.Add(step.Coord); step = Closed.First(x => x.Id == step.ParentId); } Path.Add(Origin); Path.Reverse(); } return(GetSearchDetails()); }
//this method should return true if the Search process finished (i.e either because it found a solution or because there was no solution //it should return false if the search process didn't finish yet //when returning true, the solution parameter should be set to null if there is no solution. Otherwise it must contain the found solution //if the parameter returnPartialSolution is true, then the user wants to have a partial path to the best node so far even when the search has not finished searching public bool Search(out Path solution, bool returnPartialSolution = false) { //to determine the connections of the selected nodeRecord you need to look at the NavigationGraphNode' EdgeOut list //something like this //var outConnections = bestNode.node.OutEdgeCount; //for (int i = 0; i < outConnections; i++) //{ //this.ProcessChildNode(bestNode, bestNode.node.EdgeOut(i)); //Iterate through processing each node NodeRecord current; while (Open.Count() > 0) { //Find the smallest element in the open list, using the estimatedTotalCost() current = Open.GetBestAndRemove(); //If the current node is the goal, terminate if (current.Equals(GoalNode)) { break; } //Otherwise get the outgoing connections var outConnections = current.node.OutEdgeCount; for (int i = 0; i < outConnections; i++) { this.ProcessChildNode(current, current.node.EdgeOut(i)); } Open.Remove(current); Closed.Add(current); } if (current.node != GoalNode) { solution = null; return(true); } else { Path path = new Path(); var nodes = path.PathNodes; var positions = path.PathPositions; while (current.node != StartNode) { nodes += current.parent; current = current.parent.node; } nodes.Reverse(); positions.Reverse(); solution = path; return(true); } }
static Node A_Star(Node root) { var goal = new Node(-1, Goal); Open.Add(root); while (Open.Count != 0) { var node = Open.First(); Closed.Add(node); Open.RemoveAt(0); if (node.Equals(goal)) { return(node); } foreach (var child in node.GenerateChildren()) { var nodeInOpen = Open.Where(x => x.Equals(child)).FirstOrDefault(); var nodeInClosed = Closed.Where(x => x.Equals(child)).FirstOrDefault(); if (child.Equals(goal)) { return(child); } if (nodeInOpen != null) { if (nodeInOpen.Level > child.Level) { Open.Remove(nodeInOpen); Open.Add(child); } } else if (nodeInClosed != null) { if (nodeInClosed.Level > child.Level) { Closed.Remove(nodeInClosed); Open.Add(child); } } else { Open.Add(child); } } Open.Sort((a, b) => a.FScore.CompareTo(b.FScore)); //Open= Open.OrderBy(x => x.FScore).ToList(); } Console.WriteLine("Unsolvable problem"); return(null); }
public override SearchDetails GetPathTick() { // Check the next node on the stack to see if it is the destination CurrentNode = _stack.Peek(); if (CoordsMatch(CurrentNode.Coord, Destination)) { // All the items on the stack will be the path so add them and reverse the order Path = new List <Coord>(); foreach (var item in _stack) { Path.Add(item.Coord); } Path.Reverse(); return(GetSearchDetails()); } // Get all the neighbours that haven't been visited var neighbours = GetNeighbours(CurrentNode).Where(x => !AlreadyVisited(new Coord(x.X, x.Y))).ToArray(); if (neighbours.Any()) { foreach (var neighbour in neighbours) { Grid.SetCell(neighbour.X, neighbour.Y, Enums.CellType.Open); } // Take this neighbour and add it the stack var next = neighbours.First(); var newNode = new Node(Id++, null, next.X, next.Y, 0, 0); _stack.Push(newNode); Grid.SetCell(newNode.Coord.X, newNode.Coord.Y, Enums.CellType.Current); } else { // Remove this unused node from the stack and add it to the closed list var abandonedCell = _stack.Pop(); Grid.SetCell(abandonedCell.Coord.X, abandonedCell.Coord.Y, Enums.CellType.Closed); Closed.Add(abandonedCell); } return(GetSearchDetails()); }
public List <GridSquare> FindPath(Controllers.HomeController.GData d) { ProcessData(d); GridSquare next; List <GridSquare> path = new List <GridSquare>(); List <GridSquare> neighbors; Debug.WriteLine("Target is: " + TargetNode.CoordX + ", " + TargetNode.CoordY); GridSquare current = Nodes[TargetNode.CoordX, TargetNode.CoordY]; while (!IsInBlob(current)) { neighbors = current.VisitNeighbors(Width, Height, this); ProcessNeighbors(neighbors, current); next = Open.Dequeue(); Closed.Add(Nodes[current.CoordX, current.CoordY]); current = Nodes[next.CoordX, next.CoordY]; } path = BacktrackFrom(current); return(path); }
/// <summary> /// Updates only the tiles directly affected by an action, send List of needed elements /// (Only for when revealing new tiles) /// </summary> /// <param name="toupdate">Information about newly revealed tiles</param> /// <param name="mat">The newly revealed tiles of the minesweeper table</param> public override void GetRelevantBoard(KeyValuePair <Vector2Int, MinesweeperElementInfo>[] toupdate, MinesweeperActionType mat) { if (mat == MinesweeperActionType.Uncover) { for (int i = 0; i < toupdate.Length; i++) { //note that every item in toupdate are revealed Vector2Int currentnewrevealed = toupdate[i].Key; MinesweeperElementInfo currentmsei = toupdate[i].Value; //there is always a possibility that the newly revealed tiles are in Open or Safe (when multiple tiles revealed) RemoveForSafety(currentnewrevealed); //add non-empties to 'Closed' if (currentmsei.value != 0) { Closed.Add(currentnewrevealed, currentmsei.value); //iterating through currently revealed tile, finding new tiles while trying to eliminate currentnewrevealed CheckingNewRevealed(currentnewrevealed); //remove from closed if after iteration value become 0 or less if (Closed[currentnewrevealed] <= 0) { WhenRemovingClosedNeighborCheck(currentnewrevealed); } } else { InvalidTiles[currentnewrevealed.x, currentnewrevealed.y] = true; } } } else if (mat == MinesweeperActionType.Flag) { for (int i = 0; i < toupdate.Length; i++) { Vector2Int currentmine = toupdate[i].Key; OnAddingFlaged(currentmine); } } }
/// <summary> /// Checks the whole board /// </summary> /// <param name="table"> The whole minesweeper table</param> public override void GetBoard(MinesweeperElementInfo[,] table) { List <Vector2Int> newpositions = new List <Vector2Int>(); for (int y = 0; y < table.GetLength(1); y++) { for (int x = 0; x < table.GetLength(0); x++) { MinesweeperElementInfo current = table[x, y]; Vector2Int currentpos = new Vector2Int(x, y); if (!current.hidden && current.value > 0) { if (!Closed.ContainsKey(currentpos)) { newpositions.Add(currentpos); } } } } for (int i = 0; i < newpositions.Count; i++) { for (int j = 0; j < Operators.Length; j++) { Vector2Int current = newpositions[i] + Operators[j]; //in bounds if (current.x >= 0 && current.y >= 0 && current.x < table.GetLength(1) && current.y < table.GetLength(0)) { if (table[current.x, current.y].hidden && !table[current.x, current.y].flaged && !Open.ContainsKey(current)) { Open.Add(current, 0); } } } Closed.Add(newpositions[i], table[newpositions[i].x, newpositions[i].y].value); } }
protected override void OnDocumentClosed(EditorDocument document) { Closed.Add(document); }
public override SearchDetails GetPathTick() { if (CurrentNode == null) { if (!_openList.Any()) { return(GetSearchDetails()); } // Take the current node off the open list to be examined CurrentNode = _openList.OrderBy(x => x.F).First(); // Move it to the closed list so it doesn't get examined again _openList.Remove(CurrentNode); Closed.Add(CurrentNode); Grid.SetCell(CurrentNode.Coord, Enums.CellType.Closed); _neighbours.AddRange(GetNeighbours(CurrentNode)); } if (_neighbours.Any()) { Grid.SetCell(CurrentNode.Coord, Enums.CellType.Current); var thisNeighbour = _neighbours.First(); _neighbours.Remove(thisNeighbour); // If the neighbour is the destination if (CoordsMatch(thisNeighbour, Destination)) { // Construct the path by tracing back through the closed list until there are no more parent id references Path = new List <Coord> { thisNeighbour }; int?parentId = CurrentNode.Id; while (parentId.HasValue) { var nextNode = Closed.First(x => x.Id == parentId); Path.Add(nextNode.Coord); parentId = nextNode.ParentId; } // Reorder the path to be from origin to destination and return Path.Reverse(); return(GetSearchDetails()); } // Get the cost of the current node plus the extra step var cellWeight = Grid.GetCell(thisNeighbour.X, thisNeighbour.Y).Weight; var neighbourCost = CurrentNode.G + cellWeight; // Check if the node is on the open list already and if it has a higher cost path var openListItem = _openList.FirstOrDefault(x => x.Id == GetExistingNode(true, thisNeighbour)); if (openListItem != null && openListItem.F > neighbourCost) { // Repoint the openlist node to use this lower cost path openListItem.F = neighbourCost; openListItem.ParentId = CurrentNode.Id; } // Check if the node is on the closed list already and if it has a higher cost path var closedListItem = Closed.FirstOrDefault(x => x.Id == GetExistingNode(false, thisNeighbour)); if (closedListItem != null && closedListItem.F > neighbourCost) { // Repoint the closedlist node to use this lower cost path closedListItem.F = neighbourCost; closedListItem.ParentId = CurrentNode.Id; } // If the neighbour node isn't on the open or closed list, add it if (openListItem != null || closedListItem != null) { return(GetSearchDetails()); } _openList.Add(new Node(Id++, CurrentNode.Id, thisNeighbour, CurrentNode.G + cellWeight, 0)); Grid.SetCell(thisNeighbour.X, thisNeighbour.Y, Enums.CellType.Open); } else { Grid.SetCell(CurrentNode.Coord, Enums.CellType.Closed); CurrentNode = null; return(GetPathTick()); } return(GetSearchDetails()); }
public void RemoveByte(ushort offset) { Closed.Add(offset); AllowModeChange = true; }
public void RemoveWord(ushort offset) { Closed.Add(offset); Closed.Add((ushort)(offset + 1)); AllowModeChange = true; }