Word disappears in Console.Write(); - c#

My program shows the letter and then asks with what letter should you replace it:
static void Main(string[] args)
{
string textToEncode = File.ReadAllText(#"C:\Users\ASUS\Desktop\szyfrowanie2\TextSample.txt");
textToEncode = textToEncode.ToLower();
string distinctLetters = new string(textToEncode.Distinct().ToArray());
var count = textToEncode.Distinct().Count();
Console.WriteLine("Letters used in text: \n\n");
int iteration = 0;
for (int i = 0; i < count; i++)
{
if (Equals(distinctLetters[i], ' ')) { Console.Write(" <space> "); }
else if (Equals(distinctLetters[i], '\r')) { continue; }
else if (Equals(distinctLetters[i], '\n')) { continue; }
else { Console.Write(distinctLetters[i] + " "); }
}
Console.WriteLine("\n\nEncoding: \nPlease do not use single non-letter characters for coding (such as ',' or '?'");
List<string> charsUsedToEncode = new List<string>();
List<string> charsEncoded = new List<string>();
while (iteration < count)
{
if (Equals(distinctLetters[iteration], ' ')) { Console.Write("Swap <space> with "); }
else { Console.Write("Swap " + distinctLetters[iteration] + " with "); }
string string1 = Console.ReadLine();
if (string.IsNullOrEmpty(string1) == true)
{
Console.WriteLine("You have to type a character. ");
}
else if (string1.Length > 1)
{
Console.WriteLine("You entered more than one character. ");
}
else
{
char SwappingMark = char.Parse(string1);
if (charsUsedToEncode.Contains(SwappingMark.ToString()))
{
Console.WriteLine("\nThis character has already been used.");
}
else if (Equals(distinctLetters[iteration], '\r')) { continue; }
else if (Equals(distinctLetters[iteration], '\n')) { continue; }
else
{
charsEncoded.Add(distinctLetters[iteration].ToString());
charsUsedToEncode.Add(SwappingMark.ToString());
SwappingMark = char.ToUpper(SwappingMark);
textToEncode = textToEncode.Replace(distinctLetters[iteration], SwappingMark);
iteration++;
}
}
}
textToEncode = textToEncode.ToLower();
Console.ReadLine();
}
The problem is, after a '.' char The word "Swap" disappears. It looks like this:
Swap w with a
...
Swap . with x
y with l
The word "Swap" disappears. In my TextSample after a '.' text starts in new line and I don't know why, since there is a else if (Equals(distinctLetters[iteration], '\n')) { continue; } condition.

As I mentioned in the comments, the problem is that you skip the new-line characters before printing them but they're still in the string. So, you skip them again but after actually printing the "swap" statement to the user (causing those characters to be displayed before they're ignored).
What you should do instead is not include them in the array from the beginning. Also, there's no need to create a new string; you can just use a char array like this:
char[] distinctLetters = textToEncode.Distinct()
.Where(c=> !"\r\n".Contains(c))
.ToArray();
That way, you never have to check for \r or \n again since they don't exist.
Full example:
static void Main(string[] args)
{
string textToEncode = File.ReadAllText(#"C:\Users\ASUS\Desktop\szyfrowanie2\TextSample.txt");
textToEncode = textToEncode.ToLower();
char[] distinctLetters = textToEncode.Distinct()
.Where(c=> !"\r\n".Contains(c))
.ToArray();
var count = distinctLetters.Count();
Console.WriteLine("Letters used in text: \n\n");
int iteration = 0;
for (int i = 0; i < count; i++)
{
if (distinctLetters[i] == ' ') { Console.Write(" <space> "); }
else { Console.Write(distinctLetters[i] + " "); }
}
Console.WriteLine("\n\nEncoding: \nPlease do not use single non-letter characters for coding (such as ',' or '?'");
List<string> charsUsedToEncode = new List<string>();
List<string> charsEncoded = new List<string>();
while (iteration < count)
{
if (distinctLetters[iteration] == ' ') { Console.Write("Swap <space> with "); }
else { Console.Write("Swap " + distinctLetters[iteration] + " with "); }
string string1 = Console.ReadLine();
if (string.IsNullOrEmpty(string1))
{
Console.WriteLine("You have to type a character. ");
}
else if (string1.Length > 1)
{
Console.WriteLine("You entered more than one character. ");
}
else
{
char SwappingMark = char.Parse(string1);
if (charsUsedToEncode.Contains(SwappingMark.ToString()))
{
Console.WriteLine("\nThis character has already been used.");
}
else
{
charsEncoded.Add(distinctLetters[iteration].ToString());
charsUsedToEncode.Add(SwappingMark.ToString());
SwappingMark = char.ToUpper(SwappingMark);
textToEncode = textToEncode.Replace(distinctLetters[iteration], SwappingMark);
iteration++;
}
}
}
textToEncode = textToEncode.ToLower();
Console.ReadLine();
}

Related

Hangman - when I enter a wrong letter, the message system index out of range appears

I am trying to make a hangman game in the console app but got a message index out of range.
The image below shows that I can enter a letter. If I enter a wrong letter I can enter a new letter after entering a new letter I get the message system out of range.
I think the error can be found within the method public bool raadletter (char letter).
This program contains 2 classes, the first class is the galgjespel class (hangmangame) and the second class is the program class.
//I got this stacktrace value
~
error message
at galgje2.GalgjeSpel.Raadletter(Char letter) in C:\Users\surface pro\source\repos\week3opdracht1\galgje2\Galgjespel.cs: line 37
at galgje2.Program.Speelgalgje(GalgjeSpel galgje) in C:\Users\surface pro\source\repos\week3opdracht1\galgje2\Program.cs: line 128
at galgje2.Program.Start() in C:\Users\surface pro\source\repos\week3opdracht1\galgje2\Program.cs: line 28
at galgje2.Program.Main(String[] args) in C:\Users\surface pro\source\repos\week3opdracht1\galgje2\Program.cs: line 14
~
//
class GalgjeSpel
{
public string secretWord;
public string guessedWord;
public void Init(string secretword)
{
this.secretWord = secretword;
this.guessedWord="";
char[] letter = new char [secretword.Length];
for (int i =0; i< letter.Length; i++)
{
this.guessedWord += ".";
}
}
public bool Raadletter(char letter)
{
char[] guesses = guessedWord.ToArray();
guessedWord = "";
if (secretWord.Contains(letter))
{
for(int i=0; i<secretWord.Length; i++)
{
// somewhere on this place i get the index out of range message
if (secretWord[i]==letter)
{
guesses[i] = letter;
}
}
foreach(var element in guesses)
{
guessedWord += element;
if (element!='.')
{
Console.Write($"{element} ");
}
else
{
Console.Write($". ");
}
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("------------------------------");
Console.ResetColor();
Console.WriteLine();
// return true;
}
else
{
Console.WriteLine("letter does not match secretword");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("------------------------------");
Console.ResetColor();
}
return false;
}
}
////
class Program
{
static void Main(string[] args)
{
Program myProgam = new Program();
myProgam.Start();
Console.ReadKey();
}
void Start()
{
GalgjeSpel galgje = new GalgjeSpel();
galgje.Init("eetlepel");
List<string> woordenlijst = WoordenLijst();
string nieuwwoord= SelecteerWoord(woordenlijst);
galgje.Init(nieuwwoord);
ToonWoord(nieuwwoord);Speelgalgje(galgje);
//Console.WriteLine("Het geheime woord is: " + galgje.geheimWoord);
//Console.WriteLine("Het geraden woord is: " + galgje.geradenWoord);
}
List <string> WoordenLijst()
{
List<string> Woordenlijst = new List<string>();
Woordenlijst.Add("slapen");
Woordenlijst.Add("poepen");
Woordenlijst.Add("eten");
Woordenlijst.Add("vakantie");
Woordenlijst.Add("reizen");
return Woordenlijst;
}
string SelecteerWoord(List<string> woorden)
{
GalgjeSpel gaglje = new GalgjeSpel();
Random rnd = new Random();
int randomwoord = rnd.Next(1, 5);
string nieuwwoord = woorden[randomwoord];
gaglje.secretWord = nieuwwoord;
return nieuwwoord;
}
void ToonWoord(string woord)
{
GalgjeSpel galgje = new GalgjeSpel();
Console.Write($"The secret word is : ");
char[] letter = woord.ToArray();
for (int i = 0; i< woord.Length; i++)
{
galgje.secretWord += letter[i];
Console.Write($"{letter[i]} ");
}
Console.WriteLine();
Console.Write("the guessed word is : ");
for (int i = 0; i < woord.Length; i++)
{
galgje.guessedWord += (". ");
Console.Write(". ");
}
Console.WriteLine();
}
void ToonLetter(List<char> letters)
{
Console.Write("the letters entered are : ");
foreach (var element in letters)
{
Console.Write($" {element} ");
}
Console.WriteLine();
}
char LeesLetter(List<char> geheimeletters)
{
char letter;
do
{ Console.WriteLine();
Console.Write("enter a letter : ");
letter = char.Parse(Console.ReadLine());
return letter;
} while (geheimeletters.Contains(letter));
{
}
}
bool Speelgalgje(GalgjeSpel galgje)
{
//char lijst van ingevoerde letters
List<char> ingevoerdeLetters = new List<char>();
// char lijst van geheime letters
List<char> geheimeletters = new List<char>();
// zet elke geheime letter in een char array
char[]geheimewoord = galgje.secretWord.ToArray();
// voeg elke char letter toe aan lijst van geheime letters
for (int i=0; i<geheimewoord.Length; i++)
{
geheimeletters.Add(geheimewoord[i]);
if (galgje.guessedWord == galgje.secretWord)
{
return true;
}
else
{ char letter = LeesLetter(geheimeletters);
ingevoerdeLetters.Add(letter);
ToonLetter(ingevoerdeLetters);
galgje.Raadletter(letter);
}
}return false;
}
}
The problem lies in the code before the point of the exception
public bool Raadletter(char letter)
{
char[] guesses = guessedWord.ToArray();
// Here guessedWord is truncated
guessedWord = "";
// Now if the letter is not in the secretword you don repopulate the guessedword
// So at the next loop the code builds a guesses array
// that doesn't match anymore to the secretWord length
if (secretWord.Contains(letter))
{
for (int i = 0; i < secretWord.Length; i++)
{
if (secretWord[i] == letter)
{
guesses[i] = letter;
}
}
// Here you rebuild the guessedWord, but only if you have a match
foreach (var element in guesses)
{
guessedWord += element;
....
}
}
else
{
// fail messages
}
The solution is to close the if and rebuild the guessedWord in each case
char[] guesses = guessedWord.ToArray();
guessedWord = "";
if (secretWord.Contains(letter))
{
for (int i = 0; i < secretWord.Length; i++)
{
if (secretWord[i] == letter)
{
guesses[i] = letter;
}
}
}
foreach(var element in guesses)
{
guessedWord += element;
.....
}

c# hangman - how to show every new row the letters that are tried at the right spot

The image below descripes the output that i have got for so far..
it misses the old letters that are tried.
so if a letter is guessed right, al the letters inclusive the old guess letters need to show on the point .......
now it only shows the given letter without the old letters
//
// this is the code that i got for so far
class Program
{
static void Main(string[] args)
{
Program myProgam = new Program();
myProgam.Start();
Console.ReadKey();
}
void Start()
{
GalgjeSpel galgje = new GalgjeSpel();
galgje.Init("eetlepel");
List<string> woordenlijst = WoordenLijst();
string nieuwwoord= SelecteerWoord(woordenlijst);
galgje.Init(nieuwwoord);
ToonWoord(nieuwwoord);Speelgalgje(galgje);
//Console.WriteLine("Het geheime woord is: " + galgje.geheimWoord);
//Console.WriteLine("Het geraden woord is: " + galgje.geradenWoord);
}
List <string> WoordenLijst()
{
List<string> Woordenlijst = new List<string>();
Woordenlijst.Add("slapen");
Woordenlijst.Add("poepen");
Woordenlijst.Add("eten");
Woordenlijst.Add("vakantie");
Woordenlijst.Add("reizen");
return Woordenlijst;
}
string SelecteerWoord(List<string> woorden)
{
GalgjeSpel gaglje = new GalgjeSpel();
Random rnd = new Random();
int randomwoord = rnd.Next(1, 5);
string nieuwwoord = woorden[randomwoord];
gaglje.geheimWoord = nieuwwoord;
return nieuwwoord;
}
void ToonWoord(string woord)
{
GalgjeSpel galgje = new GalgjeSpel();
Console.Write($"het geheime woord is: ");
char[] letter = woord.ToArray();
for (int i = 0; i< woord.Length; i++)
{
galgje.geheimWoord += letter[i];
Console.Write($"{letter[i]} ");
}
Console.WriteLine();
Console.Write("het geraden woord is: ");
for (int i = 0; i < woord.Length; i++)
{
galgje.geradenWoord += (". ");
Console.Write(". ");
}
Console.WriteLine();
}
void ToonLetter(List<char> letters)
{
int i = 0;
Console.Write("Ingevoerde letters zijn: ");
foreach (var element in letters)
{
Console.Write($"{letters[i]} ");
i += 1;
}
Console.WriteLine();
}
char LeesLetter(List<char> geheimeletters)
{
char letter;
List<char> ingevoerdeletter = new List<char>();
string tletter ="";
do
{ Console.WriteLine();
Console.Write("voer een letter in: ");
letter = char.Parse(Console.ReadLine());
tletter =tletter + " "+ letter ;
return letter;
} while (geheimeletters.Contains(letter));
{
}
}
bool Speelgalgje(GalgjeSpel galgje)
{
//char lijst van ingevoerde letters
List<char> ingevoerdeLetters = new List<char>();
// char lijst van geheime letters
List<char> geheimeletters = new List<char>();
// zet elke geheime letter in een char array
char[]geheimewoord = galgje.geheimWoord.ToArray();
// voeg elke char letter toe aan lijst van geheime letters
for (int i=0; i<geheimewoord.Length; i++)
{
geheimeletters.Add(geheimewoord[i]);
if (galgje.geradenWoord == galgje.geheimWoord)
{
return true;
}
else
{ char letter = LeesLetter(geheimeletters);
ingevoerdeLetters.Add(letter);
ToonLetter(ingevoerdeLetters);
galgje.Raadletter(letter);
}
}return false;
}
}
////
namespace galgje2
{
class GalgjeSpel
{
public string geheimWoord;
public string geradenWoord;
public void Init(string geheimwoord)
{
this.geheimWoord = geheimwoord;
this.geradenWoord="";
char[] letter = new char [geheimwoord.Length];
for (int i =0; i< letter.Length; i++)
{
this.geradenWoord += ".";
}
}
public bool Raadletter(char letter)
{
char[] secretword = geradenWoord.ToArray();
if (geheimWoord.Contains(letter))
{
for(int i=0; i<geheimWoord.Length; i++)
{
if (geheimWoord[i]==letter)
{
secretword[i] = letter;
Console.Write($"{letter} ");
}
else
{
Console.Write($". ");
}
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("------------------------------");
Console.ResetColor();
Console.WriteLine();
}
else
{
Console.WriteLine("letter does not match secretword");
}
return false;
}
}
}
The problem is in the Raadletter function you show only the current letter in the console.
if (geheimWoord[i]==letter)
{
secretword[i] = letter; // you store the letter in the char array
//you should print the array
Console.Write($"{letter} ");
}
else
{
Console.Write($". ");
}
If you want to print all guesses letter your code should look have something similar:
public bool Raadletter(char letter)
{
char[] secretword = geradenWoord.ToArray();
if (geheimWoord.Contains(letter))
{
geradenWoord = ""; //clear the sring only if contain letter
for (int i = 0; i < geheimWoord.Length; i++)
{
if (geheimWoord[i] == letter)
{
secretword[i] = letter; //store good letter to array
}
}
foreach (var c in secretword)
{
geradenWoord += c;// save the word
// print guesses letters
Console.Write($"{c} ");
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("------------------------------");
Console.ResetColor();
Console.WriteLine();
}
else
{
Console.WriteLine("letter does not match secretword");
}
return false;
}

Forcing Console to Skip Already-Guessed Characters in a Randomly Cycling Code-Guesser

The code begins by asking how many digits a code is. It then creates a random string of letters as long as the answer, and begins cycling through characters until it finds the code. Each character that matches is kept in the same place until each character matches.
The issue is with the console continuously guessing the incorrect character, leading to situations where the console continues guessing the wrong character and never solving it.
So, I want the console to not try incorrect characters after guessing them already.
On a side note, if anyone has any ideas on how I could change the code to instead guess one character at a time, then continue to the next, please tell me, thanks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApp3
{
class Program
{
private static Random random = new Random();
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
string intro6 = "How many characters in the password? (USE INTEGERS)";
foreach (char c in intro6)
{
Console.Write(c);
Thread.Sleep(50);
}
Console.WriteLine("");
string delta = Console.ReadLine();
try
{
int passwordlength = Convert.ToInt32(delta);
// BARRIER
string password = RandomString(passwordlength);
Random r = new Random();
string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
List<string> dictionary = new List<string>(new string[] {
password
});
string word = dictionary[r.Next(dictionary.Count)];
List<int> indexes = new List<int>();
Console.ForegroundColor = ConsoleColor.Red;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.Length; i++)
{
sb.Append(letters[r.Next(letters.Length)]);
if (sb[i] != word[i])
{
indexes.Add(i);
}
}
Console.WriteLine(sb.ToString());
while (indexes.Count > 0)
{
int index;
Thread.Sleep(10);
Console.Clear();
for (int i = indexes.Count - 1; i >= 0; i--)
{
index = indexes[i];
sb[index] = letters[r.Next(letters.Length)];
if (sb[index] == word[index])
{
indexes.RemoveAt(i);
}
}
var output = sb.ToString();
for (int i = 0; i < output.Length; i++)
{
if (indexes.Contains(i))
{
Console.ForegroundColor = ConsoleColor.Red;
}
else
{
Console.ForegroundColor = ConsoleColor.Cyan;
}
Console.Write(output[i]);
}
Console.WriteLine();
}
Console.ForegroundColor = ConsoleColor.Green;
string outro1 = "Password successfully breached. Have a nice day.";
foreach (char c in outro1)
{
Console.Write(c);
Thread.Sleep(20);
}
Console.WriteLine("");
Thread.Sleep(100);
Console.ReadLine();
}
catch
{
if (delta is string)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Clear();
Console.WriteLine("FATAL ERROR PRESS ENTER TO EXIT");
Console.ReadLine();
}
else
{
Console.WriteLine("welp, it was worth a try.");
Console.ReadLine();
}
}
}
}
}
As wubbler mentioned in his comment, it appears that you have a discrepancy between the characters being used to create the random password and the characters then being used to guess the password.
To create:
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
To guess:
string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
This causes the program to be unable to guess the password when the randomly generated password contains any numbers. By adding the numbers to the guessable characters, the program then succeeds more consistently.
And as for the request:
I want the console to not try incorrect characters after guessing them
already
You can achieve this by keeping a collection of guessable characters per index, and then removing a character from it's collection for the given index once it's guessed. The following code satisfies this:
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
string intro6 = "How many characters in the password? (USE INTEGERS)";
foreach (char c in intro6)
{
Console.Write(c);
Thread.Sleep(50);
}
Console.WriteLine("");
string delta = Console.ReadLine();
try
{
int passwordlength = Convert.ToInt32(delta);
// BARRIER
string password = RandomString(passwordlength);
Random r = new Random();
string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
List<string> dictionary = new List<string>(new string[] { password });
string word = dictionary[r.Next(dictionary.Count)];
List<int> indexes = new List<int>();
Console.ForegroundColor = ConsoleColor.Red;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.Length; i++)
{
sb.Append(letters[r.Next(letters.Length)]);
if (sb[i] != word[i])
{
indexes.Add(i);
}
}
Console.WriteLine(sb.ToString());
var charsToGuessByIndex = indexes.ToDictionary(k => k, v => letters);
while (indexes.Count > 0)
{
int index;
Thread.Sleep(10);
Console.Clear();
for (int i = indexes.Count - 1; i >= 0; i--)
{
index = indexes[i];
var charsToGuess = charsToGuessByIndex[index];
sb[index] = charsToGuess[r.Next(charsToGuess.Length)];
charsToGuessByIndex[index] = charsToGuess.Remove(charsToGuess.IndexOf(sb[index]), 1);
if (sb[index] == word[index])
{
indexes.RemoveAt(i);
}
}
var output = sb.ToString();
for (int i = 0; i < output.Length; i++)
{
if (indexes.Contains(i))
{
Console.ForegroundColor = ConsoleColor.Red;
}
else
{
Console.ForegroundColor = ConsoleColor.Cyan;
}
Console.Write(output[i]);
}
Console.WriteLine();
}
Console.ForegroundColor = ConsoleColor.Green;
string outro1 = "Password successfully breached. Have a nice day.";
foreach (char c in outro1)
{
Console.Write(c);
Thread.Sleep(20);
}
Console.WriteLine("");
Thread.Sleep(100);
Console.ReadLine();
}
catch
{
if (delta is string)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Clear();
Console.WriteLine("FATAL ERROR PRESS ENTER TO EXIT");
Console.ReadLine();
}
else
{
Console.WriteLine("welp, it was worth a try.");
Console.ReadLine();
}
}
}
The charsToGuessByIndex keeps track of which characters can be guessed per index, and is updated accordingly inside the for loop where characters are guessed at:
charsToGuessByIndex[index] = charsToGuess.Remove(charsToGuess.IndexOf(sb[index]), 1);

Keeping track of what the user inputs

This is my hangman code, and its almost good up to the point where it displays the guessed letters. It only displays the most recent guessed letter but I want it to continue on from whats left off. Such as if a person guess "A" and then "L" then Guessed letters are A, L.
I tried using a for loop after "Guessed letters are" but then it gives me the output
"A, A, A, A, A". What should I do to fix this problem?
class Hangman
{
public string[] words = new string[5] { "ARRAY", "OBJECT", "CLASS", "LOOP", "HUMBER" };
public string[] torture = new string[6] { "left arm", "right arm", "left leg", "right leg", "body", "head" };
public char[] guessed = new char[26];
int i;
public void randomizedWord()
{
Random random = new Random();
int index = random.Next(0, 5);
char[] hidden = new char[words[index].Length];
string word = words[index];
Console.WriteLine(words[index]);
Console.Write("The word is: ");
for (i = 0; i < hidden.Length; i++)
{
Console.Write('-');
hidden[i] = '-';
}
Console.WriteLine();
int lives = 6;
do
{
Console.WriteLine("Guess a letter: ");
char userinput = Console.ReadLine().ToCharArray()[0];
index++;
guessed[index] = userinput;
Console.WriteLine("Guessed letters are: " + guessed[index]);
bool foundLetter = false;
for (int i = 0; i < hidden.Length; i++)
{
if (word[i] == userinput)
{
hidden[i] = userinput;
foundLetter = true;
Console.WriteLine("You guessed right!");
}
}
for (int x = 0; x < hidden.Length; x++)
{
Console.Write(hidden[x]);
}
if (!foundLetter)
{
Console.WriteLine(" That is not a correct letter");
lives--;
if (lives == 5)
{
Console.WriteLine("You lost a " + torture[0]);
}
else if (lives == 4)
{
Console.WriteLine("You lost the " + torture[1]);
}
else if (lives == 3)
{
Console.WriteLine("You lost your " + torture[2]);
}
else if (lives == 2)
{
Console.WriteLine("You lost the " + torture[3]);
}
else if (lives == 1)
{
Console.WriteLine("You lost your " + torture[4]);
}
else
{
Console.WriteLine("You lost your " + torture[5]);
Console.WriteLine("You lose!");
break;
}
}
bool founddash = false;
for (int y = 0; y < hidden.Length; y++)
{
if (hidden[y] == '-')
{
founddash = true;
}
}
if (!founddash)
{
Console.WriteLine(" You Win! ");
break;
}
Console.WriteLine();
} while (lives != 0);
}
I was going to post on your other thread Hangman Array C#
Try changing this line
Console.WriteLine("Guessed letters are: " + guessed[index]);
To
Console.WriteLine("Guessed letters are: " + string.Join(" ", guessed).Trim());
I had a play with your hangman game and came up with this solution (while we are doing your homework). Although not related to the question.
public class HangCSharp
{
string[] words = new string[5] { "ARRAY", "OBJECT", "CLASS", "LOOP", "HUMBER" };
List<char> guesses;
Random random = new Random();
string word = "";
string current = "";
int loss = 0;
readonly int maxGuess = 6;
int highScrore = 0;
public void Run()
{
word = words[random.Next(0, words.Length)];
current = new string('-', word.Length);
loss = 0;
guesses = new List<char>();
while (loss < maxGuess)
{
Console.Clear();
writeHeader();
writeLoss();
writeCurrent();
var guess = Console.ReadKey().KeyChar.ToString().ToUpper()[0];
while (!char.IsLetterOrDigit(guess))
{
Console.WriteLine("\nInvalid Guess.. Please enter a valid alpha numeric character.");
Console.Write(":");
guess = Console.ReadKey().KeyChar;
}
while (guesses.Contains(guess))
{
Console.WriteLine("\nYou have already guessed {0}. Please try again.", guess);
Console.Write(":");
guess = Console.ReadKey().KeyChar;
}
guesses.Add(guess);
if (!isGuessCorrect(guess))
loss++;
else if (word == current)
break;
}
Console.Clear();
writeHeader();
writeLoss();
if (loss >= maxGuess)
writeYouLoose();
else
doYouWin();
Console.Write("Play again [Y\\N]?");
while (true)
{
var cmd = (Console.ReadLine() ?? "").ToUpper()[0];
if (cmd != 'Y' && cmd != 'N')
{
Console.WriteLine("Invalid Command. Type Y to start again or N to exit.");
continue;
}
else if (cmd == 'Y')
Run();
break;
}
}
bool isGuessCorrect(char guess)
{
bool isGood = word.IndexOf(guess) > -1;
List<char> newWord = new List<char>();
for (int i = 0; i < word.Length; i++)
{
if (guess == word[i])
newWord.Add(guess);
else
newWord.Add(current[i]);
}
current = string.Join("", newWord);
return isGood;
}
void writeCurrent()
{
Console.WriteLine("Enter a key below to guess the word.\nHint: {0}", current);
if (guesses.Count > 0)
Console.Write("Already guessed: {0}\n", string.Join(", ", this.guesses));
Console.Write(":");
}
void writeHeader()
{
Console.WriteLine("Hang-CSharp... v1.0\n\n");
if (highScrore > 0)
Console.WriteLine("High Score:{0}\n\n", highScrore);
}
void writeYouLoose()
{
Console.WriteLine("\nSorry you have lost... The word was {0}.", word);
}
void doYouWin()
{
Console.WriteLine("Congratulations you guessed the word {0}.", word);
int score = maxGuess - loss;
if (score > highScrore)
{
highScrore = score;
Console.WriteLine("You beat your high score.. New High Score:{0}", score);
}
else
Console.WriteLine("Your score:{0}\nHigh Score:{1}", score, highScrore);
}
void writeLoss()
{
switch (loss)
{
case 1:
Console.WriteLine(" C");
break;
case 2:
Console.WriteLine(" C{0} #", Environment.NewLine);
break;
case 3:
Console.WriteLine(" C\n/#");
break;
case 4:
Console.WriteLine(" C\n/#\\");
break;
case 5:
Console.WriteLine(" C\n/#\\\n/");
break;
case 6:
Console.WriteLine(" C\n/#\\\n/ \\");
break;
}
Console.WriteLine("\n\nLives Remaining {0}.\n", maxGuess - loss);
}
}
Can be run as new HangCSharp().Run();
The index variable is being set to a random number when the random word is selected in this line.
int index = random.Next(0, 5);
Then that index is being used to store the guesses in the do..while loop. However, since index starts from a random number between 0 and 5 you see unexpected behaviour.
Set index to 0 in the line before the do..while loop and the for loop (or the alternatives suggested elsewhere) should work e.g. as so
index = 0;
int lives = 6;
do
{
// rest of the code

Changing commas within quotes

I am trying to read the data in a text file which is separated by commas. My problem, is that one of my data pieces has a comma within it. An example of what the text file looks like is:
a, b, "c, d", e, f.
I want to be able to take the comma between c and d and change it to a semicolon so that I can still use the string.Split() method.
using (StreamReader reader = new StreamReader("file.txt"))
{
string line;
while ((line = reader.ReadLine ()) != null) {
bool firstQuote = false;
for (int i = 0; i < line.Length; i++)
{
if (line [i] == '"' )
{
firstQuote = true;
}
else if (firstQuote == true)
{
if (line [i] == '"')
{
break;
}
if ((line [i] == ','))
{
line = line.Substring (0, i) + ";" + line.Substring (i + 1, (line.Length - 1) - i);
}
}
}
Console.WriteLine (line);
}
I am having a problem. Instead of producing
a, b, "c; d", e, f
it is producing
a, b, "c; d"; e; f
It is replacing all of the following commas with semicolons instead of just the comma in the quotes. Can anybody help me fix my existing code?
Basically if you find a closing " you recognize it as it was an opening quote.
Change the line:
firstQuote = true;
to
firstQuote = !firstQuote;
and it should work.
You need to reset firstquote to false after you hit the second quote.
else if (firstQuote == true) {
if (line [i] == '"') {
firstquote = false;
break;
}
Here is a simple application to get the required result
static void Main(string[] args)
{
String str = "a,b,\"c,d\",e,f,\"g,h\",i,j,k,l,\"m,n,o\"";
int firstQuoteIndex = 0;
int secodQuoteIndex = 0;
Console.WriteLine(str);
bool iteration = false;
//String manipulation
//if count is even then count/2 is the number of pairs of double quotes we are having
//so we have to traverse count/2 times.
int count = str.Count(s => s.Equals('"'));
if (count >= 2)
{
firstQuoteIndex = str.IndexOf("\"");
for (int i = 0; i < count / 2; i++)
{
if (iteration)
{
firstQuoteIndex = str.IndexOf("\"", firstQuoteIndex + 1);
}
secodQuoteIndex = str.IndexOf("\"", firstQuoteIndex + 1);
string temp = str.Substring(firstQuoteIndex + 1, secodQuoteIndex - (firstQuoteIndex + 1));
firstQuoteIndex = secodQuoteIndex + 1;
if (count / 2 > 1)
iteration = true;
string temp2= temp.Replace(',', ';');
str = str.Replace(temp, temp2);
Console.WriteLine(temp);
}
}
Console.WriteLine(str);
Console.ReadLine();
}
Please feel free to ask in case of doubt
string line = "a,b,mc,dm,e,f,mk,lm,g,h";
string result =replacestr(line, 'm', ',', ';');
public string replacestr(string line,char seperator,char oldchr,char newchr)
{
int cnt = 0;
StringBuilder b = new StringBuilder();
foreach (char chr in line)
{
if (cnt == 1 && chr == seperator)
{
b[b.ToString().LastIndexOf(oldchr)] = newchr;
b.Append(chr);
cnt = 0;
}
else
{
if (chr == seperator)
cnt = 1;
b.Append(chr);
}
}
return b.ToString();
}

Categories