private int DFS(HashSet <string> clay, Node spring, int ymax, int ymin, Dictionary <string, Node> seen) { var stack = new StackSet <Node>(); stack.Push(spring); var answer = 0; while (stack.Any()) { var current = stack.Pop(); seen[current.Location.Hash] = current; if (current.Location.Y <= ymax && current.Location.Y >= ymin && !current.Visited) { current.Visited = true; answer++; } if (current.Location.Y > ymax) { MarkFlowing(current, stack, clay, seen); continue; } PrintArea(stack, clay, seen, current, false); // down if (!clay.Contains(current.Location.Down.Hash)) { if (!seen.ContainsKey(current.Location.Down.Hash)) { var node = new Node(current.Location.Down, current); stack.Push(node); continue; } else if (seen[current.Location.Down.Hash].Flowing) { MarkFlowing(current, stack, clay, seen); continue; } } var leftAdded = false; var rightAdded = false; // check left if (!clay.Contains(current.Location.Left.Hash)) { if (!seen.ContainsKey(current.Location.Left.Hash)) { var newLeft = new Node(current.Location.Left, current) { Right = current }; current.Left = newLeft; stack.Push(newLeft); leftAdded = true; } else if (seen[current.Location.Left.Hash].Flowing) { current.Flowing = true; } } // check Right if (!clay.Contains(current.Location.Right.Hash)) { if (!seen.ContainsKey(current.Location.Right.Hash)) { var newRight = new Node(current.Location.Right, current) { Left = current }; current.Right = newRight; stack.Push(newRight); rightAdded = true; } else if (seen[current.Location.Right.Hash].Flowing) { current.Flowing = true; } } if (!leftAdded && !rightAdded && current.Previous != null) { stack.Push(current.Previous); } } return(answer); }