C# guessing game only one guess - c#

i´m stuck with my guessing game where i should only have one chance to guess and then get a "the end" line. I have tried to make a break and breakLoop commands but i´t didn´t work and i have no idé how to fick it... Can someone please help me?
here is my code, i know that it´s not optimal and it´s because i´m still learning C#.
Console.WriteLine("gissa talet\nDu ska nu gissa ett tal mellan 1 ocn 100, så
varsågod..\nskriv in ett tal");
var str = Console.ReadLine();
int guess = Convert.ToInt32(str);
//gonna make it random between 1-100
Random rd = new Random();
int rand_num = rd.Next(1, 10);
{
//when i guess right
if (guess == rand_num)
{
Console.WriteLine("Ditt Tal är rätt. grattis!");
}
//when it´s to small guess
else if (guess < rand_num)
{
Console.WriteLine("Ditt tal är för litet. gissa på ett större tal");
}
//when i guess to big
else if (guess > rand_num)
{
Console.WriteLine("Ditt tal är för stort. gissa på ett mindre tal");
}
// when i was close to the answer
else if (Math.Abs(guess - rand_num) <= 3)
{
Console.WriteLine("Du är dock nära och det bränns");
}
// when i guess a number thats over the number i chould guess
else (guess > 10)
{
Console.WriteLine("Du måste skriva in ett tal mellan 1 och 100!");
}
}

Edit:
As you indeed only want one guess to be allowed, there is no loop needed and your code should work fine (apart form an if missing after the last else statement). To have a "game ended" notice at the end, just add
Console.WriteLine("Game ended.");
at the end of your code.
Also, there is one pair of curled brackets that is not needed in your code. The opening one after int rand_num = rd.Next(1, 10); and the closing one at the very end of the code.
And here remains the original answer:
At first, you want a loop around parts of your code to repeat as long as the answer was not correct or there are no more tries left (in case tries are limited):
const int tries = 10; // Give the player 10 tries to guess correctly.
for (int i = 0; i < tries; i++)
{
if (guessedCorrectly)
{
break;
}
}
Second, you want to define the random number before starting the loop and you want to query new guesses from the player inside the loop:
//Set random number.
//Define Loop.
{
//Get new guess from player.
//Check if guess was correct.
//Decide weather the loop must continue or ended.
}
//Display some result.
Third, you need to change the order of your if else statements. In your code, the statement inside the if (Math.Abs(guess - rand_num) <= 3) guard can never be executed, because you check for guess < rand_num and guess > rand_num before. And since you use else if, the following conditions will never be evaluated if the ones before were true. When using if else statements, alsways check for the more specific cases before checking for the more broad cases. But in your case you probably would want to just remove the else, so both conditions (and both texts) can be executed.

Related

errors using default for switch statement c#

im trying to use default at the end of my switch statement and i keep getting errors! im getting frustrated please help
im very new to programming and its quite confusing lol
case "d":
Console.WriteLine("Please enter your option here:");
Console.WriteLine("First number");
double firstNum = Int32.Parse(Console.ReadLine());
Console.WriteLine("Second number:");
double secondNum = Int32.Parse(Console.ReadLine());
double sum = firstNum / secondNum;
Console.WriteLine("Result:" + sum);
Console.WriteLine("\n");
Console.ReadKey();
break;
}
default:
else if (number == 2)
{
Console.WriteLine("Exiting the code");
Console.WriteLine("Please press any key to exit");
Console.ReadLine();
break;
}
else
{
Console.WriteLine("Wrong selection");
Console.WriteLine("Please press any key to go to the main menu");
Console.ReadLine();
Active
Error CS1002 ; expected ConsoleApp50 69 Active
Error CS1513 } expected ConsoleApp50 69 Active
Error CS1513 } expected ConsoleApp50 98 Active
When the code is that weird, sometimes the error messages don't make sense :)
A few problems I see:
At the end of your case "d": block, you have a } where there was no previous {. Unless there is code in your case "d": block that you're not showing us, then you can just delete that }.
In your default: block, you're starting with an else if, where there was no if before that. You can only use else if after an if. Unless there's code you're not showing us, then you can change the else if to just if.
There's no } at the end, to close the else block.
You still need a break; at the end of the default: block.

I get a System.IndexOutOfRangeException [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 4 years ago.
I am having a issue with my current code. I am doing a project like a lot of other people, the famous SodaCrate project.
I do NOT, want any solutions to the code, but I DO want to know why I can't solve the issue with "System.IndexOutOfRangeException".
I get this error when I try to add more than 24 bottles into my crate (I apologize for the swedish comments).
Here is my code:
public void add_soda()
{
Console.WriteLine("\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"");
Console.WriteLine("| Choose your beverage! |");
Console.WriteLine("| |"); // Välkomnar användaren
Console.WriteLine("|[1] Pepsi , Soda, 11kr |");
Console.WriteLine("|[2] Coca-Cola , Soda, 12kr |");
Console.WriteLine("|[3] Coors Light , Beer, 18kr |");
Console.WriteLine("|[4] Fiji, Water , 13kr |");
Console.WriteLine("|[5] Nocco , Energy drink , 22kr |");
Console.WriteLine("|[6] Redbull , Energy drink , 25kr |");
Console.WriteLine("| |");
Console.WriteLine("\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"");
//Console.WriteLine("[7] Randomize"); <---------- Fixa
int temp = 0;
while (!int.TryParse(Console.ReadLine(), out temp) || !(temp < 7 && temp > 0)) // Detta är en failsafe, ifall väljaren väljer något som är över 7 eller under 1 kommer följande kod att skrivas ut.
{
// Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
// Console.ResetColor();
}
switch (temp) // Denna switch statementen kommer låta oss lägga till flaskor i vår crate
{
case 1: //Om anändaren skriver in ett tal mellan 1 och 6, kommer följade cases att skriva ut deras WriteLines.
Console.WriteLine(">>> You choose Pepsi <<<");
myCrate[numberOfBottles] = new Bottle("Pepsi", "Soda", 11); // Här skapas en läsk med namnet Pepsi som kostar 11kr.
numberOfBottles++; // Denna funktion gör så att en läsk läggs in i craten varje gång den skapas.
break;
case 2:
Console.WriteLine(">>> You choose Coca-Cola <<<");
myCrate[numberOfBottles] = new Bottle("Coca-Cola", "Soda", 12);
numberOfBottles++;
break;
case 3:
Console.WriteLine(">>> You choose Coors Light <<<");
myCrate[numberOfBottles] = new Bottle("Coors Light", "Beer", 18);
numberOfBottles++;
break;
case 4:
Console.WriteLine(">>> You choose Fiji <<<");
myCrate[numberOfBottles] = new Bottle("Fiji", "Water", 13);
numberOfBottles++;
break;
case 5:
Console.WriteLine(">>> You choose Nocco <<<");
myCrate[numberOfBottles] = new Bottle("Nocco", "Energydrink", 22);
numberOfBottles++;
break;
case 6:
Console.WriteLine(">>> You choose Redbull <<<");
myCrate[numberOfBottles] = new Bottle("Redbull", "Energydrink", 25);
numberOfBottles++;
break;
default:
//Console.ForegroundColor = ConsoleColor.Red; // <<<<<----------------- FIXA
Console.WriteLine("Invalid choice!");
// Console.ResetColor;
break;
}
try
{
if(numberOfBottles >= 25)
{
Console.WriteLine("The crate is currently full!");
}
}
catch (IndexOutOfRangeException e)
{
Console.WriteLine(e.Message);
throw new ArgumentOutOfRangeException("index paramater is out of range", e);
}
}
Could anyone give me an idea or a hint of why the Exception is being thrown?
I've tried a if-else statement as well I am currently quite confused.
The issue you have occurring is due to your attempt to access a part of the Bottle[] that doesn't exist. Since you've instantiated the array with a certain length, you cannot go beyond that length. Initially (and always) you should check the index you wish to use against the Length property of your array prior to attempting to access it. Say we have an int[] for this entire example, and we initially give it a Length of 3.
int[] someNumbers = new int[3];
In the case above we have created a new int array with 3 slots of memory allocated. If we try to access it with hard coded numbers the problem becomes very obvious:
someNumbers[0] = 1;
someNumbers[1] = 2;
someNumbers[2] = 3;
someNumbers[3] = 4; // Blows up here.
The reason the fourth index of 3 doesn't work is because in C# collections are accessed with zero-based indices; this means that access starts at zero and climbs from there. So technically elements are one space behind where you think they are (if you're used to traditional number systems that start at one).
If you take the same principal and access the array with a variable instead, the same thing will happen but it is less obvious; I assume you know what the ++ operator does for this.
int index = 0;
int[] someNumbers = new int[3];
someNumbers[index++] = 1; // index = 0
someNumbers[index++] = 2; // index = 1
someNumbers[index++] = 3; // index = 2
someNumbers[index++] = 4; // index = 3 :: Blows up here.
This blows up on the fourth index of 3 for the exact same reason. The way to get around this is to check the index prior to access:
if (index < someNumbers.Length)
someNumbers[index++] = 1;
This code works because the assignment will only execute if the index is within the bounds of the array.
Adjust Array Size
Now in other languages there are ways to resize an array quite easily; but C# doesn't let us do this. Good new for us, there is a work-around for it. Again I will be using int[] to demonstrate.
Say we create our initial array with a length of 3:
int[] someNumbers = new int[3];
Somewhere along the road, we decide we need more than 3 numbers for some reason; well, we need a bigger array now. To do this (very inefficiently) you can create a new array with a bigger size and just add all of the old values:
int[] newNumberArray = new int[someNumbers.Length + 10];
for (int i = 0; i < someNumbers.Length; i++)
newNumberArray[i] = someNumbers[i];
The code above creates a bigger array, and puts all of your old values in it. Remember that this is a very inefficient way to accomplish this and I heavily recommend using List<T> or some similar object instead.
In My opinion the problem is, you use the index operator on myCrate [] on array, which does not have enough space in it.
If you know you will have 7 item in the array then please create enough place for it. This code should be like this:
myCrate = new Bottle[7];
And now youa are able to use the index operator for 0 to 6 on this array

Math.round cant do negative numbers c# [duplicate]

This question already has answers here:
Math.Round with negative parameter
(3 answers)
Closed 5 years ago.
I have a homework where im supposed to create a code which should let the user type in a decimal number and then ask how many decimals the user want the number to be rounded to. The homework assignment were given to us with minimal instruction on how to do it so we were supposed to look online. We were given a hint about Math.Round() and this is my code right now:
Console.WriteLine("Hej! Skriv in ett tal med decimaler.");
string strTal = Console.ReadLine();
double tal = Convert.ToDouble(strTal);
Console.WriteLine("Tack! Skriv nu in hur många decimaler du
vill ha med på ditt tal.");
string strAvrundaren = Console.ReadLine();
int avrundaren = Convert.ToInt32(strAvrundaren);
Console.WriteLine("Ditt tal är: " +
Math.Round(tal,avrundaren));
With this code I got it to work so that whenever the user writes a decimal number and then writes the x amount of decimals it should be rounded to it does so correctly. My problem is that I had the thought if someone were to input a negative decimal number (ex: -1, -2, -2,12313 etc..)? I tried and my code crashed when I did it. Now im coming to you guys for an explanation to why it does this.
EDIT: by saying it "crashes", whenever I write in a negative number in the terminal the window pops down to my sidebar and when I bring it back up nothing has happened on the terminal and I can write as much as I want in the terminal but nothing happens. Im on Visual Studio for the Mac if that helps.
Best Regards
Kian
Your program lacks input validation. Not only will a negative number cause it to crash, but any string that is not numeric will also cause an unhandled exception.
Typically a program should validate its inputs before attempting to use them. If the value isn't valid, you can ask the user to input it again. Example:
using System;
public class Program
{
public static void Main()
{
double tal;
while (true)
{
Console.WriteLine("Hej! Skriv in ett tal med decimaler.");
string strTal = Console.ReadLine();
var ok = double.TryParse(strTal, out tal);
if (ok) break;
}
int avrundaren;
while (true)
{
Console.WriteLine("Tack! Skriv nu in hur många decimaler du vill ha med på ditt tal.");
string strAvrundaren = Console.ReadLine();
var ok = int.TryParse(strAvrundaren, out avrundaren);
if (!ok) continue;
if (avrundaren < 0) continue;
break;
}
Console.WriteLine("Ditt tal är: " + Math.Round(tal,avrundaren));
}
}
Try it on DotNetFiddle
Rounding for negative numbers work: Here is a quick test:
var ans = Math.Round(-100.11119, 2);
Console.WriteLine(ans);
Please see fiddle as proof for above test.
If you pass a negative number for the 2nd argument like this:
var ans = Math.Round(-100.11119, -2);
Console.WriteLine(ans);
You will get a runtime error.
Run-time exception (line 7): Rounding digits must be between 0 and 15, inclusive.
Please see fiddle for above test.
Therefore, you need to check the number provided to you by the user and make sure it is between 0 and 15 (inclusive).

Setting random values from an Array into a List till condition is met. in C#

I want to set new random values from an Array into a List till one of two conditions is met. But it's only letting me add another 1 value without considering the condition. After I enter "y" the program letting me to get another value and then it asking me again if I want another card, when I enter "y" again , the code move on without letting me add another value.
The second problem is with the if(Hands.playerHand.Sum() > 22) I want the program to calculate the total value of the list and if it's more then 22 then execute the command.
Thank you!
string userAnotherCard = Console.ReadLine();
bool secondHand = true;
secondHand = (userAnotherCard == "y");
bool secondHandNo = true;
secondHandNo = (userAnotherCard == "n");
while(secondHand)
{
//if user want another card, this programm will ganerate another card and store it inside playerHand
Hands.playerHand.Add(Deck.CardDeck[Hands.rando.Next(0, Deck.CardDeck.Length)]);
Console.WriteLine("Your cards are: ");
Hands.playerHand.ForEach(Console.WriteLine);
Console.WriteLine("Would u like to take another card?");
Console.ReadLine();
if(Hands.playerHand.Sum() > 22)
Console.WriteLine("You loss, your cards sum is more than 21");
break;
}
while (secondHandNo)
break;
So I changed the code a little. Now I can choose as many values as I want but I have a problem with the while (secondHandNo) and the while (Hands.playerHand.Sum() > 21) commands. When I enter "n" after taking another card the while (secondHandNo) which should continue the code wont executed. The while (Hands.playerHand.Sum() > 21) doesn't executed as well. It's just giving me more values no matter what my answer is. Note that when I enter "n" right away without taking another card, the command work just fine and it's taking me to the rest of the code.
string userAnotherCard = Console.ReadLine();
bool secondHand = true;
secondHand = (userAnotherCard == "y");
bool secondHandNo = true;
secondHandNo = (userAnotherCard == "n");
while (secondHand)
{
Hands.playerHand.Add(Deck.CardDeck[Hands.rando.Next(0, Deck.CardDeck.Length)]);
Console.WriteLine("Your cards are: ");
Hands.playerHand.ForEach(Console.WriteLine);
Console.WriteLine("Would u like to take another card?");
Console.ReadLine();
}
while (Hands.playerHand.Sum() > 21)
{
Console.WriteLine("You loss, your cards sum is more than 21");
break;
}
while (secondHandNo)
break;
You have quite a few issues here:
You are not storing the result from the console. This can be solve easily:
userAnotherCard = Console.ReadLine();
Even if we stored it, in the while your condition checks a value that was previously assigned and is never changed. This the reason that you are in an endless loop. I would replace it simply with the condition itself:
while (userAnotherCard == "y")
It seems you are using while break instead of a simple if:
if (Hands.playerHand.Sum() > 21)
while (secondHandNo) break; is useless and can be removed from the code.
That should be enough. Final code can look like this:
string userAnotherCard = Console.ReadLine();
while (userAnotherCard == "y")
{
Hands.playerHand.Add(Deck.CardDeck[Hands.rando.Next(0, Deck.CardDeck.Length)]);
Console.WriteLine("Your cards are: ");
Hands.playerHand.ForEach(Console.WriteLine);
Console.WriteLine("Would u like to take another card?");
userAnotherCard = Console.ReadLine();
if (Hands.playerHand.Sum() > 21)
{
Console.WriteLine("You loss, your cards sum is more than 21");
break;
}
}
Ok I was able to fix this block of code. It seems to work now. I set the whole block into while loop and set each condition with an if statement and a break; if condition is met.
while (true)
{
Console.WriteLine("Would u like to take another card?");
string userAnotherCard = Console.ReadLine();
bool secondHand = true;
secondHand = (userAnotherCard == "y");
bool secondHandNo = true;
secondHandNo = (userAnotherCard == "n");
if (secondHand)
{
Hands.playerHand.Add(Deck.CardDeck[Hands.rando.Next(0, Deck.CardDeck.Length)]);
Console.WriteLine("Your cards are: ");
Hands.playerHand.ForEach(Console.WriteLine);
}
if (Hands.playerHand.Sum() > 21)
{
Console.WriteLine("You loss, your cards sum is more than 21");
break;
}
if (secondHandNo)
break;
}

How to transfer back to previous if statement?

I'm making my first text adventure game with C#, and I was just wondering how I would loop back to a previous if statement.
For Example:
if (x == 2 || y == 3)
{
//do this
if ( z > 3 || v = 6)
{
//do this
}
}
What would I use to make it go from the nested if, to the top if statement?
EDIT: more specifically:
//start
System.Console.WriteLine("You awake in a stupor. The sun blinds you as you roll over to breathe the new day.");
System.Console.WriteLine(" ");
System.Console.WriteLine(" ");
System.Console.WriteLine("To your (west), you see a volcanic mountain, with a scraggly, dangerous looking path.");
System.Console.WriteLine(" ");
System.Console.WriteLine("In the (east), you see a thick forrest. there is nothing visible past the treeline.");
System.Console.WriteLine(" ");
System.Console.WriteLine("Looking (south), you see a long winding road that seems to have no end.");
System.Console.WriteLine(" ");
System.Console.WriteLine("Hearing a sound of celebration, you look to the (north). There appears to be a city, with a celebration going on.");
System.Console.WriteLine(" ");
System.Console.WriteLine(" ");
System.Console.WriteLine("Which direction would you like to travel?");
string direction1 = Convert.ToString(Console.ReadLine());
//first decision (north)
if (direction1 == "north" || direction1 == "North")
{
Console.WriteLine("You proceed towards the north, only to be stopped by a guard:");
Console.WriteLine("Guard: 'the kingdom of al'arthar is off limits to outsiders today, its the queens birthday, and the kingdom is packed full");
Console.WriteLine(" ");
Console.WriteLine(" ");
Console.WriteLine("you can either try to (swindle) the guard, or (leave). What will you do?");
string guardConvo1 = Convert.ToString(Console.ReadLine());
Say, for example, if someone traveled North in this scenario, and then wanted to go back. Rather than recode the previous if statement, how would I make it just loop back to the previous if statement?
It's hard to know without knowing more context about what you're trying to do. You might want to extract some code into its own method and call it in both places, or create a loop (for, while, etc.) to handle control. It's even possible to use a goto command, though I would almost never recommend that.
Maybe you should have some sort of state machine running your game to help handle conditions and actions.
Update: As you've found, the way you're writing the code is almost entirely unworkable for a text adventure game. Something to get you going in the right direction would be this: refactor each room into its own method. When you want to go from one room to another, you call the method for that room.
void StartingArea()
{
System.Console.WriteLine("You awake in a stupor. The sun blinds you as you roll over to breathe the new day.");
System.Console.WriteLine(" ");
System.Console.WriteLine(" ");
System.Console.WriteLine("To your (west), you see a volcanic mountain, with a scraggly, dangerous looking path.");
System.Console.WriteLine(" ");
System.Console.WriteLine("In the (east), you see a thick forrest. there is nothing visible past the treeline.");
System.Console.WriteLine(" ");
System.Console.WriteLine("Looking (south), you see a long winding road that seems to have no end.");
System.Console.WriteLine(" ");
System.Console.WriteLine("Hearing a sound of celebration, you look to the (north). There appears to be a city, with a celebration going on.");
System.Console.WriteLine(" ");
System.Console.WriteLine(" ");
System.Console.WriteLine("Which direction would you like to travel?");
string direction1 = Convert.ToString(Console.ReadLine());
if (direction1 == "north" || direction1 == "North")
{
AlArtharGate();
}
}
void AlArtharGate()
{
Console.WriteLine("You proceed towards the north, only to be stopped by a guard:");
Console.WriteLine("Guard: 'the kingdom of al'arthar is off limits to outsiders today, its the queens birthday, and the kingdom is packed full");
Console.WriteLine(" ");
Console.WriteLine(" ");
Console.WriteLine("you can either try to (swindle) the guard, or (leave). What will you do?");
string guardConvo1 = Convert.ToString(Console.ReadLine());
if (string.Equals(guardConvo1, "leave", StringComparison.CurrentCultureIgnoreCase))
{
StartingArea();
}
}
This isn't perfect, but it's better: you have made each area its own callable entity instead of just a section of code in an if statement. You can study the code of this Python text adventure game base for a more advanced and complete example.
By the way, you might want to be ignoring all case (like I did with the comparison at the end), not just checking for "north" and "North".
Hmm not much to go on here, but there are a lot of things you could do.
A State machine is mentioned, but it might be a little abstract to wrap around at first. But think of it as cities and roads, you as a person can be at one place and only walk one road at a time. Sometimes you end up going in circles, other times you reach the end.
In your game you have a lot of actions or we can call them choices if you like. and maybe this pseudocode might get you on the right track of mind.
void Init(){
Print("Select Choice")
int choice = Read()
if(choice == 1)
{
Choice1()
}
else if(choice == 2)
{
Choice2()
}
else
{
InvalidChoice()
}
}
void Choice1(){
Print("Welcome to Choice1 perform action or choice")
int choice = Read()
if(choice == 1)
{
Choice2()
}
else if(choice == 2)
{
Choice3()
}
else
{
InvalidChoice()
}
}
void Choice2(){
Print("Welcome to Choice2 perform action or choice")
int choice = Read()
if(choice == 1)
{
Choice3()
}
else if(choice == 2)
{
Choice1()
}
else
{
InvalidChoice()
}
}
void Choice3()
{
InvalidChoice()
}
void InvalidChoice()
{
Print("You died")
}

Categories

Resources