예제 #1
0
 /// <summary>
 /// Used by Query Builder nested class.
 /// See that class for more details on parameters.
 /// </summary>
 public BreadthFirstSearch(
     Func <IGraph <BreadthFirstSearchNode <T> >, int, int, List <BreadthFirstSearchNode <T> > > adjacencyMethod,
     Predicate <IGraphSearchNode <T> > failCondition,
     Predicate <IGraphSearchNode <T> > matchCondition,
     BreadthFirstSearchNode <T>[,] searchGraph,
     IGraph <T> sourceGraph)
 {
     this.adjacencyMethod = adjacencyMethod;
     this.failCondition   = failCondition;
     this.matchCondition  = matchCondition;
     this.searchGraph     = searchGraph;
     this.sourceGraph     = sourceGraph;
 }
예제 #2
0
        /// <summary>
        /// Do a Breadth-First search of the source graph to find a node matching
        /// the provided criteria.
        /// </summary>
        /// <param name="rootX">X position to start the search at.</param>
        /// <param name="rootY">Y position to start the search at.</param>
        /// <returns></returns>
        public BreadthFirstSearchNode <T> SearchAt(int rootX, int rootY)
        {
            if (this.matchCondition == null)
            {
                return(null);
            }

            Queue <BreadthFirstSearchNode <T> > queue = new Queue <BreadthFirstSearchNode <T> >();

            queue.Enqueue(this.searchGraph[rootX, rootY]);

            while (queue.Count > 0)
            {
                BreadthFirstSearchNode <T> currentNode = queue.Dequeue();

                // Found it! Return the node containing successful search path.
                if (this.matchCondition(currentNode))
                {
                    return(currentNode);
                }

                // Still searching.
                List <BreadthFirstSearchNode <T> > adjacentNodes =
                    GetNeighborElements(currentNode.X, currentNode.Y);
                foreach (BreadthFirstSearchNode <T> adjacentNode in adjacentNodes)
                {
                    if (this.failCondition != null &&
                        this.failCondition(adjacentNode))
                    {
                        adjacentNode.SearchStatus = BreadthFirstSearchNode.SearchState.Checked;
                        continue;
                    }

                    if (adjacentNode.SearchStatus == BreadthFirstSearchNode.SearchState.Unchecked)
                    {
                        adjacentNode.SearchStatus = BreadthFirstSearchNode.SearchState.Queued;
                        adjacentNode.PreviousNode = currentNode;
                        queue.Enqueue(adjacentNode);
                    }
                }

                // Finished checking this node.
                currentNode.SearchStatus = BreadthFirstSearchNode.SearchState.Checked;
            }

            // No match found.
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Creates a mirror of an existing graph, but decorated with search markers.
        /// </summary>
        /// <param name="sourceGraph">Graph to duplicate.</param>
        /// <returns></returns>
        private static BreadthFirstSearchNode <T>[,] AssembleSearchArray(IGraph <T> sourceGraph)
        {
            int width  = sourceGraph.Width;
            int height = sourceGraph.Height;

            BreadthFirstSearchNode <T>[,] searchArray = new BreadthFirstSearchNode <T> [width, height];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    searchArray[x, y] =
                        new BreadthFirstSearchNode <T>(sourceGraph.GetElement(x, y), x, y);
                }
            }

            return(searchArray);
        }
 /// <summary>
 /// Create a new query for a graph object.
 /// </summary>
 /// <param name="sourceGraph">Graph to search.</param>
 public Query(IGraph <T> sourceGraph)
 {
     this.sourceGraph = sourceGraph;
     this.searchGraph = AssembleSearchArray(sourceGraph);
 }