So I made a pretty simple word generator program in c# that works relatively well. It generates a word based on the length defined by the user.
The algorithm adds a consonant and then a vowel for each consecutive letter in the sequence, which isn't ideal, but works well enough for basic words.
My only issue is that I told it to add a "u" to the letter sequence if a "q" shows up right before it, but no matter what I've done it makes the word at least 1 letter too long.
I have marked my problem area with a star in the comment above it. Here is the code:
public void WordFinder()
{
string word = null;
int cons;
int vow;
//counter
int i = 0;
bool isword = false;
Random rnd = new Random();
//set a new string array of consonants
string[] consonant = new string[]{"b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"};
//set a new string array of vowels
string[] vowel = new string[]{"a","e","i","o","u"};
while (isword == false)
{
word = null;
Console.WriteLine("Pick the length of a word");
int num = Convert.ToInt32(Console.ReadLine());
//set the counter "i" to 1
i = 1;
if (num%2 == 0)
{
while (i <= num)
{
if (num != 1)
{
// current consonant = random consonant
cons = rnd.Next(0, 20);
// get the consonant from the string array "consonant" and add it to word
word = word + consonant[cons];
// add 1 to counter
i ++;
//* if the consonant is "q"
if (cons == 12)
{
// add "u" right after it
word = word + vowel[4];
// add 1 to counter
i++;
}
}
vow = rnd.Next(0, 4);
word = word + vowel[vow];
i ++;
}
}
if (num % 2 != 0)
{
while (i <= num - 1)
{
//repeat same code as done to even length
if (num != 1)
{
cons = rnd.Next(0, 20);
word = word + consonant[cons];
i ++;
if (cons == 12)
{
word = word + vowel[4];
i ++;
}
}
vow = rnd.Next(0, 4);
word = word + vowel[vow];
i ++;
}
// if the length is not equal to 1
if (num != 1)
{
// add a consonant to the end of the word
cons = rnd.Next(0, 20);
word = word + consonant[cons];
}
//if the length is 1
else if (num == 1)
{
// pick a vowel
vow = rnd.Next(0, 4);
word = word + vowel[vow];
}
}
i = 1;
Console.WriteLine(word);
Console.WriteLine("Is this a word? (y/n)");
string q = Console.ReadLine();
q = q.ToLower();
//if the answer is yes, then it is a word and end the loop
if (q == "y" || q == "yes")
{
isword = true;
}
//if the answer is no try the loop again
else if (q == "n" || q == "no")
{
isword = false;
}
}
}
// main method
static void Main(string[] args)
{
Program prog = new Program();
prog.WordFinder();
//wait for user input
Console.ReadLine();
}
}
I refactored your answer and after some debugging I got it to work. Sorry I couldn't just do a tweak on it to fix it. I believe it does not allow a word to end in "qu" or "q".
public void WordFinder()
{
bool isWord = false;
Random rnd = new Random();
string[] consonants = { "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z" };
string[] vowels = { "a", "e", "i", "o", "u" };
while (isWord == false)
{
string word = "";
Console.WriteLine("Pick the length of a word");
int requestedLength = Convert.ToInt32(Console.ReadLine());
// Generate the word in consonant / vowel pairs
while (word.Length < requestedLength)
{
if (requestedLength != 1)
{
// Add the consonant
string consonant = GetRandomLetter(rnd, consonants);
if (consonant == "q" && word.Length + 3 <= requestedLength) // check +3 because we'd add 3 characters in this case, the "qu" and the vowel. Change 3 to 2 to allow words that end in "qu"
{
word += "qu";
}
else
{
while( consonant == "q")
{
// Replace an orphaned "q"
consonant = GetRandomLetter(rnd, consonants);
}
if (word.Length + 1 <= requestedLength)
{
// Only add a consonant if there's enough room remaining
word += consonant;
}
}
}
if (word.Length + 1 <= requestedLength)
{
// Only add a vowel if there's enough room remaining
word += GetRandomLetter(rnd, vowels);
}
}
Console.WriteLine(word);
Console.WriteLine("Is this a word? (y/n)");
string q = Console.ReadLine().ToLower();
if (q == "y" || q == "yes")
{
isWord = true;
}
}
}
private static string GetRandomLetter(Random rnd, string[] letters)
{
return letters[rnd.Next(0, letters.Length - 1)];
}
Edit: However, that's still pretty unruly. How about generating a random string, and then replacing "q" with "qu" after you're done?
public string WordFinder2(int requestedLength)
{
Random rnd = new Random();
string[] consonants = { "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z" };
string[] vowels = { "a", "e", "i", "o", "u" };
string word = "";
if (requestedLength == 1)
{
word = GetRandomLetter(rnd, vowels);
}
else
{
for (int i = 0; i < requestedLength; i+=2)
{
word += GetRandomLetter(rnd, consonants) + GetRandomLetter(rnd, vowels);
}
word = word.Replace("q", "qu").Substring(0, requestedLength); // We may generate a string longer than requested length, but it doesn't matter if cut off the excess.
}
return word;
}
private static string GetRandomLetter(Random rnd, string[] letters)
{
return letters[rnd.Next(0, letters.Length - 1)];
}
Your problem is occurring because of the way you are constructing your loops.
You use two separate loops, depending on whether the length is even or odd, and assume in each that the loop will add two characters. However, when a Q is encountered, the loop adds 3 characters, which causes the loop to execute one additional time, and you end up with one extra character.
Try this method:
string GenerateWord(int length)
{
if (length < 1) // do not allow words of zero length
throw new ArgumentException("Length must be greater than 0");
string word = string.Empty;
if (rand.Next() % 2 == 0) // randomly choose a vowel or consonant to start the word
word += cons[rand.Next(0, 20)];
else
word += vowel[rand.Next(0, 4)];
for (int i = 1; i < length; i += 2) // the counter starts at 1 to account for the initial letter
{ // and increments by two since we append two characters per pass
char c = cons[rand.Next(0, 20)];
char v = vowel[rand.Next(0, 4)];
if (c == 'q') // append qu if the random consonant is a q
word += "qu";
else // otherwise just append a random consant and vowel
word += c + v;
}
// the word may be short a letter because of the way the for loop above is constructed
if (word.Length < length) // we'll just append a random consonant if that's the case
word += cons[rand.Next(0, 20)];
return word;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With