public virtual string GenerateChain(int length) { var sb = new StringBuilder(); // Pick a random initiating node. Should only be one in this implementation // For now, just pick the first initiating node MarkovNode targetNode = markovNodes.First(node => node.Type == NodeType.Initiating); // Counter for length int i = 0; // Stick the prefix on the queue for the first node sb.AppendFormat(" {0}", targetNode.Prefix); do { // Stick the suffix. Prefix is not needed because it is the tail for the previous node foreach (var suffix in targetNode.SuffixList) { sb.AppendFormat(" {0}", suffix); } // Get another qualifying node targetNode = pickRandomNode(targetNode); }while (targetNode.Type != NodeType.Terminating && ++i < length); return(sb.ToString()); }
/// <summary> /// Picks a random node that meets the requirements. /// </summary> /// <param name="targetNode">The target node. The tail determines qualification.</param> /// <remarks> /// A node that meets requirements is a node who's prefix is the same as the targetNode's tail. /// </remarks> /// <returns>A qualifying node.</returns> private MarkovNode pickRandomNode(MarkovNode targetNode) { // Pick qualifying node // Generate list of qualifying nodes var qualifyingNodes = ( from node in markovNodes where node.Prefix == targetNode.Tail select node); // Pick random node. Possible bottleneck due to extension code targetNode = qualifyingNodes.ElementAt(rand.Next(qualifyingNodes.Count())); return(targetNode); }