I'm working on a C# assignment and am pretty much done, except I cannot figure out how to replay the loop based on the user answering "yes" or "no." If they answer yes I want the loop to replay, if they answer no, it will leave a nice goodbye message.
Here's my code (deleted my commenting for simplicity):
Random randomNumber = new Random();
int count = 0;
int actualNumber = randomNumber.Next(1, 50);
int userGuess = 0;
bool correct = false;
Console.WriteLine("In this program you will be prompted to guess a number between 1 and 50 \n\n" +
"I'll help by saying if your guess is higher/lower than the actual number\n\n\n\n" +
"I'm thinking of a number between 1 and 50, please enter your guess.\n\n");
while (!correct)
{
count++;
Console.Write("Guess: ");
string input = Console.ReadLine();
if (!int.TryParse(input, out userGuess))
{
Console.WriteLine("That's not a number between 1 and 50, please try again.");
continue;
}
if (userGuess < actualNumber)
{
Console.WriteLine("Sorry, the number is higher than that, keep guessing!");
}
else if (userGuess > actualNumber)
{
Console.WriteLine("Sorry, the number is lower than that, keep guessing!.");
}
else
{
correct = true;
Console.WriteLine("{0} is the right number! It took you {1} times to guess", userGuess, count);
}
}
I'm having trouble figuring out if I should use another while statement or an if/else or what and where to use it. I've searched here and found similar questions for different languages, but nothing for C#. I would appreciate any help. Thanks!
You can place your code inside do-while loop. And it will ask from user if he or she wants to replay? And if user enters Yes, then the game will start again.
Random randomNumber = new Random();
do
{
int actualNumber = randomNumber.Next(1, 50);
int count = 0;
int userGuess = 0;
bool correct = false;
Console.Clear();
Console.WriteLine("In this program you will be prompted to guess a number between 1 and 50 \n\n" +
"I'll help by saying if your guess is higher/lower than the actual number\n\n\n\n" +
"I'm thinking of a number between 1 and 50, please enter your guess.\n\n");
while (!correct)
{
// ...your code
}
Console.WriteLine("Do you want to replay?");
} while (Console.ReadLine().ToUpper() == "YES");
P.S: Initilize Random outside the loop as example in above, otherwise it will generate same number.
Related
I have created a console application where the user has 5 tries to guess number between 1 and 100. After 5 guesses the game ends, but I don’t know how to introduce at the 5th wrong intent something like “you have achieved maximum of guesses! The answer was number (X). I have tried different ways ,but is not working. This is my program
using System;
namespace Guessing_Game_4
{
class Program
{
static void Main(string[] args)
{
var number = new Random().Next(1, 100);
Console.WriteLine("Try and guess any number between 1-100. You have 5 guesses Max!");
for (var i = 0; i < 5; i++)
{
int guess = Convert.ToInt32(Console.ReadLine());
if (guess == number)
{
Console.WriteLine("You got it!");
break;
}
else
{
Console.WriteLine(guess + " is not correct! Try again!");
}
}
}
}
}
Here some Sample code
This might help
for( i=10;i>0 ; i--) {
System.out.println(" === you have " + i +" Guesses left ===");
int guess = scanner.nextInt();
if (random_number < guess) System.out.println("Smaller than guess " + guess);
if (random_number > guess) System.out.println("Greater than guess " + guess);
if (random_number == guess)
{
result = true;
break;
}
}
if (result)
{
System.out.println("You WON in "+(10-i) +" tries ");
System.out.println("******* CONGRATULATIONS **************************************");
System.out.println("*********************** YOU WON **********************");
}
else
{
System.out.println("The random number was "+random_number);
System.out.println("************************** OPPS You loose **************************************** ");
System.out.println("You are near it TRY Next time ************ GOOD LUCK ");
System.out.println("You are near it TRY Nexttime***********NEXTTIME********");
}
}
If that's all your program does, you can do the following trick. Print your message after the for loop, but now the problem is that you get the message in all cases. The trick is to return from the Main (instead of breaking the loop) on a correct guess:
Console.WriteLine("You got it!");
return;
If you've some other code to execute that returning from Main won't be a good solution, you can do the following:
Create a variable before the for loop. Let's call it isCorrectAnswer and set it to false in the beginning.
At the point where he answers correctly, set isCorrectAnswer to true before breaking the loop.
After the loop, check for that variable:
if (!isCorrectAnswer)
{
Console.WriteLine($"you have achieved maximum of guesses! The answer was number {number}.");
}
You have to have an int outside of your loop like this : int wrongAnswersCount = 0;
When the user enter a wrong number you
should add one unit to your variable wrongAnswersCount++;
In the start of the loop, you should check if the user reached the maximum amount of gueses or not, if yes break the loop and say the answer.
Your code will be something like this :
using System;
namespace Guessing_Game_4
{
class Program
{
static void Main(string[] args)
{
var number = new Random().Next(1, 100);
Console.WriteLine("Try and guess any number between 1-100. You have 5 guesses Max!");
int wrongAnswersCount = 0;
for (var i = 0; i < 5; i++)
{
if(wrongAnswersCount == 5)
{
Console.WriteLine($"you have achieved maximum of guesses! The answer was number {number}");
break;
}
int guess = Convert.ToInt32(Console.ReadLine());
if (guess == number)
{
Console.WriteLine("You got it!");
break;
}
else
{
Console.WriteLine(guess + " is not correct! Try again!");
wrongAnswersCount++;
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
var number = new Random().Next(1, 100);
Console.WriteLine("Try and guess any number between 1-100. You have 5 guesses Max!");
for (var i = 0; i < 5; i++)
{
int guess = Convert.ToInt32(Console.ReadLine());
if (guess == number && i!=5)
{
Console.WriteLine("You got it!");
break;
}
else
{
Console.WriteLine(guess + " is not correct! Try again!");
}
}
Console.WriteLine(" the maximam guse");
}
}
//Try this one
Is there a way to ignore a line/block of code if the condition is met?
I'm doing a C# .NET tutorial, and the application is a number guessing game.
I added a hint option if the user enters a wrong number (else if part):
// While guess is not correct
while (guess != correctNumber)
{
//Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Please use an actual number");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Check if guess is close to correct number
if(guess == correctNumber + 2 || guess == correctNumber - 2)
{
// Tell the user that he is close
PrintColorMessage(ConsoleColor.DarkCyan, "You are close!!");
}
// Match guess to correct number
else if (guess != correctNumber)
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Wrong number, please try again");
AskForAHint(correctNumber);
}
}
// Print success message
PrintColorMessage(ConsoleColor.Yellow, "You are CORRECT!");
Basically I am asking a user if he wants a hint, and if he writes Y, the hint will be displayed. However, is there an option to display this question only once since this if statement is included in a while loop?
It would be annoying if "Do you want a hint?" question keeps displaying even if the user says Y.
My AskForAHint function:
static void AskForAHint(int num)
{
// Ask user if he wants a hint
Console.WriteLine("Do you want a hint? [Y/N]");
// Take his answer
string ans = Console.ReadLine().ToUpper();
// If the user wants a hint
if (ans == "Y")
{
// First hint number
int beginning = (num - num % 10);
// Second hint number
int finish = beginning + 10;
// Give user a hint
Console.WriteLine("The correct number is somewhere betweer {0} and {1}", beginning, finish);
}
else if (ans == "N")
{
return;
}
}
Thanks
Another way to do it would be to make the number of hints configurable (allowing the caller to specify how many hints they want to let the user ask for), and then keep track of the number of hints given in the method itself.
This would require a slight change to the AskForAHint method, however, since we don't know if the user answered "Y" or "N" to the hint question. Since AskForHint has no return value, we could have it return a bool that indicates how the user responded to the question:
static bool AskForAHint(int num)
{
var answer = GetUserInput("Do you want a hint? [Y/N]: ", ConsoleColor.Yellow);
if (!answer.StartsWith("Y", StringComparison.OrdinalIgnoreCase))
{
return false;
}
var beginning = num - num % 10;
var finish = beginning + 10;
Console.WriteLine($"The correct number is somewhere between {beginning} and {finish}");
return true;
}
Now we can keep track of how many hints the user has received by incrementing a counter in our "Game" method:
// Only ask for a hint if they have any hints (and guesses) remaining
if (hintCount < maxHints && guessCount < maxGuesses)
{
// If they asked for a hint, increase the hint count
if (AskForAHint(correctNumber)) hintCount++;
// If they didn't want a hint, max out hint count so we don't ask again
else hintCount = maxHints;
}
To test out the sample code above, I used this method below, which also allows us to configure how many total guesses the user has, what the min and max values of the range should be, and if they should be given a "directional hint", like "too high!" or "too low!":
private static readonly Random Random = new Random();
private static void PlayGuessingGame(int maxHints = 1, int maxGuesses = 10,
int rangeMin = 1, int rangeMax = 100, bool giveDirectionalHint = true)
{
if (rangeMax < rangeMin) rangeMax = rangeMin;
var correctNumber = Random.Next(rangeMin, rangeMax + 1);
var guessCount = 0;
var hintCount = 0;
WriteMessage("Welcome to the guessing game!", ConsoleColor.White);
WriteMessage("-----------------------------\n", ConsoleColor.White);
WriteMessage($"I'm thinking of a number from {rangeMin} to {rangeMax}. ", ConsoleColor.Green);
WriteMessage("Let's see how many guesses it takes you to guess it!\n", ConsoleColor.Green);
do
{
WriteMessage($"(You have {maxGuesses - guessCount} guesses left)");
var input = GetUserInput("Enter the number I'm thinking of: ", ConsoleColor.White);
int guess;
if (!int.TryParse(input, out guess))
{
WriteMessage("Please enter a whole number", ConsoleColor.Red);
continue;
}
// Only increment guesses if they entered an actual number
guessCount++;
if (guess == correctNumber) break;
if (Math.Abs(guess - correctNumber) == 2)
{
WriteMessage("You are close!!", ConsoleColor.DarkCyan);
}
if (giveDirectionalHint)
{
WriteMessage("Wrong number - too " + (guess < correctNumber ? "low!" : "high!"),
ConsoleColor.Red);
}
else
{
WriteMessage("Wrong number, please try again", ConsoleColor.Red);
}
// Only ask for a hint if they have any hints (and guesses) remaining
if (hintCount < maxHints && guessCount < maxGuesses)
{
// If they asked for a hint, increase the hint count
if (AskForAHint(correctNumber)) hintCount++;
// If they didn't want a hint, max out hint count so we don't ask again
else hintCount = maxHints;
}
} while (guessCount < maxGuesses);
WriteMessage("You are CORRECT!", ConsoleColor.Yellow);
GetKeyFromUser("\nDone! Press any key to exit...");
}
This uses the helper functions:
public static void WriteMessage(string message, ConsoleColor color = ConsoleColor.Gray)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
private static string GetUserInput(string prompt, ConsoleColor color = ConsoleColor.Gray)
{
Console.ForegroundColor = color;
Console.Write(prompt);
Console.ResetColor();
return Console.ReadLine();
}
Output
You can see in the output below, I was only given a single hint. However that, combined with the directional hints, made the game easy to win:
I think you can do an "if" with a counter.
Try It
Int cont = 0; //global
// While guess is not correct
while (guess != correctNumber)
{
//Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Please use an actual number");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Check if guess is close to correct number
if(guess == correctNumber + 2 || guess == correctNumber - 2)
{
// Tell the user that he is close
PrintColorMessage(ConsoleColor.DarkCyan, "You are close!!");
}
// Match guess to correct number
else if (guess != correctNumber)
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Wrong number, please try again");
if(cont == 0){
AskForAHint(correctNumber);
}
}
}
// Print success message
PrintColorMessage(ConsoleColor.Yellow, "You are CORRECT!");
And in the function add
static void AskForAHint(int num)
{
// Ask user if he wants a hint
Console.WriteLine("Do you want a hint? [Y/N]");
// Take his answer
string ans = Console.ReadLine().ToUpper();
// If the user wants a hint
if (ans == "Y")
{
cont = 1;
// First hint number
int beginning = (num - num % 10);
// Second hint number
int finish = beginning + 10;
// Give user a hint
Console.WriteLine("The correct number is somewhere betweer {0} and {1}", beginning, finish);
}
else if (ans == "N")
{
return;
}
}
Use a Member Variable Boolean, its similar to how you can avoid recursive calls.
private bool alreadyHinted = false;
static void AskForAHint(int num)
{
if (alreadyHinted) return;
alreadyHinted = true;
At some point you will need to set alreadyHinted back to false;
So, I'm building this little guessing game and I recently added a try/catch to stop the console from crashing if the user inputted a wrong character (besides numbers of course). Right now it works well but it restarts the entire game, I've tried to just have the catch re-run the script starting at the "for" loop, but it breaks and the random number originally generated doesn't match.
public static void StartGame()
{
Console.Clear();
Random ran = new Random();
decimal returnValue = (ran.Next(1, 100));
Console.WriteLine("Welcome to my guessing game. I'm thinking of a number between 1 and 100, can you guess it?");
Console.WriteLine("Hint: 'Way too off' means you're greater than 25 from the answer!");
try
{
for (int guessnumber = 1; guessnumber < 6; guessnumber++)
{
var Guess = Convert.ToInt32(Console.ReadLine());
//The Guess variable is simply whatever the user inputs, which is read and used by the for loop each time it is inputed.
if (Guess == returnValue)
{
Console.WriteLine("Well done!");
Console.ReadKey();
Game.NewGame();
}
else if (Guess < returnValue)
{
Console.WriteLine("Guess higher!");
}
else if (Guess > returnValue)
{
Console.WriteLine("Guess lower!");
}
if (guessnumber == 5)
{
Console.WriteLine($"The correct answer was {returnValue}");
Console.ReadKey();
Game.NewGame();
//This if statement activates when the "guessnumber" counter has reached 5, in which case it will tell the user the correct answer, and end with a return statement.
}
//result is the absolute value of
decimal result = Math.Abs(returnValue - Guess);
if (result > 25)
Console.WriteLine("Way too off!");
if (result < 5)
{
Console.WriteLine("Very close!!");
}
if (result < 2)
{
Console.WriteLine("RED HOT!!!");
}
}
}
catch (System.FormatException)
{
Console.WriteLine("Incorrect character inputted, restarting game. . .");
System.Threading.Thread.Sleep(2000);
StartGame();
}
}
public static void NewGame()
{
Console.Clear();
string input = " ";
Console.WriteLine("Game over, would you like to play again? Y/N");
input = Console.ReadLine();
input = input.ToUpper();
if (input == "Y")
{
Console.WriteLine("Ok! Re-Initializing game...");
StartGame();
}
else
{
System.Environment.Exit(0);
}
}
}
}
As another answer stated, you can just move your try/catch inside the for loop, so the loop continues.
But you really shouldn't be relying on exception handing for something that isn't exceptional, like parsing user input.
Instead, we can use the int.TryParse method to try to parse a string to an int. The nice thing about this method is that it returns true if the parse was successful, and it sets an out parameter to the parsed value.
We can also put it in it's own method that takes in a string to be used to prompt the user, which makes the code more reusable:
public static int GetIntFromUser(string prompt)
{
int result;
bool askedOnce = false;
do
{
if (askedOnce) Console.WriteLine("Invalid input, please try again.");
Console.Write(prompt);
askedOnce = true;
} while (!int.TryParse(Console.ReadLine(), out result));
return result;
}
Now our main code is greatly simplified (also notice that the Random instance should be a class field, not created on every call to StartGame, and notice that the upper bound specified in the call to ran.Next is exclusive, so if you want to include 100 as a possible answer, make the max value 101):
private static Random ran = new Random();
public static void StartGame()
{
Console.Clear();
int randomNumber = ran.Next(1, 101);
Console.WriteLine("Welcome to my guessing game");
Console.WriteLine("I'm thinking of a number between 1 and 100, can you guess it?");
for (int guessCount = 1; guessCount < 6; guessCount++)
{
var guess = GetIntFromUser($"Guess a number (try #{guessCount}): ");
if (guess == randomNumber)
{
Console.WriteLine("Well done!");
Console.ReadKey();
Game.NewGame();
}
else if (guessCount == 5)
{
Console.WriteLine("That was your last guess.");
Console.WriteLine($"The correct answer was: {randomNumber}.");
Console.ReadKey();
Game.NewGame();
}
else
{
decimal result = Math.Abs(randomNumber - guess);
if (result > 25) Console.Write("You're way off! ");
else if (result < 5) Console.Write("Very close!! ");
else if (result < 2) Console.WriteLine("You're RED HOT!!! ");
Console.WriteLine(guess < randomNumber ? "Guess higher!" : "Guess lower!");
}
}
}
Move the Try Catch handling inside for loop. What this does is, that exceptions are handled during each guess iteration.
What you had originally was exception handling for all iterations.
Also, Dont call the StartGame Function again in your catch block. You want to allow 6 (per the for loop) Guesses and not Infinite.
Ex:
for (int guessnumber = 1; guessnumber < 6; guessnumber++)
{
try
{
}
catch (System.FormatException)
{
}
}
The simple answer is as follows:
You don't control application flow with exception handling. Catching exceptions are for exceptional circumstances, a user getting input wrong isn't exceptional... it's guaranteed.
Never ever ever ever ever (+1000) use Convert.... or int.Parse to take user input... Users make mistakes all the time, use the TryParse type methods instead, they return a bool to say if the data was successfully parsed so you can then deal with it.
Eg
var success = int.TryParse(Console.ReadLine(), out var guess);
However, you can take it one step further, and add a loop (add pepper and salt to taste)
int guess = 0;
while(!int.TryParse(Console.ReadLine(), out guess))
Console.WriteLine("Omg you had one job, just enter a number");
Additional Resources
Int32.TryParse Method
Converts the string representation of a number to its 32-bit signed
integer equivalent. A return value indicates whether the operation
succeeded.
I am making a small lottery game. Everything works fine but I can't get the message I want to be displayed if the user doesn't guess the correct number to only appear once. I don't know how to get it to appear only once and I know why it appears multiple times.
static void Main(string[] args)
{
int[] userGuessNums = new int[10];
Console.WriteLine("Input 10 numbers between 1-50.");
for (int i = 0; i < userGuessNums.Length; i++)
{
try
{
Console.Write("Number " + (i + 1) + ": ");
string numbers = Console.ReadLine();
int userNumbers = Convert.ToInt32(numbers);
userGuessNums[i] = userNumbers;
}
catch
{
Console.WriteLine("Invalid input");
}
}
Console.Clear();
Random randomer = new Random();
int randomNumber = randomer.Next(1, 51);
Console.WriteLine("The numbers you have chosen:");
foreach (int element in userGuessNums)
{
Console.Write(element + " ");
}
Console.WriteLine();
Console.WriteLine("Press 'Enter' to see if you have won.");
Console.ReadLine();
Console.WriteLine("The winning number is: " + randomNumber);
for (int i = 0; i < userGuessNums.Length; i++)
{
if (userGuessNums[i] == randomNumber)
Console.WriteLine("Congratulations! You won!");
else if (userGuessNums[i] != randomNumber)
{
Console.WriteLine("Sorry, you lose.");
}
}
}
You can check to see if the random number is in the array input by the user.
Import Linq at the top of your code
using System.Linq;
And after Console.WriteLine("The winning number is: " + randomNumber); replace the for-loop with
if (userGuessNums.Contains(randomNumber))
{
Console.WriteLine("Congratulations! You won!");
}
else
{
Console.WriteLine("Sorry, you lose.");
}
Modify your last for loop like so. Loop through your array and find a winning number then set your win prompt outside the loop.
Why does this work? Let's break it down. Mainly I'm separating the prompt for the win from the loop; this is going to stop it from continually displaying, which is what you want. However, we still need to isolate the element within the array that is an acceptable condition. By setting our userWonNum outside of the for loop with a value of -1 (An impossible win condition), it protects from an accidental win. Then we loop through our array and find a winning number and assign it to that variable. Once the loop is completed, then it will move to the next block and check if we had one.
Exciting tip on this. If you loop through with more than one winning number, it will re-assign multiple times if you implement more than one winning number, but for now, it will work.
int userWonNumber = -1;
for (int i = 0; i < userGuessNums.Length; i++)
{
if (userGuessNums[i] == randomNumber)
{
userWonNumber = randomNumber;
}
}
if (userWonNumber == randomNumber)
{
Console.WriteLine("Congrats, you won!");
}
else
{
Console.WriteLine("Sorry you lost!");
}
I'm making a game that gives user 3 guesses and if the user guesses the right number then they will win a car. I also want the user to only have 3 attempts.
static void Main(string[] args)
{
double numberToGuess = 3595.96;
double userGuess = 0;
while (userGuess != numberToGuess)
{
Console.Write("Enter your price guess: ");
userGuess = Convert.ToDouble(Console.ReadLine());
if (userGuess > numberToGuess)
{
Console.WriteLine("£{0} is too high!", userGuess);
}
else if (userGuess < numberToGuess)
{
Console.WriteLine("£{0} is too low!", userGuess);
}
else
{
Console.WriteLine("£{0} is right! Congratulations.", userGuess);
}
} Console.ReadKey();
}
I love school assignments :)
You should create a new variable like int attempts = 0 and increase it at the end of the while loop.
If the attempts greater than 2 you should break the loop.
example:
int attempts = 0;
while (userGuess != numberToGuess)
{
}
attempts++;
if (attempts > 2)
{
Console.WriteLine("Too bad, you didn't make it within three guesses.");
break;
}
} Console.ReadKey();
Clearly, you need a counter to measure how many attempts they've made. What should the type and name of that counter be? The initial value?
Then you need logic that tests that counter against the value 3.
You know how to do that test, right?
And when the test indicates the user has reached 3 guesses, it should exit.
You know how to exit, right?
So whats the problem?
int guessCount = 0;
do
{
// guess logic
...
else
{
// guess is correct
break;
}
}while( ++guessCount < 3 )