I am new to C# and am having difficulty understanding where I am going wrong in this random number guessing game I have created. I have tried to add a random.next command in the do while loop on line 30, when I run the program it says my guess is either too high or too low, I do not understand what is going wrong. Here is the unfinished code:
static void Main(string[] args)
{
Random random = new Random();
int numberToGuess = random.Next(100) + 1;
int userGuess = 0;
string name;
Console.WriteLine("What is your name?");
name = Convert.ToString(Console.ReadLine());
Console.WriteLine("In this game you need to guess which number the computer has picked in the range of 1 to 100."
+ Environment.NewLine + "If the number you enter is too high or too low the program will display this, " +
Environment.NewLine + "try to make the least amount of guesses as possible!" + Environment.NewLine
+ "==========================================================================================================");
do
{
do
{
Console.Write("Enter your guess: ");
userGuess = Convert.ToInt32(Console.ReadLine());
if (userGuess > numberToGuess)
{
Console.WriteLine(userGuess + " is too high!");
}
else if (userGuess < numberToGuess)
{
Console.WriteLine(userGuess + " is too low!");
}
else
{
Console.WriteLine(userGuess + " SPOT ON! Congratulations.");
}
numberToGuess = random.Next(100) + 1;
} while (userGuess != numberToGuess);
Console.WriteLine("Do you want to continue?");
} while (Console.ReadLine().ToUpper() == "YES");
}
If I remove numberToGuess = random.Next(100) + 1; the code works fine but repeats the same random number.
Please Help.
Debug your application replacing
Console.Write("Enter your guess: ");
With
Console.Write("Enter your guess (" + numberToGuess + "): ");
You will see that the numberToGuess is changing every time... you should comment that line and use only the fist random number generated.
Your number of guess range is very high 1 to 100 and after every time you are generating random number again. Just reduce you size of random generator number for example
int numberToGuess = random.Next(5) + 1;
First check its working good or not then think about expanding it.
This method will return a truly random number.
Public Shared Function RandomInteger(min As Integer, max As Integer) As Integer
Dim Rand As New System.Security.Cryptography.RNGCryptoServiceProvider
Dim scale As UInteger = UInteger.MaxValue
While scale = UInteger.MaxValue
' Get four random bytes.
Dim four_bytes As Byte() = New Byte(3) {}
Rand.GetBytes(four_bytes)
' Convert that into an uint.
scale = BitConverter.ToUInt32(four_bytes, 0)
End While
' Add min to the scaled difference between max and min.
Return CInt(min + (max - min) * (scale / CDbl(UInteger.MaxValue)))
End Function
Related
I am trying to make a console based application in which the program will subtract two random numbers from a range provided by the user but when i enter the values it give me a "Random min value cannot be greater than maxvalue" error
Here is my code
static void subtract()
{
bool tryagain = true;
while (tryagain == true)
{
Console.WriteLine("Choose a range of numbers");
Console.Write("First Value: ");
int firstval = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("First value: " + firstval);
Console.WriteLine("Second Value: ");
int secondval = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Second value: " + secondval);
Console.WriteLine(firstval + secondval);
Random rnd = new Random();
int firstrndval = rnd.Next(firstval, secondval); //this line is throwing the error
int secondrndval = rnd.Next(firstval, secondval);
Console.WriteLine("What is " + firstrndval + "-" + secondrndval);
int potans;
potans = Convert.ToInt32(Console.ReadLine());
int ans = firstrndval - secondrndval;
if (ans != potans)
{
Console.WriteLine("Wrong Answer");
}
else
{
Console.WriteLine("Correct Answer");
}
Console.WriteLine("Would you like to try again Y/N");
string potbol = Console.ReadLine();
potbol = potbol.ToUpper();
if (potbol == "N")
{
tryagain = false;
}
}
}
I tried switching the values if the firstval is less than secondval but it would not work,i tried the tuple method and the three variable method but it didnt seem to work for me probably because it was in an if-else statement.I'm fairly new to C# and seem to not solve this problem.
First you must find the smaller number and the bigger number among the two:
int smaller = Math.Min(firstval, secondval);
int biggest = Math.Max(firstval, secondval);
int firstrndval = rnd.Next(smaller, biggest + 1);
int secondrndval = rnd.Next(smaller, biggest + 1);
You must put +1 on the second parameter because the second parameter is exclusive. That means, if you put rnd.Next(1,10) it will only return numbers among {1,2,3,4,5,6,7,8,9} (never 10).
You have two options
First : If the first number is greater than the second , swap them like this
if (firstval > secondval)
{
int temp = firstval;
firstval = secondval;
secondval = temp;
}
this will ensure that the firstVal will always be the greater one
Second Solution : Use the Math.Min() & Math.Max() functions like this
int firstrndval = rnd.Next(Math.Min(firstval, secondval), Math.Max(firstval, secondval));
int secondrndval = rnd.Next(Math.Min(firstval, secondval), Math.Max(firstval, secondval));
this will ensure that the minimum value from both variables will be at first whatever if it's the firstVal or the SecondVal & the same for the maxmimum value from both variables
essentially I'm making a guessing game for an assignment but as I try to output the list it comes out as
System.Collections.Generic.List`1[System.Int32]
System.Collections.Generic.List`1[System.Int32]
essentially I just need to store a users guess number and their attempt number so that once they guess the correct number it will display it as
"YOU WON, the number was ___ and here are your attempts
you chose 45
you chose 54
you chose 32
you chose ___
using System;
using System.Collections.Generic;
namespace main__4_8_2021_
{
class Program
{
public static void Main(string[] args)
{
while (true)
try
{
int NumberOfTries = 0;
Console.WriteLine("Guess a number between 1 and 100");
int number = Convert.ToInt32(Console.ReadLine());
List<int> mylist2 = new List<int>(number);
List<int> mylist = new List<int>(NumberOfTries);
int rng = new Random().Next(1, 101);
if (number == rng)
{
Console.WriteLine("Your guess was correct! The number was " + number + "!");
Console.WriteLine(mylist);
Console.WriteLine(mylist2);
break;
}
else if (number > rng)
{
NumberOfTries++;
Console.WriteLine("Your guess was too high ");
Console.WriteLine(mylist);
Console.WriteLine(mylist2);
Console.WriteLine("you now have done " + NumberOfTries + " Tries");
}
else if (number < rng)
{
NumberOfTries++;
Console.WriteLine("too low, ");
Console.WriteLine(mylist);
Console.WriteLine(mylist2);
Console.WriteLine("you now have done " + NumberOfTries + " Tries");
}
Console.Write($"Try again. ");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
(the other console.writelines of the lists are just there for debug)
You have a number of issues with your code.
First, you don't need a counter for number of attempts, a Count property on the List is enough.
Second, you need to keep that list outside of the loop so it is not recreated each time.
Try the below
using System;
using System.Collections.Generic;
namespace main__4_8_2021_
{
class Program
{
public static void Main(string[] args)
{
List<int> mylist = new List<int>();
void PrintListContents() {
Console.WriteLine("here are your attempts");
var index = 0;
foreach(var value in mylist) {
Console.WriteLine($"{index}. You chose {value}");
index++;
}
}
while (true)
try
{
Console.WriteLine("Guess a number between 1 and 100");
int number = Convert.ToInt32(Console.ReadLine());
mylist.Add(number);
int rng = new Random().Next(1, 101);
if (number == rng)
{
Console.WriteLine("Your guess was correct! The number was " + number + "!");
PrintListContents()
break;
}
else if (number > rng)
{
NumberOfTries++;
Console.WriteLine("Your guess was too high ");
PrintListContents()
Console.WriteLine("you now have done " + myList.Count + " Tries");
}
else if (number < rng)
{
NumberOfTries++;
Console.WriteLine("too low, ");
PrintListContents()
Console.WriteLine("you now have done " + myList.Count + " Tries");
}
Console.Write($"Try again. ");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
Console.WriteLine(mylist);
If value is null, only the line terminator is written. Otherwise, the
ToString method of value is called to produce its string
representation, and the resulting string is written to the standard
output stream.
SOURCE https://learn.microsoft.com/en-us/dotnet/api/system.console.writeline?view=net-5.0#System_Console_WriteLine_System_Object_
this means that you actually calling the ToString method of the list. Most of the "complex" types do not overwrite the ToString method which results in just returning the string representation of Type. In your case: List<int> which is represented as System.Collections.Generic.List`1[System.Int32]
you may also want to have a look at https://learn.microsoft.com/en-us/dotnet/api/system.object.tostring?view=net-5.0
So, today I decided to start learning C# from scratch. I've managed to make a little math problems program. The thing is, whenever the user just presses enter without entering a value (or anything which isn't a number), the program crashes. I've read something about TryParse but I just can't get it.
Here's my code (part of it):
{
Random numberGenerator = new Random();
int num01 = numberGenerator.Next(1, 20);
int num02 = numberGenerator.Next(1, 20);
Console.WriteLine("Welcome, user.");
Console.ReadKey();
Fail2:
Console.WriteLine("¿What's " + num01 + "x" + num02 + "?");
int res1 = Convert.ToInt32(Console.ReadLine());
if (res1 == num01*num02)
{
Console.WriteLine("Your answer is correct");
Console.ReadKey();
}
else
{
goto Fail;
}
Thanks in advance!
Hello & welcome to StackOverflow! I have a couple of suggestions:
Avoid using goto
Replace all your Convert.X with X.TryParse whenever it's the user who gives you the value, since you don't know what it could be
Random numberGenerator = new Random();
int num01 = numberGenerator.Next(1, 20);
int num02 = numberGenerator.Next(1, 20);
Console.WriteLine("Welcome, user.");
Console.ReadKey();
// Always use a loop instead of goto statements!
while (true)
{
Console.WriteLine("¿What's " + num01 + "x" + num02 + "?");
// Old line: int res1 = Convert.ToInt32(Console.ReadLine());
// Problem: this assumes that Console.ReadLine() returns a valid number, e.g. "3"
// but as you said, the user can trick you and put something else
if (!int.TryParse(Console.ReadLine(), out int res1))
continue; // This will rerun the loop from the top, so the user will need to re-write a response
if (res1 == num01*num02)
{
Console.WriteLine("Your answer is correct");
Console.ReadKey();
}
else
{
break; // stop the outer loop on top
}
}
Use int.TryParse like this...
int res1 = 0;
if (!int.TryParse(Console.ReadLine(), out res1))
{
//failed;
}
if (res1 == num01*num02)
...
https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netcore-3.1
I wrote a basic number guessing game from C#. It seems to return the 3rd option ("Wrong choice! Please try again.") every time no matter what var c is chosen by the user. I was trying with characters (s instead of 1 and w instead of 2 etc with c as a string) but it gave the same results. Not sure where it's going bad.
using System;
namespace Challanges
{
class Program
{
static int guess = 500;
static int low = 1;
static int high = 1000;
static bool cont = false;
static void Guess() //guesses and adjusts variables according to input.
{
int c;
Console.WriteLine("Is your number greater or less than: " + guess + Environment.NewLine + "If it is less than, press 1; if it is greater, press 2." + Environment.NewLine + "If it is your number, press 3.");
c = Convert.ToInt32(Console.Read());
if (c == 1)
{
high = 500;
guess = low + high / 2;
}
else if (c == 2)
{
low = 500;
guess = low + high / 2;
}
else if (c == 3)
{
Console.WriteLine("Congratulations!! We found your number!");
cont = true;
}
else
{
Console.WriteLine("Wrong choice! Please try again.");
Console.ReadKey();
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!" + Environment.NewLine + "Let's play a guessing game. Think of a number between 1 and 1000." + Environment.NewLine + "Type your number :)");
int x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your number is: " + x + Environment.NewLine + "Too easy?");
Console.ReadKey();
Console.WriteLine("Think of a number");
if(cont == false)
{
Guess();
} else
{
Console.ReadKey();
}
}
}
}
As mentioned in the comments before, Console.Read() returns a character code. The character code for the number 1 is 49, thus your conditions fail and the else block is executed.
What you wanted to do was use Console.ReadLine()which returns a string instead of character codes. If you cast that string into an Int32 you should be able to evaluate your conditions correctly.
Before I get down-voted for the extensive code, I feel it's necessary for a solution to present itself.
I've made alterations to the program's code from the help previously presented, but I still seem to be falling into the problem that the random number number is either not being properly compared (I've had examples where number is '5' and the user's guess is '5', but I'm still getting a comment that "You're quite far off! Try again." meaning it's falling into else if (userinputcalc > 4 | userinputcalc < 10)...
So, at this stage the issue seems to lie within the comparison of number and the userinput, leading to confusing output messages.
I'm probably missing something obvious here, despite being sure it's around the loop of comparing number and userinput but I've been looking at this code and seeing nothing.
Any help is greatly appreciated, as always.
public void GuessingGame()
{
string username; // Will be the user's chosen name for program interaction
int guessesleft = 0;// Stands for the number of guesses left (out of 3)
int spaceaway = 0; // Space from the guess and the random number, if not correct guess
int roundcount = 1; //Started at 1 for the sake of the user interface - aesthetics
int number = 0; // Current value of the random number
int userinput = 0; //User input is the guess the user makes during the guessing game
int userinputcalc = 0;// calculation of guess and random number, when added to spaceaway calculation
int answersright = 0; // Number of times the user guessed the number correctly
Random rndm = new Random(); // Initialises a new class of random, which'll be used to simulate the random number
Console.WriteLine("Welcome to Guessing Game!");
Console.WriteLine("");
Console.WriteLine("Please press any button to continue.");
Console.ReadLine();
Console.WriteLine("What's your name?");
username = (Console.ReadLine());
//If you're wondering at all, the "You must guess what it is inthree tries." is intentional, since it was showing double-spaced in the command prompt
Console.WriteLine("Well, " + username + ", I am thinking of a number from 1 to 10. You must guess what it is inthree tries.");
Console.WriteLine("");
{
do
{
Console.WriteLine("Round" + roundcount); //Displays the which round (out of 10) to the user
guessesleft = 3; //The remaining guesses left for the user
do
{
number = rndm.Next(10) + 1; // int number is set to a random number between 1 and 10
Console.WriteLine("Please enter a guess:");
userinput = int.Parse(Console.ReadLine());
guessesleft = guessesleft - 1;
if (userinput == number)
{
//Below, once you've guessed right, you will have this message displayed in the console
Console.WriteLine("You guessed " + number + " *RIGHT*!");
answersright = answersright + 1;
guessesleft = 0;// No point need to guess further on something you've guessed correctly - saves correct answer value exploit
}
else if (userinput < 1 || userinput > 10) // If user's guess is less than 1 or more than 10, then out of range. Counts as a guess.
{
Console.WriteLine("You guessed " + userinput + "! and it was incorrect!");
Console.WriteLine("This is outside of the range of numbers between 1-10 ");
}
else if (userinput != number) // while the user's guess does not equal the number
{
{
// userinputcalc = Math.Abs(number - userinput);
//Left out as I was getting abnormal run-time outputs and the math showed up wrong.
//(Example: RND No. = 5 Userinput = 5 Output: "Incorrect" "Hot")
spaceaway = (number - userinput); // Works out how far from the random no. the user's guess is.
// If user guesses 6 and random no. is 5, answer will be -1 this makes the value +ve and allows output to be shown without error
if (spaceaway < 0)
{
spaceaway = (spaceaway * -1);
userinputcalc = spaceaway;
}
else if (spaceaway > 0)
{
userinputcalc = spaceaway;
}
}
{
if (userinputcalc < 2)
{
Console.WriteLine("You guessed " + userinput + "! and it was wrong!");
Console.WriteLine("Hot");
}
else if
(userinputcalc < 3)
{
Console.WriteLine("You guessed " + userinput + "! and it was wrong!");
Console.WriteLine("Warm");
}
else if
(userinputcalc < 4)
{
Console.WriteLine("You guessed " + userinput + "! and it was wrong!");
Console.WriteLine("Cold");
}
else if (userinputcalc > 4 | userinputcalc < 10)
{
Console.WriteLine("You guessed " + userinput + "! and it was wrong!");
Console.WriteLine("You're quite far off! Try again.");
}
}
}
} while (guessesleft > 0);
Console.WriteLine("");
Console.WriteLine("The number was, "+number+"!");
Console.WriteLine("");
roundcount = roundcount + 1;
} while (roundcount < 11);
Console.WriteLine("Well, " + username + ". " + "You guessed correctly, " + answersright + " times!");
}
}
}
}
OK I think theres quite a few issues here (some are off topic but definitely worth mentioning)..
I wouldn't advise using while loops to check for specific inputs
For example:
Instead of roundCount != 11 use roundCount < 11
Then there is less chance of forever getting stuck in a loop
You should declare Random outside of your loops otherwise you run the risk of just getting the same numbers ("randomly")
You reset the number to a new number after every guess so the user doesn't have a chance to guess the right number
With all this being said, I think the Math.Abs was correct if you are trying to find the distance away from the number.. I wouldnt use less than two though as that would mean only numbers that are 1 away from the answer are "hot"
Note: Answer is based off question revision #5
Update
Doesn't seem like you were far off but you still reset the number every loop
number = rndm.Next(10) + 1; //Insert here
do
{
//Displays the which round (out of 10) to the user
Console.WriteLine("Round" + roundcount);
guessesleft = 3; //The remaining guesses left for the user
do
{
// Remove this -- number = rndm.Next(10) + 1;
I think this is what you want,please try it:
static int guessesleft;
static Random ran = new Random();
static int MagicNumber;
static string UserInput;
static void Main(string[] args)
{
ConsoleKeyInfo ci = new ConsoleKeyInfo();
do
{
guessesleft = 3;
UserInput = "";
Console.Clear();
string username;
int guesscount = 1;
Console.WriteLine("Welcome to Jackie's Guessing Game!");
Console.WriteLine("");
Console.WriteLine("Please press any button to continue.");
Console.ReadLine();
Console.WriteLine("What's your name?");
username = (Console.ReadLine());
//If you're wondering at all, the "You must guess what it is inthree tries." is intentional, since it was showing double-spaced in the command prompt
Console.WriteLine("Well, " + username + ", I am thinking of a number from 1 to 10. You must guess what it is inthree tries.");
Console.WriteLine("");
MagicNumber = ran.Next(1, 11);
do
{
Console.WriteLine("Please insert your " + guesscount++ + "º guess!");
UserInput = Console.ReadLine().Trim();
if (UserInput == MagicNumber.ToString())
break;
if (Math.Abs(Convert.ToInt32(UserInput) - MagicNumber) < 2)
Console.WriteLine("Hot!!");
else if(Math.Abs(Convert.ToInt32(UserInput) - MagicNumber) < 3)
Console.WriteLine("Warm!!");
Console.WriteLine("No luck , you have " + --guessesleft + "º guesses left!");
Console.WriteLine();
} while (guesscount < 4);
if (guesscount == 4)
Console.WriteLine("Sorry " + username + " no more tries,you lost!");
else
Console.WriteLine("Congratulations your guess with number " + UserInput + " is correct,the number was " + MagicNumber);
Console.WriteLine("Press Q to quit or Enter to Play again!");
ci = Console.ReadKey();
} while (ci.Key != ConsoleKey.Q);
}