Newbie
Newbie

Reputation: 179

How to search for specific char in an array and how to then manipulate that index in c#

Okay, so I'm creating a hangman game and everything functions so far, including what I'm TRYING to do in the question.

But it feels like there is a much more efficient method of obtaining the char that is also easier to manipulate the index.

protected static void alphabetSelector(string activeWordAlphabet)
    {
        char[] activeWord = activeWordAlphabet.ToCharArray();

        string activeWordString = new string(activeWord);
        Console.WriteLine("If you'd like to guess a letter, enter the letter. \n 
        If you'd like to guess the word, please type in the word. --- testing answer{0}", 
        activeWordString);

        //Console.WriteLine("For Testing Purposes ONLY");
        String chosenLetter = Console.ReadLine();
        //Char[] letterFinder = Array.FindAll(activeWord, s => s.Equals(chosenLetter));
        //string activeWordString = new string(activeWord);

        foreach (char letter in activeWord);
        {
            if(activeWordString.Contains(chosenLetter))
            {
                Console.WriteLine("{0}", activeWordString);
                Console.ReadLine();

            }

            else
            {
                Console.WriteLine("errrr...wrong!");
                Console.ReadLine();

            }



        }



    }

I have broken up the code in some areas to prevent the reader from having to scroll sideways. If this is bothersome, please let me know and I'll leave it in the future.

So this code will successfully print out the 'word' whenever I select the correct letter from the random word (I have the console print the actual word so that I can test it successfully each time). It will also print 'wrong' when I choose a letter NOT in the string.

But I feel like I should be able to use the Array.FindAll(activeWord, ...) functionality or some other way. But every time I try and reorder the arguments, it gives me all kinds of different errors and tells me to redo my arguments.

So, if you can look at this and find an easier method of searching the actual array for the user-selected 'letter', please help!! Even if it's not using the Array.FindAll method!!

Edit

Okay, it seems like there's some confusion with what I've done and why I've done it.

I'm ONLY printing the word inside that 'if' statement to test and make sure that the foreach{if{}} will actually work to find the char inside the string. But I ultimately need to be able to provide a placeholder for a char that is successfully found, as well as being able to 'cross out' the letter (from the alphabet list not shown here).

It's hangman - surely you guys know what I'm needing it to do. It has to keep track of which letters are left in the word, which letters have been chosen, as well as which letters are left in the entire alphabet.

I'm a 4-day old newb when it comes to programming, so please. . . I'm only doing what I know to do and when I get errors, I comment things out and write more until I find something that works.

Upvotes: 1

Views: 246

Answers (3)

Paradise228
Paradise228

Reputation: 717

Ok your code is really confusing, even with your edit.

First, why these 2 lines of code since activeWordAlphabet is a string :

char[] activeWord = activeWordAlphabet.ToCharArray();

string activeWordString = new string(activeWord);

Then you do your foreach. For the word "FooBar", if the player types 'F', you will print FooBar FooBar FooBar FooBar FooBar FooBar

How does this help you in anything?

I think you have to review your algorithm. The string type have the function you need

int chosenLetterPosition = activeWord.IndexOf(chosenLetter, alreadyFoundPosition)

alreadyFoundPosition is an int from where the function will search the letter

IndexOf() returns -1 if the letter is not find or a positive number. You can save this position with your letter in a dictionary to use it again as your new 'alreadyFoundPosition' if the chosenLetter is already in the dictionary

Upvotes: 2

slava
slava

Reputation: 1915

This is my answer. Because I don't have a lot of tasks today :)

class Letter
{
    public bool ischosen { get; set; }
    public char value { get; set; }
}

class LetterList
{
    public LetterList(string word)
    {
        _lst = new List<Letter>();
        word.ToList().ForEach(x => _lst.Add(new Letter() { value = x }));
    }

    public bool FindLetter(char letter)
    {
        var search = _lst.Where(x => x.value == letter).ToList();
        search.ForEach(x=>x.ischosen=true);
        return search.Count > 0 ? true : false;
    }

    public string NotChosen()
    {
        var res = "";
        _lst.Where(x => !x.ischosen).ToList().ForEach(x => { res += x.value; });
        return res;
    }

    List<Letter> _lst;


}

How to use

var abc = new LetterList("abcdefghijklmnopqrstuvwxyz");
var answer = new LetterList("myanswer");
Console.WriteLine("This my question. Why? write your answer please");
char x = Console.ReadLine()[0];
if (answer.FindLetter(x))
{
    Console.WriteLine("you are right!");
}
else
{
    Console.WriteLine("fail");
}
abc.FindLetter(x);

Console.WriteLine("not chosen abc:{0} answer:{1}", abc.NotChosen(), answer.NotChosen());

At least we used to play this game like that when i was a child.

Upvotes: 1

crush
crush

Reputation: 17023

Take a look at this demo I put together for you: https://dotnetfiddle.net/eP9TQM

I'd suggest creating a second string for the display string. Use a StringBuilder, and you can replace the characters in it at specific indices while creating the fewest number of stringobjects in the process.

string word = "your word or phrase here";

//Initialize a new StringBuilder that will display the word with placeholders.
StringBuilder display = new StringBuilder(word.Length); //You know the display word is the same length as the original word
display.Append('-', word.Length); //Fill it with placeholders.

So now you have your phrase/word, and a string builder full of characters that need to be discovered.

Go ahead and convert the display StringBuilder to a string that you can check on each pass to see if it equals your word:

var displayString = display.ToString();

//Loop until the display string is equal to the word
while (!displayString.Equals(word))
{
    //Inside here your logic will follow.
}

So you are basically looping until the person answers here. You could of course go back and add logic to limit the number of attempts, or whatever you desire as an alternate exit strategy.

Inside this logic, you will check if they guessed a letter or a word based on how many characters they entered.

If they guessed a word, the logic is simple. Check if the guessed word is the same as the hidden word. If it is, then you break the loop and they are done. Otherwise, guessing loops back around.

If they guessed a letter, the logic is pretty straightforward, but more involved.

First get the character they guessed, just because it may be easier to work with this way.

char guess = input[0];

Now, look over the word for instances of that character:

//Look for instances of the character in the word.
for (int i = 0; i < word.Length; ++i)
{
    //If the current index in the word matches their guess, then update the display.
    if (char.ToUpperInvariant(word[i]) == char.ToUpperInvariant(guess))
        display[i] = word[i];
}

The comments above should explain the idea here.

Update your displayString at the bottom of the loop so that it will check against the hidden word again:

displayString = display.ToString();

That's really all you need to do here. No fancy Linq needed.

Upvotes: 2

Related Questions