Exemple #1
0
        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());
        }
Exemple #2
0
        //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);
        }
Exemple #4
0
        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);
 }
Exemple #9
0
        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;
 }