I have a small program that changes values of char arrays. But first you need to tell the program in which array you want to change a value; and write a new value and its position into that same array position.
But when I enter the array number, the program skips the code lines allowing the entry of the new value and its position. Then the program throws a FormatException at the end.
Here's the code:
static void addLetters(char[] messageOne, char[] messageTwo)
{
char Mnumber;
char letter;
string pos;
int position;
Console.Write("- Message #: ");
Mnumber = (char)Console.Read();
if (Mnumber == '1')
{
Console.Write("Letter: ");
letter = (char)Console.Read();
Console.Write("\nPosition: ");
pos = Console.ReadLine();
position = Int32.Parse(pos);
messageOne[position - 1] = letter;
}
if (Mnumber == '2')
{
Console.Write("Letter: ");
letter = (char)Console.Read();
Console.Write("\nPosition: ");
pos = Console.ReadLine();
position = Int32.Parse(pos);
messageTwo[position - 1] = letter;
}
}
static void Main(string[] args)
{
char[] array1 = new char[50];
char[] array2 = new char[50];
for (int i = 0; i < 50; i++)
{
array1[i] = '*';
array2[i] = '*';
}
addLetters(array1, array2);
}
}
P.S. Could you please tell me how I can make this code more 'elegant'?
When reading a single character it's reccommended to use Console.ReadKey().KeyChar. I've modified your code to handle exceptions as well:
static void addLetters(char[] messageOne, char[] messageTwo)
{
char Mnumber;
char letter;
string pos;
int position;
try
{
do
{
Console.Write("- Message #: ");
Mnumber = Console.ReadKey().KeyChar;
Console.WriteLine();
}
while (Mnumber != '1' && Mnumber != '2');
Console.Write("\nLetter: ");
letter = Console.ReadKey().KeyChar;
Console.Write("\nPosition: ");
pos = Console.ReadLine();
position = Int32.Parse(pos);
if (Mnumber == '1')
messageOne[position - 1] = letter;
else
messageTwo[position - 1] = letter;
}
catch (FormatException)
{
Console.WriteLine("Invalid input format, position must be an integer");
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Position out of array bounds");
}
finally
{
Console.Read();
}
}
Try a single function for both messages, and TryParse() your string to integer conversions
static char ReadChar(string prompt)
{
// Screen Prompt
Console.Write(prompt);
// Read a Character
return Console.ReadKey(false).KeyChar;
}
static int ReadNumber(string prompt)
{
// Screen Prompt
Console.Write(prompt);
int result=-1;
// Reads a number and onverts it into an integer
int.TryParse(Console.ReadLine(), out result);
return result;
}
// Caution, this modifies the contents of `messages`
static void addLetters(params char[][] messages)
{
// Read message index (first=1, second=2, etc)
int Mnumber=ReadNumber("- Message #: ");
// Read letter
char letter=ReadChar("Letter: ");
// Read placement position
int position=ReadNumber("\nPosition: ");
// Get the right message
char[] current_message=messages[Mnumber-1];
// Assigns a letter to the message
current_message[position]=letter;
}
static void Main(string[] args)
{
int n=50; //Store the size instead of hard coding it all over your code
char[] array1=new char[n];
char[] array2=new char[n];
for (int i=0; i<n; i++)
{
array1[i]='*';
array2[i]='*';
}
addLetters(array1, array2);
}
Related
This question already has answers here:
Retrieving a random word from a string array [duplicate]
(2 answers)
Closed 2 years ago.
Good evening.
I am trying to create a hangman game in C#. It works fine when I use just one secret word (In this example, the word HASHTAG is used).
But I need to get it to work using an array of words as per those featured in the multi-line comments.
Can anyone please offer assistance?
My full code follows...
class HangManGame
{
static void Main()
{
Console.Title = ("Hangman Game");
string secretword = "HASHTAG";
/*string[] secretword = {
"MARIO", "SONIC", "THELEGENDOFZELDA", "DONKEYKONG", "LUIGI",
"PEACH", "LINK", "LARACROFT", "BOWSER", "KRATOS",
"PLAYSTATION", "NINTENDO", "TETRIS", "GRANDTHEFTAUTO",
"FINALFANTASY", "THELASTOFUS", "GHOSTOFTSUSHIMA", "HORIZONZERODAWN",
"HALO", "FORZA", "CRASHBANDICOOT", "WORLDOFWARCRAFT", "CALLOFDUTY",
"FORTNITE", "ANIMALCROSSING", "DOOM", "METALGEARSOLID", "MINECRAFT",
"RESIDENTEVIL", "PACMAN", "SPACEINVADERS", "ASTEROIDS",
"STREETFIGHTER", "MORTALKOMBAT", "SUPERMARIOKART", "POKEMON",
"BIOSHOCK", "TOMBRAIDER"
}; */
List<string> letterGuessed = new List<string>();
int live = 5;
Console.WriteLine("Welcome To Hangman!");
Console.WriteLine("Enter a letter to guess for a {0} Letter Word ", secretword.Length);
Console.WriteLine("You Have {0} Lives remaining \n", live);
Isletter(secretword, letterGuessed);
while (live > 0)
{
string input = Console.ReadLine();
if (letterGuessed.Contains(input))
{
Console.WriteLine("You Entered Letter [{0}] already", input);
Console.WriteLine("Try a Different Letter \n");
GetAlphabet(input);
continue;
}
letterGuessed.Add(input);
if (IsWord(secretword, letterGuessed))
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(secretword);
Console.WriteLine("Congratulations!");
break;
}
else if (secretword.Contains(input))
{
Console.WriteLine("Good Entry \n");
string letters = Isletter(secretword, letterGuessed);
Console.Write(letters);
Console.WriteLine("\n");
}
else
{
Console.WriteLine("That Letter Is Not In My Word");
live -= 1;
Console.WriteLine("You Have {0} Lives Remaining", live);
}
Console.WriteLine();
if (live == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Game Over \nMy Secret Word is [ {0} ]", secretword);
break;
}
}
Console.ReadKey();
}
static bool IsWord(string secretword, List<string> letterGuessed)
{
bool word = false;
for (int i = 0; i < secretword.Length; i++)
{
string c = Convert.ToString(secretword[i]);
if (letterGuessed.Contains(c))
{
word = true;
}
else
{
return word = false;
}
}
return word;
}
static string Isletter(string secretword, List<string> letterGuessed)
{
string correctletters = "";
for (int i = 0; i < secretword.Length; i++)
{
string c = Convert.ToString(secretword[i]);
if (letterGuessed.Contains(c))
{
correctletters += c;
}
else
{
correctletters += "_ ";
}
}
return correctletters;
}
static void GetAlphabet(string letters)
{
List<string> alphabet = new List<string>();
for (int i = 1; i <= 26; i++)
{
char alpha = Convert.ToChar(i + 96);
alphabet.Add(Convert.ToString(alpha));
}
int num = 49;
Console.WriteLine("Letters Left are :");
for (int i = 0; i < num; i++)
{
if (letters.Contains(letters))
{
alphabet.Remove(letters);
num -= 1;
}
Console.Write("[" + alphabet[i] + "] ");
}
Console.WriteLine();
Console.WriteLine("\n");
}
}
}
Implementation of 'Honeyboy Wilson' comment
Random random = new Random();
string secretword = secretwords[random.Next(0, secretwords.Length)];
Switch the declaration order and use the Random class to pick a value from the Array?
string[] secretWords = {
"MARIO", "SONIC", "THELEGENDOFZELDA", "DONKEYKONG", "LUIGI",
"PEACH", "LINK", "LARACROFT", "BOWSER", "KRATOS",
"PLAYSTATION", "NINTENDO", "TETRIS", "GRANDTHEFTAUTO",
"FINALFANTASY", "THELASTOFUS", "GHOSTOFTSUSHIMA", "HORIZONZERODAWN",
"HALO", "FORZA", "CRASHBANDICOOT", "WORLDOFWARCRAFT", "CALLOFDUTY",
"FORTNITE", "ANIMALCROSSING", "DOOM", "METALGEARSOLID", "MINECRAFT",
"RESIDENTEVIL", "PACMAN", "SPACEINVADERS", "ASTEROIDS",
"STREETFIGHTER", "MORTALKOMBAT", "SUPERMARIOKART", "POKEMON",
"BIOSHOCK", "TOMBRAIDER"
};
Random R = new Random();
string secretword = secretWords[R.Next(secretWords.Length)];
I want to create simple console wingman game.My error is that if i try get pos of 2 same character in word i get only one and the other is skipped.
For example Tomatoe.
Console output:
Tomatoe
_ o m a t _ _
I know i didnt use live didnt have time for that i do it layter.
class Program {
static string[] word = { "Pineapple", "Apple" , "Tomatoe" , "Pizza"};
static int wordIndex = 0;
static char[] randomWord;
static bool guessing = true;
public static void Main(string[] args)
{
int lives = 3;
Console.OutputEncoding = Encoding.UTF8;
Console.InputEncoding = Encoding.UTF8;
Random r = new Random();
wordIndex = r.Next(word.Length);
randomWord = word[wordIndex].ToLower().ToCharArray();
char[] randomWordcensored = new char[randomWord.Length];
for (int i = 0; i < randomWord.Length; i++)
{
randomWordcensored[i] = '_';
}
Console.WriteLine("Hello");
foreach (var item in randomWordcensored)
{
Console.Write(item + " ");
}
Console.WriteLine();
Console.WriteLine("Please Enter character:");
while (guessing = true)
{
int g = 0;
char userinput;
bool security = char.TryParse(Console.ReadLine() ,out userinput);
if (security == true) {
if (randomWord.Contains(userinput))
{ //help needed
g = (word[wordIndex].ToString().IndexOf(userinput) == -1 ? 0 : word[wordIndex].ToString().IndexOf(userinput));
randomWordcensored[g] = userinput;
Console.WriteLine("Good :) " + g);
foreach (var item in randomWordcensored)
{
Console.Write(item + " ");
}
}
else
{
lives--;
Console.WriteLine("Wrong!\n-Lives:" + lives);
}
}
else
{
Console.WriteLine("Enter only one charracter!");
}
}
}
}
You'll want to handle user input that might be different casing and such. Because of that it's easiest to just visit every character in the random word just once.
Here's a REPL that I made to solve this:
using System;
using System.Collections.Generic;
class MainClass {
public static void Main (string[] args) {
var word = "Tomato";
var input = "t";
var letter = input.ToLower()[0];
var indices = new List<int>();
for(var i = 0; i < word.Length; i++)
if (word.ToLower()[i] == letter)
indices.Add(i);
Console.WriteLine($"Secret word: {word}");
Console.WriteLine($"User guess: {input}");
Console.WriteLine($"Found at {String.Join(", ", indices)}");
}
}
and its output:
Mono C# compiler version 4.0.4.0
Secret word: Tomato
User guess: t
Found at 0, 4
Print first repeating character in the string given using C#. When running this getting error message.
Cannot implicitly convert type 'bool' to 'char'
public class Program {
public static void Main (string[] args) {
string str = "fafaffaa";
char[] ArrChar = str.ToCharArray ();
Console.WriteLine ("First Repeating char :", MatChar (ArrChar));
}
public static char MatChar (char[] input) {
HashSet<char> HasChar = new HashSet<char> ();
for (int i = 0; i < input.Length; i++) {
char c = input[i];
if (HasChar.Contains (c)) return c;
else return HasChar.Add (c);
}
return '\0';
}
}
Do not return in the else case. Also, you forgot the placeholder in your format string
public static void Main(string[] args)
{
string str = "fafaffaa";
char[] ArrChar = str.ToCharArray();
Console.WriteLine("First Repeating char : {0}", MatChar(ArrChar));
}
public static char MatChar(char[] input)
{
HashSet<char> HasChar = new HashSet<char>();
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (HasChar.Contains(c))
return c;
else
HasChar.Add(c);
}
return '\0';
}
You have a return on the else condition. I think your intention is that you just want to add to the HashSet.
if (HasChar.Contains(c)) return c; else HasChar.Add(c);
Getting this error because HasChar.Add() return bool. It return true if element added else false. So only getting this error, So use List instead of HashSet.
Can rewrite following
public class Program
{
public static void Main(string[] args)
{
string str = "faffaa";
char[] ArrChar = str.ToCharArray();
MatChar(ArrChar);
Console.Read();
}
public static void MatChar(char[] input)
{
List<char> HasChar = new List<char>();
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (HasChar.Contains(c))
{
Console.WriteLine("First repeating character: {0}", c);
break;
}
else
HasChar.Add(c);
}
}
}
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("1. SHC ");
int UserInput1 = Console.Read();
if (UserInput1 == 1)
{
Console.WriteLine("Mass (kg): ");
int shcmass = Console.Read();
Console.WriteLine("Specific Heat Capactiy (J/Kg/°C): ");
int shcshc = Console.Read();
Console.WriteLine("Temperature Difference (△Ø): ");
int shctemp = Console.Read();
int shcfinal = shcmass * shcshc * shctemp;
Console.WriteLine("Energy: " + shcfinal);
}
This is the code I am using within a small console application. I don't know if I am missing something but every time I run it, the first bit works where it says "1. SHC" and gives time for the user input. But once entered the console application dies and I cannot figure out why.
There's nothing stopping the console application to close, add a Console.ReadLine() at the end of your mainloop. I'd recommend using ReadLine() over reads for other input as well, but it would depend on your needs. If you see from the "Remarks" section of the Console.Read documentation it's preferable to use ReadLine()
e.g.
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("1. SHC ");
int UserInput1 = int.Parse(Console.ReadLine());
if (UserInput1 == 1)
{
Console.WriteLine("Mass (kg): ");
int shcmass = int.Parse(Console.ReadLine());
Console.WriteLine("Specific Heat Capactiy (J/Kg/°C): ");
int shcshc = int.Parse(Console.ReadLine());
Console.WriteLine("Temperature Difference (△Ø): ");
int shctemp = int.Parse(Console.ReadLine());
int shcfinal = shcmass * shcshc * shctemp;
Console.WriteLine("Energy: " + shcfinal);
}
Console.ReadLine();
}
Console.Read() returns
The next character from the input stream, or negative one (-1) if
there are currently no more characters to be read.
https://msdn.microsoft.com/en-us/library/system.console.read(v=vs.110).aspx
You will need
ch = Convert.ToChar(x);
Excerpt:
class Sample
{
public static void Main()
{
string m1 = "\nType a string of text then press Enter. " +
"Type '+' anywhere in the text to quit:\n";
string m2 = "Character '{0}' is hexadecimal 0x{1:x4}.";
string m3 = "Character is hexadecimal 0x{0:x4}.";
char ch;
int x;
//
Console.WriteLine(m1);
do
{
x = Console.Read();
try
{
ch = Convert.ToChar(x);
if (Char.IsWhiteSpace(ch))
{
Console.WriteLine(m3, x);
if (ch == 0x0a)
Console.WriteLine(m1);
}
else
Console.WriteLine(m2, ch, x);
}
catch (OverflowException e)
{
Console.WriteLine("{0} Value read = {1}.", e.Message, x);
ch = Char.MinValue;
Console.WriteLine(m1);
}
} while (ch != '+');
}
}
I've had similar issues before. When using Console.Read() after Console.WriteLine() you'll end up reading '\r' which is what causes the crash I believe. Try using Console.ReadKey() instead.
In my hangman game, I am attempting to prompt the user to enter the number of "lives" (or guesses) the player should be given. After I type a number at the prompt, the following error message is displayed:
Cannot implicitly convert type 'int' to 'string'
The following line causes the error:
lives = Console.ReadLine();
The lives field is an integer. How can I correctly assign a user-entered value to an integer field?
Here is my complete code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
namespace ConsoleApplication6
{
class Hangman
{
//guesses
public static int lives = 5;
//Words for the game
static string[] wordBank = { "study", "cat", "dress", "shoes", "lipstick" };
// Create new ArrayList and initialize with words from array wordBank
static ArrayList wordList = new ArrayList(wordBank);
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Title = "C# Hangman";
Console.WriteLine("Hang man!");
//Gamemenu
string response = "";
do
{
Console.Write("Enter Command (1. Add Words, 2. List Words , 3. Play , 4. Exit) Pick 1-4: ");
response = Console.ReadLine();
switch (response)
{
case "1": AddWord(); break;
case "2": ListWords(); break;
case "3": Play(); break;
case "4": break;
}
} while (response != "4");
}
//add words to list
static void AddWord()
{
Console.Write("Enter the word to add: ");
String temp = Console.ReadLine();
wordList.Add(temp);
Console.WriteLine("{0} was added to the dictionary!", temp);
}
//Display words
static void ListWords()
{
foreach (Object obj in wordList)
Console.WriteLine("{0}", obj);
Console.WriteLine();
}
//How many guesses
static void AskLives()
{
try
{
Console.WriteLine("please enter number of lives?");
//This line gives me the error
lives = Console.ReadLine();
}
catch
{
// if user does not enter a number ask it again
AskLives();
}
}
//Gameplay
static void Play()
{
Random random = new Random((int)DateTime.Now.Ticks);
string wordToGuess = wordList[random.Next(0, wordList.Count)].ToString();
string wordToGuessUppercase = wordToGuess.ToUpper();
StringBuilder displayToPlayer = new StringBuilder(wordToGuess.Length);
for (int i = 0; i < wordToGuess.Length; i++)
displayToPlayer.Append('-');
List<char> correctGuesses = new List<char>();
List<char> incorrectGuesses = new List<char>();
bool won = false;
int lettersRevealed = 0;
string input;
char guess;
AskLives();
while (!won && lives > 0)
{
Console.WriteLine("Current word: " + displayToPlayer);
Console.Write("Guess a letter: ");
input = Console.ReadLine().ToUpper();
guess = input[0];
if (correctGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was correct!", guess);
continue;
}
else if (incorrectGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was wrong!", guess);
continue;
}
if (wordToGuessUppercase.Contains(guess))
{
correctGuesses.Add(guess);
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuessUppercase[i] == guess)
{
displayToPlayer[i] = wordToGuess[i];
lettersRevealed++;
}
}
if (lettersRevealed == wordToGuess.Length)
won = true;
}
else
{
incorrectGuesses.Add(guess);
Console.WriteLine("Nope, there's no '{0}' in it!", guess);
lives--;
}
Console.WriteLine(displayToPlayer.ToString());
}
if (won)
Console.WriteLine("You won!");
else
Console.WriteLine("You lost! It was '{0}'", wordToGuess);
Console.Write("Press ENTER to exit...");
Console.ReadLine();
}
}
}
Your lives field is an integer, but Console.ReadLine returns a string.
You can use Int32.Parse(Console.ReadLine()) to parse the input into an integer. Note that an exception will be thrown if the text entered by the user cannot be interpreted as an integer.
Your catch block will work here and re-prompt. It would be more appropriate to use the Int32.TryParse method:
int tmpLives;
if (Int32.TryParse(Console.ReadLine(), out tmpLives))
{
lives = tmpLives;
}
else
{
AskLives();
}
You want to do something along the lines of:
string livesString = Console.ReadLine();
lives = Convert.ToInt32(livesString);
I'm guessing Console.ReadLine() gives you a string. This will not play ball with your integer lives. You could try this:
lives = Int.Parse(Console.ReadLine())