I am just starting out with learning C#, and to practice I am trying to create a hangman game (guess letters of a word).
I created a class WordToGuess and created multiple instances of this class, one for each word.
Now I would like to randomly pick one of these instances to be guessed by the player. I am not sure how to approach this.
I found code to randomly pick an index from an array, which seems to be a good way to do it. But now I don't know what exactly I can do. Can I list instances in an array? And if not, how can I elegantly do it otherwise. I can think of a workaround, but that's not the point of the exercise.
Example of my instance:
WordToGuess duck = new WordToGuess();
duck.numberOfLetters = 4;
duck.theWord = "Duck";
duck.theLetters = new string[] { "d", "u", "c", "k" };
duck.difficulty = "easy";
duck.wordID = "e3";
My random generation attempt (I thought I could just generate the string ID and then address the instance that way, I think I didn't think that through though)
string[] easyWords = new string[] { "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
Random rndE = new Random();
int indexE = rndE.Next(easyWords.Length);
CodePudding user response:
An example with arrays:
class Program
{
static void Main(string[] args)
{
WordToGuess[] wtg = new WordToGuess[10];
wtg[0] = new WordToGuess("Duck", "easy", "e3");
wtg[1] = new WordToGuess("Dog", "easy", "e4");
wtg[2] = new WordToGuess("House", "easy", "e5");
wtg[3] = new WordToGuess("Pneumonoultramicroscopicsilicovolcanoconiosis", "difficult", "e6");
Console.WriteLine();
foreach (var item in wtg)
{
if (item is not null)
{
Console.WriteLine($"{item.wordID}, {item.theWord}, {item.difficulty}, {item.numberOfLetters}");
}
}
Console.WriteLine();
Random r = new Random();
WordToGuess randomWord = wtg[r.Next(0, 3)];
Console.WriteLine($"A random word: {randomWord.wordID}, {randomWord.theWord}, {randomWord.difficulty}, {randomWord.numberOfLetters}");
// this needs: using System.Linq;
randomWord = wtg.Where(x => x is not null).OrderBy(x => r.Next()).First();
Console.WriteLine($"Another random word: {randomWord.wordID}, {randomWord.theWord}, {randomWord.difficulty}, {randomWord.numberOfLetters}");
Console.ReadLine();
}
}
public class WordToGuess
{
public int numberOfLetters { get; set; }
public string theWord { get; set; }
public char[] theLetters { get; set; }
public string difficulty { get; set; }
public string wordID { get; set; }
public WordToGuess()
{}
public WordToGuess(string theWord, string difficulty, string wordID)
{
this.numberOfLetters=theWord.Length;
this.theWord=theWord;
this.theLetters=theWord.ToUpper().ToCharArray();
this.difficulty=difficulty;
this.wordID=wordID;
}
}
output like this:
e3, Duck, easy, 4
e4, Dog, easy, 3
e5, House, easy, 5
e6, Pneumonoultramicroscopicsilicovolcanoconiosis, difficult, 45
A random word: e4, Dog, easy, 3
Another random word: e5, House, easy, 5
The word Pneumo....iosis was found here: https://irisreading.com/10-longest-words-in-the-english-language/
CodePudding user response:
There are many ways to do what you want. Maybe one of the best would be to store the WordToGuess
instances in a Dictionary<string, WordToGuess>
where the key is that identifier.
But i would also refactor your class, some properties are not needed like the string[]
for the letters, since string already implements IEnumerable<char>
. I would also make that Diffciculty an enum
instead of a string
and provide a constructor for WordToGuess
that takes the most important properties as input:
public class WordToGuess
{
public enum GuessDifficulty
{
Easy, Medium, Hard
}
public WordToGuess(string word, string id, GuessDifficulty difficulty)
{
TheWord = word;
ID = id;
Difficulty = difficulty;
}
public string ID {get;set;}
public string TheWord {get;set;}
public GuessDifficulty Difficulty {get;set;}
}
Now you can initialize and fill the dictionary in this way:
Dictionary<string, WordToGuess> wordDictionary = new Dictionary<string, WordToGuess>();
WordToGuess duck = new WordToGuess("Duck", "e3", WordToGuess.GuessDifficulty.Easy);
wordDictionary.Add(duck.ID, duck);
// initialize and add more ...
Your random word logic then just tries to find the word with the Id in the dictionary:
string[] easyWords = new string[] { "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
Random rndE = new Random();
int idIndex = rndE.Next(easyWords.Length);
WordToGuess randomWord = wordDictionary.TryGetValue(easyWords[idIndex], out WordToGuess w) ? w : null;
Note that it's null
if there is not a word with that random identifier.
CodePudding user response:
Make a List and add all instances to the list. Then use that random index code on the list. In C# we rarely use [] and instead use lists. (Yes you can have object instances in an array)