if (testModetrue)
{
try
{
Console.Write("What number do you want the roll to be set to? (1-6)");
string diceString = Console.ReadLine();
int diceCheck = int.Parse(diceString);
if ((diceCheck >= minDiceValue) || (diceCheck <= maxDiceValue))
{
diceNo = int.Parse(diceString);
}
else if ((diceCheck <= minDiceValue) || (diceCheck >= maxDiceValue))
{
Console.WriteLine("Please enter a number between 1-6.");
break;
}
}
catch (Exception)
{
Console.WriteLine("An error has occured.");
return;
}
}
This code checks to see whether the answer given doesn't go past 6 or below 1, however whenever I run it, it does it anyway then it throws the out of array error, anybody help?
int diceCheck = int.Parse(diceString);
if ((diceCheck >= minDiceValue) || (diceCheck <= maxDiceValue))
{
diceNo = int.Parse(diceString);
}
This conditional should be AND rather than OR. Also, since you're parsing the string before the conditional, you don't need to do it inside it, so you should change that part to:
int diceCheck = int.Parse(diceString);
if (diceCheck > maxDiceValue && diceCheck < minDiceValue)
{
Console.Writeline("Please write a number between 1 and 6");
break;
}
Your other if statement was also kind of redundant because you already have other variable (dicecheck) with the value, so remove it.
private const int maxDiceValue = 6;
private const int minDiceValue = 1;
Console.Write("What number do you want the roll to be set to? (1-6)");
string diceString = Console.ReadLine();
int diceCheck;
if (!int.TryParse(diceString, out diceCheck) ||
diceCheck < minDiceValue ||
diceCheck > maxDiceValue) {
Console.WriteLine("Please enter a number between 1-6.");
return;
}
// add diceCheck to array here
Lets imagine the user introduce -1.
In the first condition you are validating if -1 >= 1 which is false, but you are also validating if -1 <= 6 which is true.
Instead of && (AND ALSO) you are using || (Or Else).
Since one of the condition is always true, the validating will always return true and therefore the code will run throwing an error.
Related
I came across this situation however I don't know how do I handle this exception when the user enters a number outside of the index of the string or any other datatype. In that condition I want the program to display the exception and go back to the first if statement. The code must be as basic as possible as I have just started learning programming. I know the use of 'Try Catch' (or so I think) but I can't determine how to use it here.
choice = int.Parse(Console.ReadLine());
if (arr[choice] != 'X' && arr[choice] != 'O')
{
if (player % 2 == 0)
{
arr[choice] = 'O';
player++;
}
else
{
arr[choice] = 'X';
player++;
}
}
else
{
Console.WriteLine("Sorry the row {0} is already marked with {1}", choice,arr[choice]);
Console.WriteLine("\n");
}
You can do it like this:
int choice;
bool isValidChoice = int.TryParse(Console.ReadLine(), out choice) && choice >= 0 && choice < arr.Length;
if (isValidChoice && arr[choice] != 'X' && arr[choice] != 'O') {
if (player % 2 == 0) {
arr[choice] = 'O';
player++;
} else {
arr[choice] = 'X';
player++;
}
} else if (!isValidChoice) {
Console.WriteLine("Sorry you have not entered a valid in-range integer");
} else {
Console.WriteLine("Sorry the row {0} is already marked with {1}", choice, arr[choice]);
Console.WriteLine("\n");
}
Some explanations:
int.TryParse, is effectively the equivalent of
int choice;
bool isValid = false;
try {
choice = int.Parse(Console.ReadLine());
isValid = true;
} catch {}
&& will only be evaluated only when the previous statement is correct. So in
choice >= 0 && choice < arr.Length the choice < arr.Length will only be checked if the choice >= 0 is correct
If you want to retry as long as the input is invalid. Try using the while(!isValidChoice) loop. I will not tell you how, as I think it will be a good learning experience.
I am using TryParse for the code below, but when I put 1 or 2 the program doesnt continue.
int x = -1;
bool noRecords = true;
do
{
Console.WriteLine("1.Add Data");
Console.WriteLine("2.Show Data");
Console.WriteLine("0.Exit");
//x = Convert.ToInt32(Console.ReadLine());
if (x == 1)
{
Helper.ShowAddMenu(noRecords);
}
if (x == 2)
{
Helper.ShowDataMenu();
}
} //while (x != 0);
while (!int.TryParse(Console.ReadLine(), out x) || x > 2 || x < 0);
Your while loop is wrong if you want it to continue when you enter 1 or 2. The order of operations during execution of that expression in your while loop will be:
You enter the value 1
Console.Readline() will return the string "1"
int.TryParse("1", out x) will set x to 1 and will return true
!true evaluates to false
x > 2 evaluates to false because x is 1
x < 0 evaluates to false because x is 1
therefore, your while loop is while(false || false || false)
EDIT: Given the discussion in the comments below, I believe OPs use case would be best served with a code structure more like the following. Trying to cram it all into the while clause is going to be confusing.
static void Main()
{
ShowMenu();
while (true)
{
int x;
if (!int.TryParse(Console.Readline(), out x))
ShowMenu();
else if (x == 0)
break;
else if (x == 1)
Helper.ShowAddMenu(noRecords);
else if (x == 2)
Helper.ShowDataMenu();
}
}
static void ShowMenu()
{
Console.WriteLine("1.Add Data");
Console.WriteLine("2.Show Data");
Console.WriteLine("0.Exit");
}
Change !int.TryParse to just int.TryParse. TryParse returns true on success, not false.
See here dotnetfiddle.net/6JCoPQ
I have the following C# Code
int amount_guesses = 2;
int c_answer = 4;
int u_answer = 0;
Console.WriteLine("Guessing Game");
Console.WriteLine("*Hint:The number is between 1 and 5");
Console.WriteLine("*Hint:You only get 2 guesses");
while (u_answer != c_answer || amount_guesses != 0)
{
u_answer = Convert.ToInt32(Console.ReadLine());
amount_guesses = amount_guesses-1;
if (u_answer == c_answer)
{
Console.WriteLine("Well Done that is the Correct Number");
}
else
{
Console.WriteLine("Wrong Number!Try again.You have {0} trys left", amount_guesses);
}
}
Console.WriteLine("Press any key to close");
Console.ReadLine();
But it's not jumping out of the loop when the requirements in the while statement are not met.
I also tried
while ((u_answer != c_answer) || (amount_guesses != 0))
But it's still not working, I ended changing the logic to this:
int amount_guesses = 2;
int c_answer = 4;
int u_answer = 0;
Console.WriteLine("Guessing Game");
Console.WriteLine("*Hint:The number is between 1 and 5");
Console.WriteLine("*Hint:You only get 2 guesses");
while (u_answer != c_answer && amount_guesses != 0)
{
u_answer = Convert.ToInt32(Console.ReadLine());
amount_guesses = amount_guesses-1;
if (u_answer == c_answer)
{
Console.WriteLine("Well Done that is the Correct Number");
amount_guesses = 0;
}
else
{
Console.WriteLine("Wrong Number!Try again.You have {0} trys left", amount_guesses);
}
}
Console.WriteLine("Press any key to close");
Console.ReadLine();
That works fine, but I wanted to know why my code at the top where I use || does not work?
A while loop continues as long as its condition is met. In your case, you want to continue loop as long as the player hasn't guessed the number and has guesses left. You should use an && (logical AND) condition, not an ||:
while (u_answer != c_answer && amount_guesses != 0)
{
// Here ----------------^
This is a common(ish) issue when using negation in boolean logic. OR sounds like it should be right as it matches are English way of speaking, but actually AND is what you want.
I try to always write the condition testing for equality and then negate it, so instead of:
u_answer != c_answer && amount_guesses != 0
You can write:
!(u_answer == c_answer || amount_guesses == 0)
Which is the same condition.
Take a look at De Morgams Law, also more easily remembered as
Break the line, change the sign
I'm just starting to learn C# and I'm trying to create a really simple program about knowing the DayOfWeek of a specific Date. The continue keyword in the do-while loop doesn't work for error checking.
I have tried doing another way of error checking, by including the conditions directly inside the while loop, but I'm curious why the continue doesn't work.
class Program
{
static void Main(string[] args)
{
int yearInput, monthInput, dateInput;
Console.WriteLine("We can tell you any day of any date");
bool correctInput;
//the problem starts at dateInput request (the third do while loop)
do { Console.WriteLine("\nSet a year :");
correctInput = int.TryParse(Console.ReadLine(), out yearInput);
if (!correctInput)
{
Console.WriteLine("Incorrect Input!");
}
}
while (!correctInput);
// this part is where is starts
do
{
Console.WriteLine("\nSet a month :");
correctInput = int.TryParse(Console.ReadLine(), out monthInput);
if (!correctInput || monthInput < 1 || monthInput > 12)
{
Console.WriteLine("Incorrect Input!");
}
}
while (!correctInput || monthInput < 1 || monthInput > 12);
do
{
Console.WriteLine("\nSet a date :");
correctInput = int.TryParse(Console.ReadLine(), out dateInput);
if (!correctInput || dateInput > 31 || dateInput < 1)
{
Console.WriteLine("Incorrect Input!");
}
else
{
if (dateInput > DateTime.DaysInMonth(yearInput, monthInput))
{
Console.WriteLine("The date doesn't reach that many!");
continue;
}
}
} while (!correctInput || dateInput > 31 || dateInput < 1);
DateTime day = getDayofDate(yearInput, monthInput, dateInput);
Console.WriteLine("\nIt is {0}.", day.DayOfWeek);
Console.ReadKey();
}
static public DateTime getDayofDate (int year, int month, int day)
{
return new DateTime(year, month, day);
}
}
I expect it to repeat the loop after it meets the error, but it shows ArgumentsOutOfRangeException instead.
The continue works, but still checks the loop's condition. However, the condition is false - the loop stops! To fix that, you can set correctInput to false, and also you can remove the continue - because there are no more statements after the if to execute (the computer automatically goes to the next iteration):
do
{
Console.WriteLine("\nSet a date :");
correctInput = int.TryParse(Console.ReadLine(), out dateInput);
if (!correctInput || dateInput > 31 || dateInput < 1)
{
Console.WriteLine("Incorrect Input!");
}
else
{
if (dateInput > DateTime.DaysInMonth(yearInput, monthInput))
{
Console.WriteLine("The date doesn't reach that many!");
correctInput = false; // Makes one more iteration of the loop
}
}
} while (!correctInput || dateInput > 31 || dateInput < 1);
I'm working on a random number guessing game as a c# console program. It's done with the code and working. However, there is a part that I want to make better:
I declared an instance of a Guess class I created, now how to make this part more efficient?
int counter = 0;
do
{
myGuess.UserGuess = GetUserGuess(); //read user guess
if (myGuess.Compair() == "match")
{
Console.WriteLine("\n\t Correct!You WIN !");
}
else if (myGuess.Compair() == "high")
{
if (counter < 3)
Console.WriteLine("\n\tTry a lower number,");
else
Console.WriteLine("\n\tSorry you LOSE !, The right number is " + myGuess.RndNum);
counter++;
}
else if (myGuess.Compair() == "low")
{
if (counter < 3)
Console.WriteLine("\n\tTry a higher number,");
else
Console.WriteLine("\n\tSorry you LOSE !, The right number is " + myGuess.RndNum);
counter++;
}
} while (myGuess.Compair() != "match" && counter < 4);
Thanks in advance.
What does "Compair()" function look like? It seems like that could return an integer rather than a string for a simpler function. An example of that looks like:
// just an example implementation
public int Compair() {
if (UserGuess < actualValue) return -1;
if (UserGuess > actualValue) return 1;
return 0;
}
And then your routine becomes:
int counter = 0;
bool success = false;
do
{
myGuess.UserGuess = GetUserGuess();
int compair= myGuess.Compair()
switch (compair) {
case 0:
Console.WriteLine("\n\t Correct!You WIN !");
success = true;
break;
case 1:
case -1:
if (counter < 3) Console.WriteLine("\n\tTry a {0} number,", compair == -1 ? "lower" : "higher");
break;
}
counter++;
if (counter >= 3 && !success)
Console.WriteLine("\n\tSorry you LOSE !, The right number is " + myGuess.RndNum);
} while (!success && counter < 4);
That should do it! This should be faster because it isn't using string comparisons, it might be a bit easier to read and it should have fixed a few logical issues.
Note - I made a few assumptions about the use of properties so this example might not compile out of the get but it should get you most of the way there. Best of luck!