/Engine/NameGenerator.cs
C# | 407 lines | 348 code | 40 blank | 19 comment | 59 complexity | 3d125ba61313a657e0c33b44bfbae9aa MD5 | raw file
- using System;
- using System.Globalization;
- using System.Linq;
-
- namespace Ruction
- {
- /// <summary>Handles the generation of random names.</summary>
- internal static class NameGenerator
- {
- #region Member Variables
-
- /// <summary>Private storage for letter proportions.</summary>
- private static int[] _letterPrp;
-
- /// <summary>Private storage for letter pecrentages.</summary>
- private static float[] _letterPct;
-
- /// <summary>Private storage for name 'spice'.</summary>
- private static string[] _nameSpice;
-
- /// <summary>Private randomizer.</summary>
- private static Random _rnd;
-
- #endregion Member Variables
-
- #region Constructors
-
- /// <summary>Static constructor for name generation data.</summary>
- static NameGenerator()
- {
- _rnd = new Random(DateTime.Now.Millisecond);
- _nameSpice = new string[26];
- _letterPct = new float[26];
- _letterPrp = new int[26];
-
- InitNameGen();
- }
-
- #endregion Constructors
-
- #region Properties
-
- #region NameSpice
- /// <summary>Gets the name spice string array.</summary>
- public static string[] NameSpice { get { return _nameSpice; } }
- #endregion NameSpice
-
- #endregion Properties
-
- #region Methods
-
- #region GenerateName
- /// <summary>Generates a random name.</summary>
- /// <param name="min">The minimum name length.</param>
- /// <param name="max">The maximum name length.</param>
- /// <param name="specials">True to use special strings in the name.</param>
- /// <returns>A string containing a randomly generated name.</returns>
- internal static string GenerateName(int min, int max, bool specials)
- {
- int i = 0;
- bool GoodWord = false;
- string retVal = string.Empty;
- char LastChar = char.MinValue, TwoCharsAgo = char.MinValue;
-
- do
- {
- retVal = Convert.ToChar(Convert.ToInt32(_rnd.NextDouble() * 26) + 65).ToString();
- LastChar = retVal[0];
- GoodWord = true;
-
- for (i = 0; i < (Convert.ToInt32(_rnd.NextDouble() * (max - min + 1)) + min) - 1; i++)
- {
- if (Consonant(LastChar))
- {
- if (Consonant(TwoCharsAgo))
- {
- if (LastChar.Equals('y') || LastChar.Equals('Y'))
- {
- retVal += AddChars("BCDFGKLMNPRSTVXZ");
- }
- else { retVal += AddChars("AEIOU"); }
- }
- else
- {
- if (_rnd.NextDouble() < 0.2)
- {
- if (LastChar.Equals('q') || LastChar.Equals('Q'))
- {
- retVal += AddChars("U");
- }
- else { retVal += AddChars("AEIOU"); }
- }
- else
- {
- #region BIG Switch Statement
- switch (LastChar)
- {
- case 'B':
- case 'b':
- retVal += AddChars("BLRSY");
- break;
- case 'C':
- case 'c':
- retVal += AddChars("CHKLRSTY");
- break;
- case 'D':
- case 'd':
- retVal += AddChars("DRSWY");
- break;
- case 'F':
- case 'f':
- retVal += AddChars("FLRSTY");
- break;
- case 'G':
- case 'g':
- retVal += AddChars("GHLRS");
- break;
- case 'H':
- case 'h':
- retVal += AddChars("AEIOUY");
- break;
- case 'J':
- case 'j':
- retVal += AddChars("AEIOU");
- break;
- case 'K':
- case 'k':
- retVal += AddChars("HKLNRSTW");
- break;
- case 'L':
- case 'l':
- retVal += AddChars("CDKLMNPSTY");
- break;
- case 'M':
- case 'm':
- retVal += AddChars("MPSY");
- break;
- case 'N':
- case 'n':
- retVal += AddChars("CDKNSTY");
- break;
- case 'P':
- case 'p':
- retVal += AddChars("HLPRSTY");
- break;
- case 'Q':
- case 'q':
- retVal += AddChars("U");
- break;
- case 'R':
- case 'r':
- retVal += AddChars("CDKMNPRSTY");
- break;
- case 'S':
- case 's':
- retVal += AddChars("CHKLMNPSTWY");
- break;
- case 'T':
- case 't':
- retVal += AddChars("HRSTWY");
- break;
- case 'V':
- case 'v':
- retVal += AddChars("LRS");
- break;
- case 'W':
- case 'w':
- retVal += AddChars("HKST");
- break;
- case 'X':
- case 'x':
- retVal += AddChars("CSYAEIOU");
- break;
- case 'Y':
- case 'y':
- retVal += AddChars("LSTKMNPC");
- break;
- case 'Z':
- case 'z':
- retVal += AddChars("HZZZ");
- break;
- }
- #endregion BIG Switch Statement
- }
- }
- }
- else
- {
- if (Consonant(TwoCharsAgo))
- {
- if (_rnd.NextDouble() < 0.9 && retVal.Length >= 2 && !retVal.Substring(retVal.Length - 2, 2).Equals("QU", StringComparison.OrdinalIgnoreCase))
- {
- retVal += AddChars("BCDFGHJKLMNPQRSTVWX");
- }
- else
- {
- switch (LastChar)
- {
- case 'A':
- case 'a':
- retVal += AddChars("IU");
- break;
- case 'E':
- case 'e':
- retVal += AddChars("AEIOU");
- break;
- case 'I':
- case 'i':
- retVal += AddChars("AEO");
- break;
- case 'O':
- case 'o':
- retVal += AddChars("AEIOU");
- break;
- case 'U':
- case 'u':
- retVal += AddChars("AEI");
- break;
- }
- }
- }
- else
- {
- retVal += AddChars("BCDFGKLMNPRST");
- }
- }
-
- TwoCharsAgo = LastChar;
- LastChar = retVal[retVal.Length - 1];
- }
-
- TwoCharsAgo = retVal[0];
- LastChar = retVal.Length > 1 ? retVal[1] : TwoCharsAgo;
-
- if (TwoCharsAgo.Equals(LastChar)) GoodWord = false;
-
- if ((LastChar.Equals('s') || LastChar.Equals('S')) || (LastChar.Equals('d') || LastChar.Equals('D')))
- {
- if (Consonant(TwoCharsAgo)) { GoodWord = false; }
- }
-
- char[] checkChars = new char[] { 'T', 't', 'K', 'k', 'M', 'm', 'N', 'n', 'P', 'p', 'C', 'c' };
- if (checkChars.Contains(LastChar))
- {
- if (Consonant(TwoCharsAgo) && (!TwoCharsAgo.Equals('S') && !TwoCharsAgo.Equals('s')))
- GoodWord = false;
- }
-
- if ((TwoCharsAgo.Equals('Y') || TwoCharsAgo.Equals('y')) && Consonant(LastChar)) GoodWord = false;
-
- if (retVal.Length >= 2 && !retVal.Substring(retVal.Length - 2, 2).Equals("QU", StringComparison.OrdinalIgnoreCase))
- GoodWord = false;
-
- if (retVal.Contains("IY") || retVal.Contains("WI") ||
- retVal.Contains("YI") || retVal.Contains("UY") ||
- retVal.Contains("UW") || retVal.Contains("IH") ||
- retVal.Contains("UH")) GoodWord = false;
-
- if ((TwoCharsAgo.Equals('X') || TwoCharsAgo.Equals('x')) || (retVal.Length >= 2 && retVal.Substring(0, 2).Equals("IL", StringComparison.OrdinalIgnoreCase)))
- GoodWord = false;
- }
- while (!GoodWord);
-
- LastChar = retVal[retVal.Length - 1];
- TwoCharsAgo = retVal[retVal.Length - 2];
-
- if ((Consonant(LastChar) && Consonant(TwoCharsAgo)) ||
- retVal.Length < 4 || _rnd.NextDouble() < 0.15)
- {
- if (Consonant(LastChar) && (!LastChar.Equals('Y') || !LastChar.Equals('y')))
- {
- retVal += _nameSpice[(Convert.ToInt32(_rnd.NextDouble() * 6) + 17)];
- }
- else { retVal += _nameSpice[(Convert.ToInt32(_rnd.NextDouble() * 6) + 11)]; }
- }
-
- if (specials)
- {
- if (_rnd.NextDouble() < 0.13)
- {
- retVal = _nameSpice[(Convert.ToInt32(_rnd.NextDouble() * 10) + 1)] + retVal;
- }
- }
-
- retVal = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(retVal.ToLower());
-
- return retVal;
- }
- #endregion GenerateName
-
- #region AddChars
- /// <summary>Selects a random character from a set of characters.</summary>
- /// <param name="letters">The characters to choose from.</param>
- /// <returns>A string containing a single character chosen at random.</returns>
- private static string AddChars(string letters)
- {
- int j = 0;
- string retVal = string.Empty;
- float letterTotal = 0, letterTresh = 0, randLetter = 0;
-
- for (j = 0; j < letters.Length; j++)
- {
- letterTotal += _letterPrp[Convert.ToInt32(letters[j]) - 65];
- }
-
- letterTresh = 0;
- for (j = 0; j < letters.Length; j++)
- {
- letterTresh += (_letterPrp[Convert.ToInt32(letters[j]) - 65] / letterTotal);
- _letterPct[j] = letterTresh;
- }
-
- randLetter = Convert.ToSingle(_rnd.NextDouble());
- for (j = 0; j < letters.Length; j++)
- {
- if (randLetter <= _letterPct[j])
- {
- retVal = letters[j].ToString();
- break;
- }
- }
-
- return retVal;
- }
- #endregion AddChars
-
- #region Consonant
- /// <summary>Determines if a given character is a consonant or not.</summary>
- /// <param name="c">The character to analyze.</param>
- /// <returns>True if the character is an english language consonant, otherwise false.</returns>
- private static bool Consonant(char c)
- {
- bool retVal = false;
- if (!c.Equals(char.MinValue))
- {
- retVal = !(c.Equals('a') || c.Equals('A') ||
- c.Equals('e') || c.Equals('E') ||
- c.Equals('i') || c.Equals('I') ||
- c.Equals('o') || c.Equals('O') ||
- c.Equals('u') || c.Equals('U'));
- }
- return retVal;
- }
- #endregion Consonant
-
- #region InitNameGen
- /// <summary>Initializes require name generation arrays.</summary>
- private static void InitNameGen()
- {
- _letterPrp[0] = 9;
- _letterPrp[1] = 2;
- _letterPrp[2] = 2;
- _letterPrp[3] = 4;
- _letterPrp[4] = 12;
- _letterPrp[5] = 2;
- _letterPrp[6] = 3;
- _letterPrp[7] = 2;
- _letterPrp[8] = 9;
- _letterPrp[9] = 1;
- _letterPrp[10] = 1;
- _letterPrp[11] = 4;
- _letterPrp[12] = 2;
- _letterPrp[13] = 6;
- _letterPrp[14] = 8;
- _letterPrp[15] = 2;
- _letterPrp[16] = 1;
- _letterPrp[17] = 6;
- _letterPrp[18] = 4;
- _letterPrp[19] = 6;
- _letterPrp[20] = 4;
- _letterPrp[21] = 2;
- _letterPrp[22] = 2;
- _letterPrp[23] = 1;
- _letterPrp[24] = 2;
- _letterPrp[25] = 1;
-
- _nameSpice[0] = "Upper";
- _nameSpice[1] = "Lower";
- _nameSpice[2] = "Old";
- _nameSpice[3] = "New";
- _nameSpice[4] = "San";
- _nameSpice[5] = "Costa";
- _nameSpice[6] = "North";
- _nameSpice[7] = "South";
- _nameSpice[8] = "East";
- _nameSpice[9] = "West";
- _nameSpice[10] = "tia";
- _nameSpice[11] = "lia";
- _nameSpice[12] = "way";
- _nameSpice[13] = "land";
- _nameSpice[14] = "ton";
- _nameSpice[15] = "burg";
- _nameSpice[16] = "ary";
- _nameSpice[17] = "age";
- _nameSpice[18] = "ia";
- _nameSpice[19] = "any";
- _nameSpice[20] = "ica";
- _nameSpice[21] = "ania";
- _nameSpice[22] = "Isle";
- _nameSpice[23] = "Island";
- _nameSpice[24] = "The Isle of";
- }
- #endregion InitNameGen
-
- #endregion Methods
- }
- }