Display random string value from array as asterisks - c#

I am making a program for a hangman game that picks a random word from a text file of words and then asks the user to guess each letter of the word. Each letter in the word is displayed with an asterisk and when the user makes a correct guess the actual letter is then displayed. After the word is guessed it will then display the number of times missed and ask the user if they want to guess another word.
I have the asterisks hard coded but I would like the asterisks to be the same length of the random word chosen from the text file. I am not sure how I would do this
Any help would be appreciated.
static void Main(string[] args)
{
char[] guessed = new char[26];
char[] testword = "******".ToCharArray();
char[] word = RandomLine().ToCharArray();
char[] copy = word;
char guess;
char playAgain;
int amountMissed = 0, index = 0;
Console.WriteLine(testword);
do
{
Console.WriteLine("I have picked a random word on animals");
Console.WriteLine("Your task is to guess the correct word");
while (testword != word)
{
Console.Write("Please enter a letter to guess: ");
guess = char.Parse(Console.ReadLine());
bool right = false;
for (int j = 0; j < copy.Length; j++)
{
if (copy[j] == guess)
{
Console.WriteLine("Your guess is correct.");
testword[j] = guess;
guessed[index] = guess;
index++;
right = true;
}
}
if (right != true)
{
Console.WriteLine("Your guess is incorrect.");
amountMissed++;
}
else
{
right = false;
}
Console.WriteLine(testword);
}
Console.WriteLine($"The word is {copy}. You missed {amountMissed} times.");
Console.WriteLine("Do you want to guess another word? Enter y or n: ");
playAgain = char.Parse(Console.ReadLine());
} while (playAgain == 'y' || playAgain == 'Y');
Console.WriteLine("Good-Bye and thanks for playing my Hangman game.");
}
public static string RandomLine()
{
try
{
// store text file in an array and return a random value
string[] lines = File.ReadAllLines("C:\\Intel\\Advanced1.csv");
Random rand = new Random();
return lines[rand.Next(lines.Length)];
}
catch (Exception e)
{
Console.WriteLine("The file could not be read");
Console.WriteLine(e.Message);
}
}

To display the coded word (with asterisks) with same length as word, you could use
char[] testword = new string('*',word.Length).ToCharArray();
Making few other corrections in your code
char[] guessed = new char[26];
char guess;
char playAgain;
int amountMissed = 0, index = 0;
do
{
char[] word = RandomLine().ToCharArray(); // Change :This needs to be inside the loop so that new random word could be selected user selects to continue the game
char[] testword = new string('*',word.Length).ToCharArray(); // Change : Reordered initilization of word and testword so that we could generate testword with same length as original
char[] copy = word;
Console.WriteLine(testword);
Console.WriteLine("I have picked a random word on animals");
Console.WriteLine("Your task is to guess the correct word");
while (!testword.SequenceEqual(word)) // Change : Comparison of arrays
{
Console.Write("Please enter a letter to guess: ");
guess = char.Parse(Console.ReadLine());
bool right = false;
for (int j = 0; j < copy.Length; j++)
{
if (copy[j] == guess)
{
Console.WriteLine("Your guess is correct.");
testword[j] = guess;
guessed[index] = guess;
index++;
right = true;
}
}
if (right != true)
{
Console.WriteLine("Your guess is incorrect.");
amountMissed++;
}
else
{
right = false;
}
Console.WriteLine(testword);
}
Console.WriteLine($"The word is {copy}. You missed {amountMissed} times.");
Console.WriteLine("Do you want to guess another word? Enter y or n: ");
playAgain = char.Parse(Console.ReadLine());
} while (playAgain == 'y' || playAgain == 'Y');
Console.WriteLine("Good-Bye and thanks for playing my Hangman game.");

This way:
class Program
{
static void Main(string[] args)
{
bool found = false;
string originalWord = "test";
char[] word = originalWord.ToCharArray();
char[] asteriskedWord = new string('*', word.Length).ToCharArray();
while (found == false)
{
Console.WriteLine(asteriskedWord);
string input = Console.ReadLine();
if (input.Length != 1)
{
Console.WriteLine("Your input can be only one char.");
}
else
{
char c = char.Parse(input);
for (int i = 0; i < word.Length; i++)
{
if (word[i] == c)
{
asteriskedWord[i] = c;
word[i] = '*';
int missingCharsAmount = asteriskedWord.Count(x => x == '*');
Console.WriteLine("Correct, missing " + missingCharsAmount + " chars.");
if (missingCharsAmount == 0)
{
found = true;
}
break;
}
}
}
}
}
}

Related

using methods for program?

So I did this hangman game, and it works perfectly fine, the only problem is that I want to use methods to organize everything.
And yes, it is a school project. I tried my best but whenever I try to put a part of the program in a method it's as if I removed a variable and it underlines it in red.
I removed them for now so it's more clear. also, the file I used contained 19 8 letters max words, one on each line.
Can someone tell me how I can incorporate methods without ruining the whole thing? also English isn't my first language plz excuse any mistakes, the code was in french and I translated it for this question. thank you very much. I appreciate your time and effort :)
using System;
using System.IO;
namespace TP3
{
class Program
{
public const String Dico = "dico.txt";
public static void Welcome()
{
//Mot de bienvenue
Console.WriteLine("Welcome to hangman !");
}
public static void Goodbye()
{
Console.WriteLine("thx for playing, goodbye!");
}
public static void Program()
{
int SolvedWords= 0;
string WordToGuess= "";
int NumberOfLetters ;
int x = 0;
int WordTried = 0;
Console.WriteLine("");
Console.WriteLine("Do you wanna guess a word ? oui or non.");
Console.WriteLine("you have 8 chances per word.");
string Answer= Console.ReadLine();
Answer= Answer.ToLower();
while (Answer== "oui" && WordTried <19)
{
const int Lives= 8;
int LostLives= 0;
int LivesLeft= 8;
int LettersGuesed= 0;
x += 1;
WordTried += 1;
if (WordTried <= 20 && WordTried >1)
{
Console.WriteLine("Do you wanna guess a word ? oui or non.");
Answer= Console.ReadLine();
Answer= Answer.ToLower();
}
//Read a word in the file
int compteur = 0;
string ligne;
// Read file and show on the line
System.IO.StreamReader file = new System.IO.StreamReader(#"dico.txt");
while ((line = file.ReadLine()) != null)
{
compteur++;
if (compteur == x)
{
WordToGuess= line;
}
}
file.Close();
char[] table;
table = new char[WordToGuess.Length];
for (int i = 0; i < table.Length; i++)
{
table[i] = WordToGuess [i];
}
//change each letter into a *
Console.WriteLine("here’s the word to guess : ");
string HiddenWord = "********";
char[] table2;
table2 = new char[WordToGuess.Length];
for (int i = 0; i < table2.Length; i++)
{
table2[i] = HiddenWord[i];
}
for (int i = 0; i < table2.Length; i++)
{
Console.Write(table2[i]);
}
Console.WriteLine("");
//guess the word
while (LettersGuesed< WordToGuess.Length && LivesLeft> 0)
{
Console.WriteLine("");
/* Console.WriteLine("Devinez une seule Letterdu mot. Ne pas écrire une Letter plus d'une fois de suite. Si c'est le cas, recommencez le jeu.");*/
string Letter= Console.ReadLine();
Letter= Letter.ToLower();
NumberOfLetters = Letter.Length;
char[] table3;
table3= new char[NumberOfLetters ];
for (int i = 0; i < table2.Length; i++)
{
if (table[i].Equals(Letter[0]))
{
Table2[i] = Letter[0];
LettersGuesed+= 1;
}
}
for (int i = 0; i < table2.Length; i++)
{
Console.Write(table2[i]);
}
if (WordToGuess.IndexOf(Lettre) < 0)
{
Console.WriteLine("");
Console.WriteLine("wrong letter.");
LostLives+= 1;
LivesLeft= Lives- LostLives;
Console.WriteLine("you have " + LivesLeft+ " lives left.");
}
if (WordToGuess.IndexOf(Lettre) >= 0)
{
Console.WriteLine(" ");
Console.WriteLine("right !");
Console.WriteLine("you have " + LivesLeft+ " lives left.");
}
if (LettersGuesed== WordToGuess.Length && LivesLeft> 0)
{
SolvedWords+= 1;
Console.WriteLine(" ");
Console.WriteLine("you found the word !");
Console.WriteLine("you found " + SolvedWords+ " on" + WordTried + " words so far.");
}
if (LivesLeft== 0)
{
Console.WriteLine("you couldnt guess the word.");
Console.WriteLine("the word was :");
for (int i = 0; i < table.Length; i++)
{
Console.Write(table[i]);
}
Console.WriteLine(" ");
Console.WriteLine("you found " + SolvedWords+ " on" + WordTried + " words so far.");
}
if (WordTried == 19)
{
Console.WriteLine("no more words to guess.");
}
}
}
}
static void Main(string[] args)
{
Welcome();
Programme();
Goodbye();
}
}
}
Im not going to make every method for your project, I'll help kickstart on how to think about it. Look at your current code for reading the file of words. You can move that into a method -
public string[] ReadWordsFromFile()
{
string file = "path to your file here";
return File.ReadAllLines(file);
}
Or pass the file path as parameter -
public string[] ReadWordsFromFile(string filePath)
{
return File.ReadAllLines(filePath);
}
Next you can have a method to get random words -
public string GetRandomWord(string[] wordsArray)
{
Random random = new Random();
int randomIndex = random.Next(0, wordsArray.Length);
return wordsArray[randomIndex];
}
Note - words can be repeated if you do it this way, if you don't want that - then add logic to remove that item from the list once its used in the game. If you remove it within this method, its not actually going to remove it from the game, as you'll still be passing the entire array when getting a new word. Ill leave the implementation of that logic to you, if you want it.
In the "game controller" code -
you can use the above methods like this -
string file = "your path to txt file";
string[] allWords = ReadWordsFromFile(file);
string WordToGuess = GetRandomWord(allWords);
May be your next goal should be something like this -
public void GameControler()
{
// get all words here and other logic before game starts
while (Attempts > 0)
{
string WordToGuess = GetRandomWord(wordsArray);
// get letterGuessed from user
bool letterExists = CheckIfLetterExists(WordToGuess, letterGuessed);
if (!letterExists)
{
Attempts--;
ExecuteWrongGuessMethod(x, y);
}
else
{
ExecuteRightGuessMethod(w);
}
}
}
public bool CheckIfLetterExists(string word, string letter)
{
if (word.Contains(letter)) return true;
else return false;
}
public void ExecuteWrongGuessMethod(string passWhatYouNeedTo, int somethingElse)
{
// what to do when the guess is wrong e.g. Console.Writeline("wrong guess");
}
public void ExecuteRightGuessMethod(string word)
{
// logic when guess is right. e.g. Show the letter guessed within the word on the console etc.
}
All of this isn't the best way to do it. BUT I personally feel this is logically next step a beginner takes after what you've implemented. Seeing a fully well-developed program might be too much without understanding atleast some basic concepts of OOP.
After learning how to create Methods and use them, then comes classes and objects. Which should be implemented in this game, but this is all for now. I recommend you do a short C# course on coursera etc or even youtube. And slowly move towards a better understanding of SOLID principles. And by SOLID I mean an acronym for the 5 principles and not the actual word. All the best.

Guessing game gets stuck in infinite loop

am trying to make a hangman game where it picks a random word from a text file of words. It then displays the word in asterisks and asks the user to guess each letter of the word if they guess right it uncovers that letter.They keep playing until they guess all the letters in the word.After the word is guessed it will display the number of misses and ask if they want to play again.
The Problem I am having is when the word is guessed correctly it just keeps asking for a letter even if the word is uncovered. I am not sure how to fix this. I would like to do this without using linq if possible.
any help would be appericated
static void Main(string[] args)
{
char[] guessed = new char[26];
char guess = ' ';
char playAgain= ' ';
bool validLetterInput = false;
bool validAnswer = false;
int amountMissed = 0, index = 0;
do
{
// initilization of word and testword so that we could generate a testword with the same length as original
char[] word = RandomLine().Trim().ToCharArray();
char[] testword = new string('*', word.Length).ToCharArray();
char[] copy = word;
Console.WriteLine(testword);
Console.WriteLine("I have picked a random word on animals");
Console.WriteLine("Your task is to guess the correct word");
//Check if the 2 arrays are equal
while (testword != word)
{
while (!validLetterInput)
{
try
{
Console.Write("Please enter a letter to guess: ");
guess = char.Parse(Console.ReadLine().ToLower());
//Checks if guess is letter or not
if (((guess >= 'A' && guess <= 'Z') || (guess >= 'a' && guess <= 'z')))
{
validLetterInput = true;
}
else
{
Console.WriteLine("Invalid Input");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
validLetterInput = false;
bool right = false;
for (int j = 0; j < copy.Length; j++)
{
if (copy[j] == guess)
{
Console.WriteLine("Your guess is correct.");
testword[j] = guess;
guessed[index] = guess;
index++;
right = true;
}
}
if (right != true)
{
Console.WriteLine("Your guess is incorrect.");
amountMissed++;
}
else
{
right = false;
}
Console.WriteLine(testword);
}
Console.WriteLine($"The word is {string.Join("",testword)}. You missed {amountMissed} times.");
while (!validAnswer)
{
try
{
Console.WriteLine("Do you want to guess another word? Enter y or n: ");
playAgain = char.Parse(Console.ReadLine());
if(playAgain == 'y' || playAgain == 'Y' || playAgain == 'n' || playAgain == 'N')
{
validAnswer = true;
}
else
{
Console.WriteLine("Invalid input try again");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
validAnswer = false;
} while (playAgain == 'y' || playAgain == 'Y');
Console.WriteLine("Good-Bye and thanks for playing my Hangman game.");
}
public static string RandomLine()
{
// store text file in an array and return a random value
string[] lines = File.ReadAllLines("E:\\Amimals1.csv");
Random rand = new Random();
return lines[rand.Next(lines.Length)].ToLower();
}
}
There are various ways to compare two arrays / lists. Simple method i see for character arrays / lists is to convert them to strings and then compare.
Array Comparison thread on stackoverflow
testword.ToString() != word.ToString()
In regards to what Flydog57, use this link to learn how to debug code:
Compare the arrays with "SequenceEqual" instead of !=. This way you will need to change your while statement to:
while (!testword.SequenceEqual(word))
This is noted by Quartermeister and further explained by ohn Buchanan in the question "Easiest way to compare arrays in C#". link is here:
Easiest way to compare arrays in C#
Otherwise great program!
Note when you are trying debugging, a simple thing I like to put in there is a write of what response I want to see initially if I cannot figure out through debug. you can always remove the line later. I put this at the end of the while statement.
Console.WriteLine(testword.SequenceEqual(word));

How can I use List.Contains

I have assignment to make Hangman game with methods, so far everything is going ok until I realized that the word that I input by char when has two consecutive characters it can't get the following if statement
if (correctGuesses.Count == randomWord.Length)
{
Console.WriteLine("You won the word is: {0}", randomWord);
break;
}
and thus I can never finish the game if the word is something like Green
I was trying to use List.Contains('*') if contains it to continue if not to break and to write the Word thus to win, but it fails if I put '!' in front or if I don't put it, it becomes a endless loop . Could you please help me if there is a way to use Contains in a way that will not search only for one symbol but will check for every single one until there is no more.
I will post the code here.
static string GeneratingRandomWords()
{
Random r = new Random();
List<string> words = new List<string>() { /*"Cat", "Dog", "Eagle", "Lion", "Shark",*/ "Green" };
string word = words[r.Next(0, words.Count)];
return word;
}
static char Input()
{
char inputt = char.Parse(Console.ReadLine());
return inputt;
}
static char[] TransformingCharToInvisible(string randomWord)
{
char[] charFromString = randomWord.ToCharArray();
for (int i = 0; i < randomWord.Length; i++)
{
charFromString[i] = '*';
}
Console.WriteLine(charFromString);
return charFromString;
}
static int CorrectGuesses(char input, string randomWord, int correct)
{
if (randomWord.Contains(input))
{
Console.WriteLine("Next");
correct++;
}
return correct;
}
static int Lives(string randomWord, char input, int lives)
{
if (!randomWord.Contains(input))
{
Console.WriteLine("Try another one");
lives--;
}
return lives;
}
static List<char> CorrectWord(List<char> correctGuesses, string randomWord, char input)
{
if (randomWord.Contains(input))
{
correctGuesses.Add(input);
char[] charFromString = randomWord.ToCharArray();
for (int i = 0; i < randomWord.Length; i++)
{
charFromString[i] = '*';
if (correctGuesses.Contains(randomWord[i]))
{
charFromString[i] = randomWord[i];
}
}
Console.WriteLine(charFromString);
}
return correctGuesses;
}
static void Main(string[] args)
{
string randomWord = GeneratingRandomWords();
TransformingCharToInvisible(randomWord);
List<char> correctGuesses = new List<char>();
int lives = 10;
int correct = 0;
//bool won = true;
while (true)
{
Console.WriteLine("Write a char");
char input = Input();
correct = CorrectGuesses(input, randomWord, correct);
lives = Lives(randomWord, input, lives);
if (correctGuesses.Contains(input))
{
Console.WriteLine("You've already tried '{0}', and it was correct!", input);
continue;
}
correctGuesses = CorrectWord(correctGuesses, randomWord, input);
if (lives == 0)
{
Console.WriteLine("You lose sorry, try againg next time ");
break;
}
if (correctGuesses.Count == randomWord.Length)
{
Console.WriteLine("You won the word is: {0}", randomWord);
break;
}
}
}
Here a simplified version of your code where i did not add all the error checking but the basics use the required Contains to check if letters are found
static void Main(string[] args)
{
var lives = 10;
var correctGuesses = new List<char>();
var word = "green";
while (true)
{
Console.WriteLine("Guess a letter? ");
// deliberatly just check for 1 character for simplicity reasons
var input = Console.ReadLine()[0];
// if already guessed give a chance to the user to retry
if (correctGuesses.Contains(input))
{
Console.WriteLine("Letter already guessed");
}
else
{
// if the word contains the letter
if (word.Contains(input))
{
// add as a correct guess
correctGuesses.Add(input);
Console.WriteLine("Letter found");
}
else
{
// letter dont exist remove a life
lives--;
Console.WriteLine("Letter not found");
}
}
// check if the user still have lives
if (lives == 0)
{
Console.WriteLine("You lost");
break;
}
// check if the amount of distinct character in the word match
// the amount found. This mean the word is completly guessed
else if (word.Distinct().Count() == correctGuesses.Count())
{
Console.WriteLine("You won you found the word");
break;
}
}
Console.ReadKey();
}
I didn't understand you very well
but I modified your code like this :
private static bool IsCorrectGuess(char input, string actualWord)
{
return actualWord.Contains(input);
}
private static void WriteCorrectGuesses(ICollection<char> correctGuesses, string randomWord)
{
char[] charFromString = randomWord.ToCharArray();
for (var i = 0; i < randomWord.Length; i++)
{
charFromString[i] = '*';
if (correctGuesses.Contains(randomWord[i]))
charFromString[i] = randomWord[i];
}
Console.WriteLine(charFromString);
}
private static string GeneratingRandomWords()
{
var r = new Random();
var words = new List<string>
{
/*"Cat", "Dog", "Eagle", "Lion", "Shark",*/ "Green"
};
return words[r.Next(0, words.Count)];
}
private static char Input()
{
return char.Parse(Console.ReadLine() ?? throw new InvalidOperationException());
}
private static void Main(string[] args)
{
string randomWord = GeneratingRandomWords();
var correctGuesses = new List<char>();
WriteCorrectGuesses(correctGuesses, randomWord);
var lives = 10;
var correct = 0;
//bool won = true;
while (true)
{
Console.WriteLine("Write a char");
char input = Input();
if (IsCorrectGuess(input, randomWord))
{
// correct letter
int score = randomWord.ToCharArray().Count(item => item == input);
for (var i = 0; i < score; i++)
{
correctGuesses.Add(input);
correct++;
}
WriteCorrectGuesses(correctGuesses, randomWord);
if (correctGuesses.Count == randomWord.Length)
{
Console.WriteLine("You won the word is: {0}", randomWord);
Console.Read();
break;
}
Console.WriteLine("Next");
}
else
{
// wrong letter
Console.WriteLine($"Try another one. You still have {lives} to try.");
lives--;
}
if (lives == 0)
{
Console.WriteLine("You lose sorry, try again next time ");
break;
}
}
}

StringBuilder display spaces in hidden message

So essentially I want the displayToPlayer variable have the spaces automatically added but I'm not quite sure how to achieve this.
How can I have the spaces automatically added to the hidden message without using a turn or it been added to the guessed letter tally.
Current Result:
Desired Result:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace guessingGame
{
class Program
{
static void Main(string[] args)
{
string[] quoteList = {
"NEVER GUNNA LET YOU DOWN",
/*"NEVER GUNNA RUN AROUND",
"THIS IS A TEST"*/
}; // the list of quotes that need to be guessed by the player
Random random = new Random((int)DateTime.Now.Ticks);
string quoteToGuess = quoteList[random.Next(0, quoteList.Length)];
string quoteToGuessUppercase = quoteToGuess.ToUpper();
StringBuilder displayToPlayer = new StringBuilder(quoteToGuess.Length);
for (int i = 0; i < quoteToGuess.Length; i++)
{
displayToPlayer.Append('*');
}
List<char> correctGuesses = new List<char>();
List<char> incorrectGuesses = new List<char>();
int quoteToGuessLength = quoteToGuess.Count(characters => !Char.IsWhiteSpace(characters));
int turnsLeft = quoteToGuess.Distinct().Count(characters => !Char.IsWhiteSpace(characters)) + 3;
bool quoteGuessed = false;
int lettersRevealed = 0;
string userInput;
char userGuess;
Console.WriteLine("Can you work out the quote? (you have {0} chances)", turnsLeft);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine(displayToPlayer.ToString());
Console.WriteLine();
while (!quoteGuessed && turnsLeft > 0)
{
Console.Write("Enter your letter ==>");
try
{
userInput = Console.ReadLine().ToUpper();
userGuess = userInput[0];
if (correctGuesses.Contains(userGuess))
{
Console.WriteLine("You've already tried '{0}', and it was correct!", userGuess);
continue;
}
else if (incorrectGuesses.Contains(userGuess))
{
Console.WriteLine("You've already tried '{0}', and it was wrong!", userGuess);
continue;
}
if (quoteToGuessUppercase.Contains(userGuess))
{
correctGuesses.Add(userGuess);
for (int i = 0; i < quoteToGuess.Length; i++)
{
if (quoteToGuessUppercase[i] == userGuess)
{
displayToPlayer[i] = quoteToGuess[i];
lettersRevealed++;
}
}
if (lettersRevealed == quoteToGuess.Length)
{
quoteGuessed = true;
}
turnsLeft--;
Console.Clear();
Console.WriteLine("You have guessed {0} letter(s) out of a total of {1}", lettersRevealed, quoteToGuessLength);
Console.WriteLine("You have {0} attempts remaining!", turnsLeft);
Console.WriteLine();
Console.WriteLine(displayToPlayer.ToString());
Console.WriteLine();
Console.WriteLine("Correct guess, there's a '{0}' in it!", userGuess);
Console.WriteLine();
}
else
{
incorrectGuesses.Add(userGuess);
turnsLeft--;
Console.Clear();
Console.WriteLine("You have guessed {0} letter(s) out of a total of {1}", lettersRevealed, quoteToGuessLength);
Console.WriteLine("You have {0} attempts remaining!", turnsLeft);
Console.WriteLine();
Console.WriteLine(displayToPlayer.ToString());
Console.WriteLine();
Console.WriteLine("Incorrect guess, there's no '{0}' in it!", userGuess);
Console.WriteLine();
}
}
catch (Exception e)
{
Console.WriteLine("Enter A Valid Character");
}
}
if (quoteGuessed)
{
Console.WriteLine(quoteToGuess);
Console.WriteLine("You have guessed all {0} letters out of a total of {0} Well done!!!", quoteToGuessLength);
}
else
{
Console.WriteLine("You lost! It was '{0}'", quoteToGuess);
}
}
}
}
If i understand you correctly, this will probably work
for (int i = 0; i < quoteToGuess.Length; i++)
{
displayToPlayer.Append(quoteToGuess[i] == ' ' ? ' ' : '*');
}
Its basically saying, if the character at the index of i in quoteToGuess is ' ', then add ' ', if not add '*'
?: Operator (C# Reference)
The conditional operator (?:), commonly known as the ternary
conditional operator, returns one of two values depending on the value
of a Boolean expression. Following is the syntax for the conditional
operator.
Strings and indexes
An index is the position of a Char object (not a Unicode character) in
a String. An index is a zero-based, nonnegative number that starts
from the first position in the string, which is index position zero
You can get rid of the StringBuilder and your for loop completely using System.Linq:
var displayToPlayer = new string(quoteToGuess.Select(c => c == ' ' ? ' ' : '*').ToArray());
If you get an error because Select() doesn't seem to be defined, add this on top of your file:
using System.Linq;

Cant understand why the for loop get out of range

I am learning c#, and have home works to make simple dictionary in console aplication.
I wrote all the code and it should work good but in one of the for loops the program throws Error:System.IndexOutofRange.
I tried all I know (I am only beginner so I dont know much) but it always gives the error.
The main idea of the program is the user must enter how much words he wishes to use then enter the words in the his language (my is Hebrew so in the program is Hebrew) and in English and it save the words in two deffernt Arrays but in same index. Then the program ask the user to enter sentence in his language and then the program runs on the sentence finds the words (each time the program see space it starts a new word), then with another for loop it looks in the Hebrew Array and if it finds match place the word that in the same index but in the English Array, and if not found it writes the original word.
static void Main(string[] args)
{
Console.WriteLine("Enter the number of words you wish to use");
int wordsNumber = int.Parse(Console.ReadLine());
string[] hebrew = new string[wordsNumber];
string[] english = new string[wordsNumber];
for (int i = 0; i < wordsNumber; i++)
{
Console.WriteLine("Enter word in Hebrew.");
hebrew[i] = Console.ReadLine();
Console.WriteLine("Now enter the translate of {0} in English.",hebrew[i]);
english[i] = Console.ReadLine();
}
Console.WriteLine("Now enter the sentence that you want to translate..and press ENTER");
string searchSentence = Console.ReadLine();
string translateWord = "";
string result = "";
while(searchSentence != "stop")
{
for (int i = 0; i < searchSentence.Length;i++ )
{
translateWord = "";
while ((searchSentence[i] == ' ')&&(searchSentence.Length > i))//Skip the spaces in the start of the sentence
i++;
while ((searchSentence[i] != ' ') && (searchSentence.Length > i))//Here is the problem when with the OutOfRnge
{
translateWord += searchSentence[i];
i++;
}
for(int j = 0;j<hebrew.Length ;j++)
{
if (translateWord == hebrew[j])
{
result += english[j];
}
else
{
result += translateWord[i];
}
result += " ";
}
}
Console.WriteLine(result);
Console.WriteLine("Enter new sentence for translate or enter 'stop' to EXIT the programm");
searchSentence = Console.ReadLine();
}
while ((searchSentence[i] != ' ') && (searchSentence.Length > i))
Consider that the way you are used to read (right-to-left in your neck of the woods) is affecting the way you write code. This code is backwards, both in the order of the && operands and in the Length test. And thus doesn't take advantage of the short-circuiting behavior of the && operator. Probably difficult to unlearn, something you'll have to work on.
Avoid this exception with:
while ((i < searchSentence.Length) && (searchSentence[i] != ' '))
Which ensures that searchSentence[i] cannot throw the IndexOutOfRangeException.
Your code was very confusing and it would be hard to tell where the error was.. However you would be better off constructing a dictionary full of translations and then using that. I have left out error handling for you to expand upon but here is an example of doing the exact same - but with a dictionary
Dictionary<string, string> words = new Dictionary<string, string>();
Console.WriteLine("Enter the number of words you wish to use");
int wordsNumber = int.Parse(Console.ReadLine());
for (int i = 0; i < wordsNumber; i++)
{
Console.WriteLine("Enter word in Hebrew.");
string hebrew = Console.ReadLine();
Console.WriteLine("Now enter the translate of {0} in English.", hebrew);
string english = Console.ReadLine();
words.Add(hebrew, english);
}
Console.WriteLine("Now enter the sentence that you want to translate..and press ENTER");
string searchSentence = Console.ReadLine();
string[] splitSentence = searchSentence.Split(new char[]{' '});
string result = "";
foreach (string s in splitSentence)
result += string.Format("{0} ", words[s]);
Console.WriteLine(result);
Console.ReadLine();
Looking at
while(searchSentence != "stop")
{
for (int i = 0; i < searchSentence.Length;i++ )
{
translateWord = "";
while ((searchSentence[i] == ' ')&&(searchSentence.Length > i))//Skip the spaces in the start of the sentence
i++; //updated here and used on nex line when i could be greater than SearchSentence.Length now
while ((searchSentence[i] != ' ') && (searchSentence.Length > i))//Here is the problem when with the OutOfRnge
{
translateWord += searchSentence[i];
i++; // updated here
}
for(int j = 0;j<hebrew.Length ;j++)
{
if (translateWord == hebrew[j])
{
result += english[j];
}
else
{
result += translateWord[i];
}
result += " ";
}
}
You increment i inside the for loop. If it becomes equal to or greater than searchSentence.Length then you use it it will throw the error you get
edit to fix make this change from this
for (int i = 0; i < searchSentence.Length;i++ )
{
translateWord = "";
while ((searchSentence[i] == ' ')&&(searchSentence.Length > i))//Skip the spaces in the start of the sentence
i++;
while ((searchSentence[i] != ' ') && (searchSentence.Length > i))//Here is the problem when with the OutOfRnge
{
translateWord += searchSentence[i];
i++;
}
for(int j = 0;j<hebrew.Length ;j++)
{
if (translateWord == hebrew[j])
{
result += english[j];
}
else
{
result += translateWord[i];
}
result += " ";
}
}
to this
for (int i = 0; i < searchSentence.Length;i++ )
{
if(((searchSentence[i] != ' ')&&(searchSentence.Length > i)))
{
while ((searchSentence[i] != ' ') && (searchSentence.Length > i))//Here was the problem when with the OutOfRnge
{
translateWord += searchSentence[i];
i++; // updated here
if(i>=searchSentence.Length)
{
break;
}
}
if(i>=searchSentence.Length)
for(int j = 0;j<hebrew.Length ;j++)
{
if (translateWord == hebrew[j])
{
result += english[j];
}
else
{
result += translateWord[i];
}
result += " ";
}
}
}

Categories