diff --git a/.gitignore b/.gitignore index 26f6612..00ec382 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ /Syllabore/.vs/Syllabore/v17 /Syllabore/.vs/Syllabore/FileContentIndex /Syllabore/.vs/ProjectEvaluation +/Syllabore/Syllabore.Example/bin/Debug/net7.0 diff --git a/Syllabore/Syllabore.Example/Syllabore.Example.csproj b/Syllabore/Syllabore.Example/Syllabore.Example.csproj index b315cc8..5eceedb 100644 --- a/Syllabore/Syllabore.Example/Syllabore.Example.csproj +++ b/Syllabore/Syllabore.Example/Syllabore.Example.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net7.0 diff --git a/Syllabore/Syllabore/DefaultSyllableGenerator.cs b/Syllabore/Syllabore/DefaultSyllableGenerator.cs index 35c1695..7d9fe2f 100644 --- a/Syllabore/Syllabore/DefaultSyllableGenerator.cs +++ b/Syllabore/Syllabore/DefaultSyllableGenerator.cs @@ -1,17 +1,23 @@ using System; using System.Collections.Generic; using System.Text; +using static System.Net.WebRequestMethods; namespace Syllabore { /// - /// /// The default syllable provider used by a vanilla instance /// of . - /// /// public class DefaultSyllableGenerator : SyllableGenerator { + /// + /// Instantiates a new + /// containing a subset of consonants and vowels from the English + /// language. See further details in the wiki at + /// + /// https://github.com/kesac/Syllabore/wiki/DefaultSyllableGenerator. + /// public DefaultSyllableGenerator() { this.WithLeadingConsonants("bdlmprst"); @@ -22,7 +28,6 @@ public DefaultSyllableGenerator() this.WithProbability(x => x .OfLeadingConsonants(0.95, 0.25) .OfFinalConsonants(0.50, 0.25)); - } } } diff --git a/Syllabore/Syllabore/DeprecatedDefaultNameTransformer.cs b/Syllabore/Syllabore/DeprecatedDefaultNameTransformer.cs index 59bdc05..b6bd59c 100644 --- a/Syllabore/Syllabore/DeprecatedDefaultNameTransformer.cs +++ b/Syllabore/Syllabore/DeprecatedDefaultNameTransformer.cs @@ -5,8 +5,10 @@ namespace Syllabore { /// - /// This transformer creates variations of names by replacing one syllable - /// with another syllable. Syllables are derived from . + /// Deprecated. This transformer was originally used to + /// create variations of names by replacing one syllable + /// with another syllable. Syllables were derived from + /// . /// [Obsolete("No longer used", false)] public class DefaultNameTransformer : NameTransformer @@ -15,6 +17,9 @@ public class DefaultNameTransformer : NameTransformer private Random Random { get; set; } + /// + /// Deprecated. No longer used. + /// [Obsolete("No longer used", false)] public DefaultNameTransformer() { diff --git a/Syllabore/Syllabore/DeprecatedNameTransformer.cs b/Syllabore/Syllabore/DeprecatedNameTransformer.cs index aab5789..a109d90 100644 --- a/Syllabore/Syllabore/DeprecatedNameTransformer.cs +++ b/Syllabore/Syllabore/DeprecatedNameTransformer.cs @@ -4,6 +4,9 @@ namespace Syllabore { + /// + /// Deprecated. Use instead. + /// [Obsolete("Use TransformSet instead", false)] public class NameTransformer : TransformSet { } } diff --git a/Syllabore/Syllabore/GeneratorProbability.cs b/Syllabore/Syllabore/GeneratorProbability.cs index 61e2962..d59e1b5 100644 --- a/Syllabore/Syllabore/GeneratorProbability.cs +++ b/Syllabore/Syllabore/GeneratorProbability.cs @@ -6,22 +6,68 @@ namespace Syllabore { /// - /// Contains probability settings in a . + /// Contains the probability settings of a . /// public class GeneratorProbability { + /// + /// The probability that a leading vowel exists in the starting syllable. In other + /// words, this is the probability that a name starts with a vowel rather than a consonant. + /// public double? ChanceStartingSyllableLeadingVowelExists { get; set; } + + /// + /// The probability that a leading vowel in the starting syllable is a sequence. In other + /// words, this is the probability that a name starts with a vowel sequence rather than a consonant. + /// public double? ChanceStartingSyllableLeadingVowelIsSequence { get; set; } + + /// + /// The probability that a leading consonant exists in a syllable. A leading + /// consonant is a consonant that appears before a vowel in a syllable. + /// public double? ChanceLeadingConsonantExists { get; set; } + + /// + /// The probability that a leading consonant in a syllable is a sequence. A leading + /// consonant sequence is a consonant sequence that appears before a vowel in a syllable. + /// public double? ChanceLeadingConsonantIsSequence { get; set; } + + /// + /// The probability that a vowel exists in a syllable. + /// public double? ChanceVowelExists { get; set; } + + /// + /// The probability that a vowel in a syllable is a sequence. + /// public double? ChanceVowelIsSequence { get; set; } + + /// + /// The probability that a trailing consonant exists in a syllable. A trailing + /// consonant is a consonant that appears after a vowel in a syllable. + /// public double? ChanceTrailingConsonantExists { get; set; } + + /// + /// The probability that a trailing consonant in a syllable is a sequence. A trailing + /// consonant is a consonant that appears after a vowel in a syllable. + /// public double? ChanceTrailingConsonantIsSequence { get; set; } - public double? ChanceFinalConsonantExists { get; set; } - public double? ChanceFinalConsonantIsSequence { get; set; } - public GeneratorProbability() { } + /// + /// The probability that a final consonant exists in a syllable. Final consonants + /// are the same as trailing consonants excecpt they only appear in the final + /// syllable of a name. + /// + public double? ChanceFinalConsonantExists { get; set; } + /// + /// The probability that a final consonant in a syllable is a sequence. Final consonants + /// are the same as trailing consonants excecpt they only appear in the final + /// syllable of a name. + /// + public double? ChanceFinalConsonantIsSequence { get; set; } } } diff --git a/Syllabore/Syllabore/Grapheme.cs b/Syllabore/Syllabore/Grapheme.cs index 62ef289..1a26437 100644 --- a/Syllabore/Syllabore/Grapheme.cs +++ b/Syllabore/Syllabore/Grapheme.cs @@ -6,18 +6,27 @@ namespace Syllabore { /// /// - /// A is the most basic indivisible unit - /// of a writing system. In Syllabore, they - /// can represent a single vowel, consonant, or sequence. - /// - /// - /// s are used by s - /// to construct syllables. + /// A is an indivisible unit of a + /// writing system. In Syllabore, Graphemes + /// are used to represent vowels, consonants, or sequences. + /// Graphemes are used directly by + /// SyllableGenerators + /// when constructing syllables. /// /// public class Grapheme : IWeighted { + /// + /// The vowel, consonant, or sequence that + /// this represents. + /// public string Value { get; set; } + + /// + /// The weight of occurrence for this + /// . By default the + /// value is 1. + /// public int Weight { get; set; } /// diff --git a/Syllabore/Syllabore/INameGenerator.cs b/Syllabore/Syllabore/INameGenerator.cs index 8160aa6..1470792 100644 --- a/Syllabore/Syllabore/INameGenerator.cs +++ b/Syllabore/Syllabore/INameGenerator.cs @@ -11,7 +11,8 @@ namespace Syllabore public interface INameGenerator : IGenerator { /// - /// Returns a new name of the specified syllable length. + /// Returns a string representing a name of the specified syllable length. + /// Note that syllable length is not the same as string length. /// string Next(int syllableLength); @@ -22,6 +23,7 @@ public interface INameGenerator : IGenerator /// /// Returns a new of the specified syllable length. + /// Note that syllable length is not the same as string length. /// Name NextName(int syllableLength); } diff --git a/Syllabore/Syllabore/Json/JsonPropertyCast.cs b/Syllabore/Syllabore/Json/JsonPropertyCast.cs index 5018d9a..3a85546 100644 --- a/Syllabore/Syllabore/Json/JsonPropertyCast.cs +++ b/Syllabore/Syllabore/Json/JsonPropertyCast.cs @@ -6,20 +6,34 @@ namespace Syllabore.Json { + /// + /// A special kind of + /// that's only role is to cast the value of a property to a different . + /// public class JsonPropertyCast : JsonConverter { private Type TargetType; + /// + /// Instantiates a new that will + /// cast properties to the specified . + /// public JsonPropertyCast(Type targetType) { this.TargetType = targetType; } + /// + /// Override. Reads the value of a property and casts it to the specified . + /// public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return (T)JsonSerializer.Deserialize(ref reader, this.TargetType, options); } + /// + /// Override. Writes the value of a property and casts it to the specified . + /// public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, this.TargetType, options); diff --git a/Syllabore/Syllabore/Json/NameGeneratorSerializer.cs b/Syllabore/Syllabore/Json/NameGeneratorSerializer.cs index 9b8b70f..1dca6b5 100644 --- a/Syllabore/Syllabore/Json/NameGeneratorSerializer.cs +++ b/Syllabore/Syllabore/Json/NameGeneratorSerializer.cs @@ -22,10 +22,27 @@ public class NameGeneratorSerializer /// private static readonly char[] AllowedCharacters = { '\r', '\n', '\u0022' }; - public Type ProviderType { get; set; } + /// + /// The class of a 's + /// property. + /// + public Type ProviderType { get; set; } // TODO: Rename + + /// + /// The class of a 's + /// property. + /// public Type TransformerType { get; set; } + + /// + /// The class of a 's + /// property. + /// public Type FilterType { get; set; } + /// + /// Creates a new instance of . + /// public NameGeneratorSerializer() { this.ProviderType = typeof(SyllableGenerator); diff --git a/Syllabore/Syllabore/Name.cs b/Syllabore/Syllabore/Name.cs index 8e2f2bc..2127ddf 100644 --- a/Syllabore/Syllabore/Name.cs +++ b/Syllabore/Syllabore/Name.cs @@ -9,12 +9,12 @@ namespace Syllabore public class Name { /// - /// Ordered syllables that make up this name. + /// The ordered syllables that make up this name. /// public List Syllables { get; set; } /// - /// An empty name. + /// Instantiates an empty name. /// public Name() { @@ -22,7 +22,7 @@ public Name() } /// - /// Instantiates a name with the desired starting syllables. + /// Instantiates a new name with the desired starting syllables. /// /// public Name(params string[] syllable) @@ -31,7 +31,7 @@ public Name(params string[] syllable) } /// - /// Instantiates a name that is a copy of the specified name. (This constructor + /// Instantiates a new name that is a copy of the specified name. (This constructor /// is useful for a .) /// /// @@ -50,16 +50,26 @@ public override string ToString() return result.Substring(0, 1).ToUpper() + result.Substring(1).ToLower(); } + /// + /// A is equal to another + /// if and only if their + /// string representations are also equal. + /// public override bool Equals(object obj) { - if(obj is Name){ - return (((Name)obj).ToString() == this.ToString()); + if (obj is Name name) + { + return (name.ToString() == this.ToString()); } return false; } - public override int GetHashCode() + + /// + /// Returns a hash code for this . + /// + public override int GetHashCode() // Needs to exist for the Equals() override. { return base.GetHashCode(); } diff --git a/Syllabore/Syllabore/NameFilter.cs b/Syllabore/Syllabore/NameFilter.cs index c39771d..e8d72de 100644 --- a/Syllabore/Syllabore/NameFilter.cs +++ b/Syllabore/Syllabore/NameFilter.cs @@ -5,20 +5,54 @@ namespace Syllabore { - + /// + /// The type of condition that a + /// uses. + /// public enum FilterCondition { + /// + /// Condition is met if the name contains a specific substring. + /// Contains, + + /// + /// Condition is met if the name starts with a specific substring. + /// StartsWith, + + /// + /// Condition is met if the name ends with a specific substring. + /// EndsWith, + + /// + /// Condition is met if the name matches a specific regular expression. + /// MatchesPattern } + /// + /// A constraint used by a when + /// testing names for validity. + /// public class FilterConstraint { + /// + /// The type of condition names will be tested against. + /// (eg. Contains, StartsWith, EndsWith, MatchesPattern) + /// public FilterCondition Type { get; set; } + + /// + /// The value that names will be tested against (in conjunction + /// with ). + /// public string Value { get; set; } + /// + /// Creates a new with the specified condition and value. + /// public FilterConstraint(FilterCondition type, string value) { this.Type = type; @@ -33,8 +67,14 @@ public FilterConstraint(FilterCondition type, string value) [Serializable] public class NameFilter : INameFilter { + /// + /// The list of constraints that names must pass to be considered valid. + /// public List Constraints { get; set; } + /// + /// Instantiates a new with no constraints. + /// public NameFilter() { this.Constraints = new List(); @@ -83,7 +123,6 @@ public NameFilter DoNotAllowStart(params string[] prefixes) foreach (string s in prefixes) { this.Constraints.Add(new FilterConstraint(FilterCondition.StartsWith, s)); - // this.Conditions.Add("^" + s.Trim()); } return this; diff --git a/Syllabore/Syllabore/NameFormatter.cs b/Syllabore/Syllabore/NameFormatter.cs index 2a9b8b7..f883cdf 100644 --- a/Syllabore/Syllabore/NameFormatter.cs +++ b/Syllabore/Syllabore/NameFormatter.cs @@ -23,6 +23,11 @@ public class NameFormatter : IGenerator /// /// public string Format { get; set; } + + /// + /// The NameGenerators + /// used by this . + /// public Dictionary BoundNameGenerators { get; set; } /// diff --git a/Syllabore/Syllabore/NameGenerator.cs b/Syllabore/Syllabore/NameGenerator.cs index 039161e..11f298d 100644 --- a/Syllabore/Syllabore/NameGenerator.cs +++ b/Syllabore/Syllabore/NameGenerator.cs @@ -19,10 +19,21 @@ namespace Syllabore /// public class NameGenerator : INameGenerator { + + /// + /// + /// The default maximum number of attempts a + /// will make to satisfy its own . If the maximum + /// number of attempts is exceeded, an will be thrown. + /// + /// + /// Hitting the limit is indicative of a that + /// can never satisfy its own . + /// + /// private const int DefaultMaximumRetries = 1000; - // private const double DefaultTransformChance = 1.0; - private Random Random { get; set; } + private Random _random; /// /// @@ -37,22 +48,22 @@ public class NameGenerator : INameGenerator public ISyllableGenerator Provider { get; set; } /// - /// /// The name transformer used during name generation. /// A vanilla will not use a /// transformer by default. - /// /// public INameTransformer Transformer { get; set; } + /// + /// The probability that a name will be transformed + /// during the generation process. + /// public double TransformerChance { get; set; } /// - /// /// The filter used to validate a 's output. /// A vanilla will not use a /// filter by default. - /// /// public INameFilter Filter { get; set; } @@ -126,7 +137,7 @@ public NameGenerator(ISyllableGenerator provider, INameTransformer transformer, this.UsingFilter(filter); } - this.Random = new Random(); + _random = new Random(); } #endregion @@ -161,7 +172,7 @@ public NameGenerator UsingProvider(ISyllableGenerator provider) /// Sets the syllable generator of this to the specified . /// /// - /// When multiple calls to this method or are made, the last call will take precedence. + /// When multiple calls to this method or are made, the last call will take precedence. /// /// public NameGenerator UsingSyllables(Func configure) @@ -175,7 +186,7 @@ public NameGenerator UsingSyllables(Func c /// Sets the syllable generator of this to the specified . /// /// - /// When multiple calls to this method or are made, the last call will take precedence. + /// When multiple calls to this method are made, the last call will take precedence. /// /// public NameGenerator UsingSyllables(ISyllableGenerator provider) @@ -232,23 +243,6 @@ public NameGenerator DoNotAllow(params string[] regex) #region Transformations - /* - /// - /// Sets the name transformer of this to the specified . - /// A vanilla does not use transformers by default. - /// - /// The name transformer will be applied to every generated name. - /// - /// - /// When multiple calls to this method is made, the last call will take precedence. - /// - /// - public NameGenerator UsingTransforms(Func configure) - { - return this.UsingTransforms(1.0, configure); - } - */ - /// /// Sets the name transformer of this to the specified . /// A vanilla does not use transformers by default. @@ -394,10 +388,11 @@ public NameGenerator LimitRetries(int limit) /// /// - /// Generates and returns a random name. The name will be consistent with this 's syllable provider, name transformer (if it is used), and name filter (if it is used). + /// Generates and returns a random name. The name will be consistent with this 's + /// syllable provider, name transformer (if it is used), and name filter (if it is used). /// /// - /// If you need to access to individual syllables of a name, use instead. + /// If you need to access to individual syllables of a name, use instead. /// /// public string Next() @@ -410,7 +405,7 @@ public string Next() throw new InvalidOperationException("The value of property MinimumSyllables must be less than or equal to property MaximumSyllables. Both values must be postive integers."); } - var syllableLength = this.Random.Next(this.MinimumSyllables, this.MaximumSyllables + 1); + var syllableLength = _random.Next(this.MinimumSyllables, this.MaximumSyllables + 1); return this.Next(syllableLength); } @@ -422,7 +417,7 @@ public string Next() /// syllable provider, name transformer (if it is used), and name filter (if it is used). /// /// - /// If you need to access to individual syllables of a name, use instead. + /// If you need to access to individual syllables of a name, use instead. /// /// public string Next(int syllableLength) @@ -441,7 +436,7 @@ public Name NextName() throw new InvalidOperationException("The value of property MinimumSyllables must be less than or equal to property MaximumSyllables. Both values must be postive integers."); } - var syllableLength = this.Random.Next(this.MinimumSyllables, this.MaximumSyllables + 1); + var syllableLength = _random.Next(this.MinimumSyllables, this.MaximumSyllables + 1); return this.NextName(syllableLength); } @@ -469,7 +464,6 @@ public Name NextName(int syllableLength) { if (i == 0 && syllableLength > 1) { - //result.Syllables[i] = this.Provider.NextStartingSyllable(); result.Syllables.Add(this.Provider.NextStartingSyllable()); } else if (i == syllableLength - 1 && syllableLength > 1) @@ -482,11 +476,7 @@ public Name NextName(int syllableLength) } } - //if (this.Transformer != null - // && this.Transformer.TransformChance.HasValue - // && this.Random.NextDouble() < this.Transformer.TransformChance) - //if (this.Transformer != null) - if (this.Transformer != null && this.Random.NextDouble() < this.TransformerChance) + if (this.Transformer != null && _random.NextDouble() < this.TransformerChance) { result = this.Transformer.Apply(result); } diff --git a/Syllabore/Syllabore/SyllableGenerator.cs b/Syllabore/Syllabore/SyllableGenerator.cs index 0209bfe..f598921 100644 --- a/Syllabore/Syllabore/SyllableGenerator.cs +++ b/Syllabore/Syllabore/SyllableGenerator.cs @@ -13,24 +13,86 @@ namespace Syllabore /// public enum Context { + /// + /// Default generator context. + /// None, + + /// + /// The last added grapheme(s) are leading consonants. + /// LeadingConsonant, + + /// + /// The last added grapheme(s) are leading consonant sequences. + /// LeadingConsonantSequence, + + /// + /// The last added grapheme(s) are vowels. + /// Vowel, + + /// + /// The last added grapheme(s) are vowel sequences. + /// VowelSequence, + + /// + /// The last added grapheme(s) are trailing consonants. + /// TrailingConsonant, + + /// + /// The last added grapheme(s) are trailing consonant sequences. + /// TrailingConsonantSequence, + + /// + /// The last added grapheme(s) are final consonants. + /// LeadingVowelInStartingSyllable, + + /// + /// The last added grapheme(s) are final consonant sequences. + /// LeadingVowelSequenceInStartingSyllable, + + /// + /// The last added grapheme(s) are final consonants. + /// FinalConsonant, + + /// + /// The last added grapheme(s) are final consonant sequences. + /// FinalConsonantSequence } + /// + /// Descriptors for the position of a syllable within a name. + /// public enum SyllablePosition { + /// + /// An indeterminate position. + /// Unknown, + + /// + /// The first syllable of a name. + /// Starting, + + /// + /// Any position that is not the + /// first or last syllable of a name. + /// Middle, + + /// + /// The last syllable of a name. + /// Ending } @@ -53,22 +115,78 @@ public class SyllableGenerator : ISyllableGenerator private const double DefaultChanceFinalConsonantBecomesSequence = 0.25; // Only if consonant final sequences are supplied - private Random Random { get; set; } - private Context Context { get; set; } // For contextual command .Sequences() - private List LastChanges { get; set; } // For contextual command .Weight() + private Random _random { get; set; } + private Context _context { get; set; } // For contextual command .Sequences() + private List _lastChanges { get; set; } // For contextual command .Weight() + + /// + /// Leading consonants are consonants that appear before + /// the vowel within a syllable. + /// public List LeadingConsonants { get; set; } + + /// + /// Leading consonants sequences are sequences that appear + /// before the vowel within a syllable. Consonant sequences are made + /// up of more than one , but are treated + /// like a single consonant during syllable generation. + /// public List LeadingConsonantSequences { get; set; } + + /// + /// The vowels that can appear within a syllable. + /// public List Vowels { get; set; } + + /// + /// The vowel sequences that can appear within a syllable. + /// Sequences are made up of more than one + /// , but treated as a single vowel. + /// public List VowelSequences { get; set; } + + /// + /// Trailing consonants are consonants that appear after + /// the vowel within a syllable. + /// public List TrailingConsonants { get; set; } + + /// + /// Trailing consonant sequences are sequences that appear + /// after the vowel within a syllable. Consonant sequences are made + /// up of more than one , but are treated + /// like a single consonant during syllable generation. + /// public List TrailingConsonantSequences { get; set; } + + /// + /// Final consonants are identical to trailing consonants, except + /// they only appear in the final syllable of a name. + /// public List FinalConsonants { get; set; } + + /// + /// Final consonant sequences are identical to trailing consonant sequences, + /// except they only appear in the final syllable of a name. + /// public List FinalConsonantSequences { get; set; } + + /// + /// The probability settings for this . + /// public GeneratorProbability Probability { get; set; } + + /// + /// When true, will not throw an exception + /// when it generates an empty string. By default, this is false. + /// public bool AllowEmptyStringGeneration { get; set; } #region Convenience Properties + /// + /// Returns true if the probability of a leading consonant being generated is greater than zero. + /// public bool LeadingConsonantsAllowed { get @@ -77,6 +195,9 @@ public bool LeadingConsonantsAllowed } } + /// + /// Returns true if the probability of a leading consonant sequence being generated is greater than zero. + /// public bool LeadingConsonantSequencesAllowed { get @@ -85,6 +206,9 @@ public bool LeadingConsonantSequencesAllowed } } + /// + /// Returns true if the probability of a vowel being generated is greater than zero. + /// public bool VowelsAllowed { get @@ -93,6 +217,9 @@ public bool VowelsAllowed } } + /// + /// Returns true if the probability of a vowel sequence being generated is greater than zero. + /// public bool VowelSequencesAllowed { get @@ -101,6 +228,9 @@ public bool VowelSequencesAllowed } } + /// + /// Returns true if the probability of a trailing consonant being generated is greater than zero. + /// public bool TrailingConsonantsAllowed { get @@ -109,6 +239,9 @@ public bool TrailingConsonantsAllowed } } + /// + /// Returns true if the probability of a trailing consonant sequence being generated is greater than zero. + /// public bool TrailingConsonantSequencesAllowed { get @@ -117,6 +250,9 @@ public bool TrailingConsonantSequencesAllowed } } + /// + /// Returns true if the probability of a final consonant being generated is greater than zero. + /// public bool FinalConsonantsAllowed { get @@ -125,6 +261,9 @@ public bool FinalConsonantsAllowed } } + /// + /// Returns true if the probability of a final consonant sequence being generated is greater than zero. + /// public bool FinalConsonantSequencesAllowed { get @@ -133,32 +272,40 @@ public bool FinalConsonantSequencesAllowed } } + /// + /// Returns true if the probability of a leading vowel being generated within the starting syllable is greater than zero. + /// public bool LeadingVowelForStartingSyllableAllowed { get { - //return Probability.StartingSyllable.ChanceLeadingVowelExists.HasValue && Probability.StartingSyllable.ChanceLeadingVowelExists > 0; return Probability.ChanceStartingSyllableLeadingVowelExists.HasValue && Probability.ChanceStartingSyllableLeadingVowelExists > 0; } } + /// + /// Returns true if the probability of a leading vowel sequence being generated within the starting syllable is greater than zero. + /// public bool LeadingVowelSequenceForStartingSyllableAllowed { get { - // return Probability.StartingSyllable.ChanceLeadingVowelBecomesSequence.HasValue && Probability.StartingSyllable.ChanceLeadingVowelBecomesSequence > 0; return Probability.ChanceStartingSyllableLeadingVowelIsSequence.HasValue && Probability.ChanceStartingSyllableLeadingVowelIsSequence > 0; } } #endregion + /// + /// Instantiates a new with + /// an empty pool of vowels and consonants. + /// public SyllableGenerator() { - this.Random = new Random(); + _random = new Random(); this.Probability = new GeneratorProbability(); - this.Context = Context.None; - this.LastChanges = new List(); + _context = Context.None; + _lastChanges = new List(); this.AllowEmptyStringGeneration = false; this.LeadingConsonants = new List(); @@ -172,7 +319,10 @@ public SyllableGenerator() } /// - /// Adds the specified consonants as consonants that can occur before or after a vowel. + /// Adds the specified consonants into the pool of leading and trailing + /// consonants. Within a syllable, leading consonants are consonants + /// that appear before a vowel and trailing consonants are consonants + /// that appear after a vowel. /// public SyllableGenerator WithConsonants(params string[] consonants) { @@ -185,7 +335,7 @@ public SyllableGenerator WithConsonants(params string[] consonants) this.LeadingConsonants.AddRange(changes); this.TrailingConsonants.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if (this.Probability.ChanceLeadingConsonantExists == null) { @@ -197,13 +347,14 @@ public SyllableGenerator WithConsonants(params string[] consonants) this.Probability.ChanceTrailingConsonantExists = DefaultChanceTrailingConsonantExists; } - this.Context = Context.None; + _context = Context.None; return this; } /// - /// Adds the specified consonants as consonants that can occur before a vowel. + /// Adds the specified consonants to the pool of leading consonants. + /// Within a syllable, leading consonants are consonants that appear before a vowel. /// public SyllableGenerator WithLeadingConsonants(params string[] consonants) { @@ -216,41 +367,42 @@ public SyllableGenerator WithLeadingConsonants(params string[] consonants) } this.LeadingConsonants.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if (this.Probability.ChanceLeadingConsonantExists == null) { this.Probability.ChanceLeadingConsonantExists = DefaultChanceLeadingConsonantExists; } - this.Context = Context.LeadingConsonant; + _context = Context.LeadingConsonant; return this; } /// - /// Adds the specified consonant sequences as sequences that can occur before a vowel. + /// Adds the specified consonant sequences into the pool of leading consonant sequences. /// public SyllableGenerator WithLeadingConsonantSequences(params string[] consonantSequences) { var changes = consonantSequences.Select(x => new Grapheme(x)).ToList(); this.LeadingConsonantSequences.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if(this.Probability.ChanceLeadingConsonantIsSequence == null) { this.Probability.ChanceLeadingConsonantIsSequence = DefaultChanceLeadingConsonantBecomesSequence; } - this.Context = Context.LeadingConsonantSequence; + _context = Context.LeadingConsonantSequence; return this; } /// - /// Adds the specified vowels as vowels that can be used to form the 'center' of syllables. + /// Adds the specified vowels to the pool of possible vowels this + /// can generate. /// public SyllableGenerator WithVowels(params string[] vowels) { @@ -262,40 +414,43 @@ public SyllableGenerator WithVowels(params string[] vowels) } this.Vowels.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if (this.Probability.ChanceVowelExists == null) { this.Probability.ChanceVowelExists = DefaultChanceVowelExists; } - this.Context = Context.Vowel; + _context = Context.Vowel; return this; } /// - /// Adds the specified vowel sequences as sequences that can be used to form the 'center' of syllables. + /// Adds the specified vowel sequences to the pool of possible vowel sequences this + /// can generate. /// public SyllableGenerator WithVowelSequences(params string[] vowelSequences) { var changes = vowelSequences.Select(x => new Grapheme(x)).ToList(); this.VowelSequences.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if(this.Probability.ChanceVowelIsSequence == null) { this.Probability.ChanceVowelIsSequence = DefaultChanceVowelBecomesSequence; } - this.Context = Context.VowelSequence; + _context = Context.VowelSequence; return this; } /// - /// Adds the specified consonants as consonants that can appear after a vowel. + /// Adds the specified consonants to the pool of trailing consonants. + /// Within a syllable, trailing consonants are consonants that appear + /// after a vowel. /// public SyllableGenerator WithTrailingConsonants(params string[] consonants) { @@ -307,14 +462,14 @@ public SyllableGenerator WithTrailingConsonants(params string[] consonants) } this.TrailingConsonants.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if (this.Probability.ChanceTrailingConsonantExists == null) { this.Probability.ChanceTrailingConsonantExists = DefaultChanceTrailingConsonantExists; } - this.Context = Context.TrailingConsonant; + _context = Context.TrailingConsonant; return this; } @@ -327,21 +482,21 @@ public SyllableGenerator WithTrailingConsonantSequences(params string[] consonan { var changes = consonantSequences.Select(x => new Grapheme(x)).ToList(); this.TrailingConsonantSequences.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if(this.Probability.ChanceTrailingConsonantIsSequence == null) { this.Probability.ChanceTrailingConsonantIsSequence = DefaultChanceTrailingConsonantBecomesSequence; } - this.Context = Context.TrailingConsonantSequence; + _context = Context.TrailingConsonantSequence; return this; } /// - /// Adds the specified consonants as consonants that only appear - /// as the final consonant in an ending syllable. + /// Adds the specified consonants to the pool of consonants that must only appear + /// as the trailing consonant of an ending syllable. /// public SyllableGenerator WithFinalConsonants(params string[] consonants) { @@ -353,45 +508,45 @@ public SyllableGenerator WithFinalConsonants(params string[] consonants) } this.FinalConsonants.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if (this.Probability.ChanceFinalConsonantExists == null) { this.Probability.ChanceFinalConsonantExists = DefaultChanceFinalConsonantExists; } - this.Context = Context.FinalConsonant; + _context = Context.FinalConsonant; return this; } /// - /// Adds the specified final consonant sequences as sequences that can only appear - /// as the final consonant sequence in an ending syllable. + /// Adds the specified consonant sequences to the pool of sequences that must only appear + /// as the trailing consonant sequence of an ending syllable. /// public SyllableGenerator WithFinalConsonantSequences(params string[] consonantSequences) { var changes = consonantSequences.Select(x => new Grapheme(x)).ToList(); this.FinalConsonantSequences.AddRange(changes); - this.LastChanges.ReplaceWith(changes); + _lastChanges.ReplaceWith(changes); if (this.Probability.ChanceFinalConsonantIsSequence == null) { this.Probability.ChanceFinalConsonantIsSequence = DefaultChanceFinalConsonantBecomesSequence; } - this.Context = Context.FinalConsonantSequence; + _context = Context.FinalConsonantSequence; return this; } /// - /// Defines the specified sequences for leading consonants, trailing consonants, - /// or vowels depending on the context. + /// Contextual on the last call. Adds the specified sequences as + /// leading consonants, trailing consonants, or vowels depending on the context. /// public SyllableGenerator Sequences(params string[] sequences) { - switch (this.Context) + switch (_context) { case Context.LeadingConsonant: this.WithLeadingConsonantSequences(sequences); @@ -406,18 +561,21 @@ public SyllableGenerator Sequences(params string[] sequences) this.WithFinalConsonantSequences(sequences); break; default: - this.Context = Context.None; + _context = Context.None; break; } return this; } - + /// + /// Contextual on the last call. Sets the weight of the last + /// added graphemes. + /// public SyllableGenerator Weight(int weight) { - foreach(var g in this.LastChanges) + foreach(var g in _lastChanges) { g.Weight = weight; } @@ -425,20 +583,8 @@ public SyllableGenerator Weight(int weight) return this; } - - /* - /// - /// Used to manage the probability of vowels/consonants turning into sequences, of leading - /// consonants starting a syllable, of trailing consonants ending a syllable, etc. - /// - public SyllableGenerator WithProbability(Func configure) - { - this.Probability = configure(this.Probability); - return this; - }/**/ - /// - /// Used to manage the probability of vowels/consonants turning into sequences, of leading + /// Sets the probability of vowels/consonants turning into sequences, of leading /// consonants starting a syllable, of trailing consonants ending a syllable, etc. /// public SyllableGenerator WithProbability(Func configure) @@ -561,17 +707,27 @@ private string NextFinalConsonantSequence() } } - + /// + /// Returns a random syllable suitable for starting a name. + /// public virtual string NextStartingSyllable() { return GenerateSyllable(SyllablePosition.Starting); } + /// + /// Returns a random syllable suitable for any position. + /// + /// public virtual string NextSyllable() { return GenerateSyllable(SyllablePosition.Middle); } + /// + /// Returns a random suitable suitable for ending a name. + /// + /// public virtual string NextEndingSyllable() { return GenerateSyllable(SyllablePosition.Ending); @@ -583,10 +739,10 @@ private string GenerateSyllable(SyllablePosition position) if (position == SyllablePosition.Starting && this.LeadingVowelForStartingSyllableAllowed - && this.Random.NextDouble() < this.Probability.ChanceStartingSyllableLeadingVowelExists) + && _random.NextDouble() < this.Probability.ChanceStartingSyllableLeadingVowelExists) { - if (this.VowelSequencesAllowed && this.Random.NextDouble() < this.Probability.ChanceStartingSyllableLeadingVowelIsSequence) + if (this.VowelSequencesAllowed && _random.NextDouble() < this.Probability.ChanceStartingSyllableLeadingVowelIsSequence) { output.Append(this.NextVowelSequence()); } @@ -598,11 +754,11 @@ private string GenerateSyllable(SyllablePosition position) else { // Determine if there is a leading consonant in this syllable - if (this.LeadingConsonantsAllowed && this.Random.NextDouble() < this.Probability.ChanceLeadingConsonantExists) + if (this.LeadingConsonantsAllowed && _random.NextDouble() < this.Probability.ChanceLeadingConsonantExists) { // If there is a leading consonant, determine if it is a sequence - if (this.LeadingConsonantSequencesAllowed && this.Random.NextDouble() < this.Probability.ChanceLeadingConsonantIsSequence) + if (this.LeadingConsonantSequencesAllowed && _random.NextDouble() < this.Probability.ChanceLeadingConsonantIsSequence) { output.Append(this.NextLeadingConsonantSequence()); } @@ -613,11 +769,11 @@ private string GenerateSyllable(SyllablePosition position) } // Determine if there is a vowel in this syllable (by default, this probability is 100%) - if(this.VowelsAllowed && this.Random.NextDouble() < this.Probability.ChanceVowelExists) + if(this.VowelsAllowed && _random.NextDouble() < this.Probability.ChanceVowelExists) { // Then check if the vowel is a vowel sequence - if (this.VowelSequencesAllowed && this.Random.NextDouble() < this.Probability.ChanceVowelIsSequence) + if (this.VowelSequencesAllowed && _random.NextDouble() < this.Probability.ChanceVowelIsSequence) { output.Append(this.NextVowelSequence()); } @@ -633,11 +789,11 @@ private string GenerateSyllable(SyllablePosition position) // (as opposed to a 'trailing' consonant) if(position == SyllablePosition.Ending && this.FinalConsonantsAllowed - && this.Random.NextDouble() < this.Probability.ChanceFinalConsonantExists) + && _random.NextDouble() < this.Probability.ChanceFinalConsonantExists) { // We need to append a final consonant, // but we need to determine if the consonant is a sequence first - if (this.FinalConsonantSequencesAllowed && this.Random.NextDouble() < this.Probability.ChanceFinalConsonantIsSequence) + if (this.FinalConsonantSequencesAllowed && _random.NextDouble() < this.Probability.ChanceFinalConsonantIsSequence) { output.Append(this.NextFinalConsonantSequence()); } @@ -647,11 +803,11 @@ private string GenerateSyllable(SyllablePosition position) } } // Otherwise, roll for a trailing consonant - else if (this.TrailingConsonantsAllowed && this.Random.NextDouble() < this.Probability.ChanceTrailingConsonantExists) + else if (this.TrailingConsonantsAllowed && _random.NextDouble() < this.Probability.ChanceTrailingConsonantExists) { // If we need to append a trailing consonant, check if // we need a sequence instead - if (this.TrailingConsonantSequencesAllowed && this.Random.NextDouble() < this.Probability.ChanceTrailingConsonantIsSequence) + if (this.TrailingConsonantSequencesAllowed && _random.NextDouble() < this.Probability.ChanceTrailingConsonantIsSequence) { output.Append(this.NextTrailingConsonantSequence()); } diff --git a/Syllabore/Syllabore/SyllableSet.cs b/Syllabore/Syllabore/SyllableSet.cs index 5b93a0f..98a85bb 100644 --- a/Syllabore/Syllabore/SyllableSet.cs +++ b/Syllabore/Syllabore/SyllableSet.cs @@ -20,14 +20,38 @@ namespace Syllabore /// public class SyllableSet : ISyllableGenerator { + /// + /// The syllable set size for starting syllables. + /// public int StartingSyllableMax { get; set; } + + /// + /// The syllable set size for syllables occurring + /// between the starting and ending syllable. + /// public int MiddleSyllableMax { get; set; } + + /// + /// The syllable set size for ending syllables. + /// public int EndingSyllableMax { get; set; } - private ISyllableGenerator Provider { get; set; } + private ISyllableGenerator _generator { get; set; } + /// + /// The finite set of syllables to be used in the starting position of a name. + /// public HashSet StartingSyllables { get; set; } + + /// + /// The finite set of syllables to be used between the starting and ending + /// positions of a name. + /// public HashSet MiddleSyllables { get; set; } + + /// + /// The finite set of syllables to be used in the ending position of a name. + /// public HashSet EndingSyllables { get; set; } /// @@ -75,7 +99,7 @@ public SyllableSet WithGenerator(Func conf /// public SyllableSet WithGenerator(ISyllableGenerator provider) { - this.Provider = provider; + _generator = provider; return this; } @@ -150,42 +174,50 @@ public SyllableSet WithEndingSyllable(params string[] syllables) return this; } - // Inherited + /// + /// Returns a random syllable suitable for use in the starting position + /// of a name. + /// public string NextStartingSyllable() { if (this.StartingSyllables.Count < this.StartingSyllableMax) { for (int i = this.StartingSyllables.Count; i < this.StartingSyllableMax; i++) { - this.StartingSyllables.Add(this.Provider.NextStartingSyllable()); + this.StartingSyllables.Add(_generator.NextStartingSyllable()); } } return this.StartingSyllables.RandomItem(); } - // Inherited + /// + /// Returns a random syllable suitable for use between the starting and ending + /// positions of a name. + /// public string NextSyllable() { if (this.MiddleSyllables.Count < this.MiddleSyllableMax) { for (int i = this.MiddleSyllables.Count; i < this.MiddleSyllableMax; i++) { - this.MiddleSyllables.Add(this.Provider.NextSyllable()); + this.MiddleSyllables.Add(_generator.NextSyllable()); } } return this.MiddleSyllables.RandomItem(); } - // Inherited + /// + /// Returns a random syllable suitable for use in the ending position of a name. + /// public string NextEndingSyllable() { if (this.EndingSyllables.Count < this.EndingSyllableMax) { for (int i = this.EndingSyllables.Count; i < this.EndingSyllableMax; i++) { - this.EndingSyllables.Add(this.Provider.NextEndingSyllable()); + this.EndingSyllables.Add(_generator.NextEndingSyllable()); } } diff --git a/Syllabore/Syllabore/Transform.cs b/Syllabore/Syllabore/Transform.cs index 0ad3a24..2cd8a0d 100644 --- a/Syllabore/Syllabore/Transform.cs +++ b/Syllabore/Syllabore/Transform.cs @@ -7,24 +7,39 @@ namespace Syllabore { /// /// - /// A changes a source name into a new name. + /// A is a mechanism for changing a source name into + /// a new, modified name. Transforming names is useful for adding some + /// determinism in name generation or for creating iterations on an established name. /// /// - /// s can have - /// an optional condition that must be fulfilled for a transformation to occur. + /// Transforms can have an optional condition that + /// must be fulfilled for a transformation to occur. /// /// public class Transform : IWeighted, INameTransformer { + /// + /// The steps that this transform will execute. + /// public List Steps { get; set; } /// - /// A positive integer that influences the probability of this transform being used over others. - /// Given two transforms X and Y with a weight of 3 and 1 respectively, transform X will be applied 75% of the time. - /// All transforms default to a weight of 1. + /// A positive integer that influences the probability of this transform being + /// used over others. Given two transforms X and Y with a weight of 3 and 1 + /// respectively, transform X will be applied 75% of the time. All transforms + /// default to a weight of 1. /// public int Weight { get; set; } + + /// + /// The index of the syllable that the condition operates on. A negative index + /// can be provided to traverse right-to-left from the end of the name instead. + /// public int? ConditionalIndex { get; set; } + + /// + /// A regular expression that must be satisfied for the transform to be applied. + /// public string ConditionalRegex { get; set; } /// @@ -109,7 +124,7 @@ public Transform When(int index, string regex) /// - /// Adds a transform step that replaces a syllable at the specified index with + /// Adds a step that replaces a syllable at the specified index with /// a desired string. /// /// The index can be a negative integer to traverse from the @@ -124,7 +139,7 @@ public Transform ReplaceSyllable(int index, string replacement) } /// - /// Adds a transform step that replaces all instances of the specified substring in each syllable with + /// Adds a step that replaces all instances of the specified substring in each syllable with /// a desired string. Note that the substring must be completely contained in a syllable to be replaced. /// public Transform ReplaceAll(string substring, string replacement) @@ -140,7 +155,7 @@ public Transform ReplaceAll(string substring, string replacement) /// The index can be a negative integer to traverse from the /// end of the name instead. (For example, an index -1 will be interpreted as the /// last syllable of a name. - /// The string to insert. + /// The string to insert. /// public Transform InsertSyllable(int index, string syllable) { @@ -158,7 +173,7 @@ public Transform AppendSyllable(string syllable) } /// - /// Adds a transform step that removes the syllable at the specified index. + /// Adds a step that removes the syllable at the specified index. /// /// The index can be a negative integer to traverse from the /// end of the name instead. (For example, an index -1 will be interpreted as the diff --git a/Syllabore/Syllabore/TransformSet.cs b/Syllabore/Syllabore/TransformSet.cs index d40d85a..0709aa6 100644 --- a/Syllabore/Syllabore/TransformSet.cs +++ b/Syllabore/Syllabore/TransformSet.cs @@ -9,23 +9,43 @@ namespace Syllabore /// /// - /// A receives - /// a source name, applies one or more s, and creates a new name. - /// By default, all s of the same set are applied to the source name - /// and in the order they were added. + /// A takes a source name, + /// applies one or more Transforms, + /// then creates a new name. By default, all + /// Transforms of the same set are + /// applied to the source name and in the order they were added. /// /// - /// To randomize what transforms are applied, make sure to call - /// when configuring a . + /// To randomize what transforms are applied, make sure to call + /// when configuring a + /// . /// /// [Serializable] public class TransformSet : INameTransformer { - private Random Random; + private Random _random; + + /// + /// The Transforms that make up this + /// . + /// public List Transforms { get; set; } + /// + /// When true, Transforms are not + /// applied in the order they were added. Instead, a random + /// number of Transforms are selected + /// and applied. Property is + /// used to determine how many random selections are made. + /// public bool UseRandomSelection { get; set; } + + /// + /// When is true, this property + /// is used to determine how many random Transforms + /// are selected and applied. + /// public int RandomSelectionCount { get; set; } /// @@ -36,7 +56,7 @@ public class TransformSet : INameTransformer /// public TransformSet() { - this.Random = new Random(); + _random = new Random(); this.Transforms = new List(); this.UseRandomSelection = false; this.RandomSelectionCount = 0; @@ -108,7 +128,7 @@ private bool CanTransformBeApplied(Transform transform, Name sourceName) { int index = transform.ConditionalIndex.Value; - if (index < 0) // reverse index provided, so translate into forward index (eg. -1 is the last syllable) + if (index < 0) // reverse index provided, so translate into a forward index (eg. -1 is the last syllable) { index = sourceName.Syllables.Count + index; } @@ -193,7 +213,6 @@ public TransformSet RandomlySelect(int limit) return this; } - } } diff --git a/Syllabore/Syllabore/TransformStep.cs b/Syllabore/Syllabore/TransformStep.cs index 14b15b3..d44a06b 100644 --- a/Syllabore/Syllabore/TransformStep.cs +++ b/Syllabore/Syllabore/TransformStep.cs @@ -4,13 +4,42 @@ namespace Syllabore { + /// + /// The type of action that a + /// will apply to a . + /// public enum TransformStepType { + /// + /// Adds a syllable to a , displacing other + /// syllables as needed. + /// InsertSyllable, + + /// + /// Adds a syllable to the end of a . + /// AppendSyllable, + + /// + /// Replaces a single syllable with a another syllable. + /// ReplaceSyllable, + + /// + /// Deletes a syllable from a , displacing + /// other syllables as needed. + /// RemoveSyllable, - Lambda, // Note: this one cannot be serialized + + /// + /// An action that is not serializable and expressed in a lambda. + /// + Lambda, + + /// + /// Replaces all instances of a substring with another substring. + /// ReplaceAllSubstring } @@ -19,25 +48,53 @@ public enum TransformStepType /// public class TransformStep { + /// + /// The type of action this represents. + /// public TransformStepType Type { get; set; } + + /// + /// The arguments that are passed to the action. + /// public List Arguments { get; set; } - private Action UnserializableAction { get; set; } - public TransformStep() + /// + /// If this is of type , + /// this property will contain the action to be applied. + /// + private Action _unserializableAction { get; set; } + + /// + /// Instantiates a new with + /// no type or arguments. + /// + public TransformStep() // Needs to exist for serialization { this.Arguments = new List(); } + /// + /// Instantiates a new with + /// the specified type and arguments. + /// public TransformStep(TransformStepType type, params string[] args) { this.Type = type; this.Arguments = new List(args); } + /// + /// Instantiates a new with + /// type and the + /// specified to execute. + /// Note that this type of is + /// not serializable. + /// + /// public TransformStep(Action unserializableAction) { this.Type = TransformStepType.Lambda; - this.UnserializableAction = unserializableAction; + _unserializableAction = unserializableAction; } /// @@ -104,7 +161,7 @@ public void Modify(Name name) } else if(this.Type == TransformStepType.Lambda) { - UnserializableAction(name); + _unserializableAction(name); }