Why doesn't void Main start after the if-condition? - c#

Void Main won't start again after the if-statement.
I have been experimenting for a while with such constructions and normally they work. But that's not the case. The generator void is somewhere below, please don't take it into consideration.
class Program
{
private static string Input = Console.ReadLine();
static void Main()
{
Console.WriteLine("Press any key to start");
Program.Generator();
Console.WriteLine("Are you satisfied? Type '1' if yes or '2' if no.");
Console.ReadLine();
if (Input == "2")
Program.Main();
}
}
No errors, no mistakes, the console just closes after completing Main.

Welcome to stack overflow. You're not crazy, just missing a piece of information about programming and flow of control. Specifically, iteration statements.
The program you've written will exit any time Input holds a value other than 2 because there's no loop forcing it to run over and over again.
static void Main()
{
Console.WriteLine("Press any key to start");
Console.ReadKey();
do
{
// Program.Generator();
Console.WriteLine("Are you satisfied? Type '1' if yes or '2' if no.");
} while (Console.ReadKey().KeyChar != '1');
}

Related

How to put User Input to end the loop on c#

Im new to programming in C# and i encountered some problems, I am trying to create a countdown Console Command but im stuck on how to terminate the loop using a user input (in this case, when the user presses the "Enter" Button)
Here is the code that I currently have
using System;
using System.Threading;
class stopWatch {
public static void Main (string[] args) {
Console.WriteLine ("Access The Clock? Y/N");
string yN = Console.ReadLine();
if ((yN == "y") || (yN == "Y")) {
Console.WriteLine ("Timer (T) or Stopwatch (S)?");
var sT = Console.ReadLine();
if ((sT == "s") || (sT == "S")) {
Console.WriteLine ("Press the 'Enter' Button to Start");
Console.ReadLine();
Console.WriteLine("Stopwatch Started");
Console.WriteLine("Press the 'Enter' Button again to Stop");
for(int i = 0; i >= 0; i ++) {
Console.WriteLine(i);
Thread.Sleep(1000);
}
}
}
else if ((yN =="n") || (yN == "N")) {
Console.WriteLine ("Alright, Thank You");
Environment.Exit(0);
}
else {
Console.WriteLine ("Wrong Input");
Environment.Exit (0);
}
}
}
keep in mind im very new to c# and loops, i'm getting a hard time translating and trying on everything, it'd be really grateful of me to get an extra explanation for your answers
You need to use separate thread for that. Threads is advanced theme, but the basic goal is to do several things at once (in your example run stopwatch and wait for user input). Here is full working code based on your sample:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp13
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Access The Clock? Y/N");
string yN = Console.ReadLine().ToLower();
if (yN == "y")
{
Console.WriteLine("Timer (T) or Stopwatch (S)?");
var sT = Console.ReadLine().ToLower();
if (sT == "s")
{
Console.WriteLine("Press the 'Enter' Button to Start");
Console.ReadLine();
bool runStopWatch = true;
Task.Run(() =>
{
for (int i = 0;; i++)
{
Console.WriteLine(i);
Thread.Sleep(1000);
if (!runStopWatch)
{
break;
}
}
});
Console.WriteLine("Stopwatch Started");
Console.WriteLine("Press the 'Enter' Button again to Stop");
Console.ReadLine();
runStopWatch = false;
}
}
else if (yN == "n")
{
Console.WriteLine("Alright, Thank You");
Environment.Exit(0);
}
else
{
Console.WriteLine("Wrong Input");
Environment.Exit(0);
}
}
}
}
Task.Run starts a new thread, so your stopwatch runs independent of the main thread (which waits for user to press Enter). Variable runStopWatch is shared between threads (don't think about it right now), so when main thread sets it to false, stopwatch's thread sees it and terminated the loop.
Side mote. More proper way to do this is to use CancellationToken istead of bool variable. But again. don't worry about it right now.
Since you're new im going to try to explain it as simple as possible. The solution you're trying to create is a solution to a multi-threaded problem. This means you will have to do an action while another action takes place. This can be resolved using async methods, this might be too advanced for now, so I will suggest reading up on loops and then multi-threaded programming first.
But for an answer i will have to refer to this post here on how to fix this particular problem. (Look at the second part of the accepted answer).

Ending a loop to return to next sequence

I was trying to make a text adventure in C#. Ive only been coding for a few days and I can't find how to do this.
I was trying to to ask a yes or no question and yes would go to the next question in the story. If its a no I wanted it to start a loop till it forces the player to type the correct answer (yes). After the user types yes how do i get it to exit the loop and move to the next part of the story? If this doesn't make sense ask me and I will try to reexplain.
Here is how i got it to at least go to the next section. I would like it to loop till the user says yes. I would like it to loop though.
using System;
namespace Game.of.words.forgotten.period
{
class Program
{
public static player currentplayer = new player();
static void Main(string[] args)
{
Console.Clear();
Start();
Encounters.Firstencounter();
}
static void Start()
{
Console.WriteLine("Game Of Words The Forgotten Period");
Console.WriteLine("Welcome to my world. What is your name? ");
string currentplayer = Console.ReadLine();
Console.Clear();
Console.WriteLine("We are happy to see you here " + currentplayer + " !");
Console.WriteLine("I bet you are wondering where you are and why you are here. Is that correct? (Yes) or (No)");
string input = Console.ReadLine();
if (input.ToLower() == "yes")
{
//Yes
Console.WriteLine("I thought as much.I am incredibly skilled at the confusion arts");
}
else
{
//no
Console.WriteLine("Well I just assumed because... I mean I took all this time to make this a crazy experience to");
Console.WriteLine(" confuse you but I guess you are too smart for that.");
Console.WriteLine("Please just say yes.");
Console.ReadLine();
if (input.ToLower() == "no")
{
Console.WriteLine("Okay fine. You can be like that");
}
else
Console.Write("I thought as much. I am incredibly skilled at the confusion arts.");
Console.ReadKey();
Console.Clear();
}
Console.ReadLine();
Console.WriteLine("As you see we are in the middle of no where. Surounded by Tall mountains and no trees.");
Console.WriteLine("I bet you can feel the slight breeze and smell the fragrece of the flowers all around us");
Console.WriteLine("Do you want me to telaport us into town or do you walk through the flowers and watch the clouds for a while? ");
Console.ReadLine();
Console.Clear();
}
}
}
Here is another example. I am not understanding something.
class Program
{
static void Main(string[] args)
{
Console.Write("hello Player what is your name? ");
String Name= Console.ReadLine();
string j = ("June");
if (Name != j)
{
Console.WriteLine("Hello " + Name);
while (Name != j)
{
Console.WriteLine("Thats not your name");
// Creates endless loop. If I add a readline it will
//print hello michael and then that is not your name will
//Repeat on every enter.
//If I put a break; it just prints both and ends.
}
Console.ReadLine();
}
Console.ReadLine();
}
}
on the second example you don't really need the if statement, you can use the while loop.
string exitName = "exit";
Console.Write($"hello Player what is your name? (to skip the while loop you must type {exitName}) {Environment.NewLine}");
String Name = Console.ReadLine();
while (Name != exitName)//while the name does not equal 'exit' you will stay in the loop
{
Console.WriteLine("You did not exit!");
Console.WriteLine($"You entered {Name} you must enter {exitName} to exit this loop!");
Name = Console.ReadLine();
}
Console.WriteLine("press any key to end game");
Console.ReadLine();
In your first example you have the lines
Console.WriteLine("Please just say yes.");
Console.ReadLine();
this should be
Console.WriteLine("Please just say yes.");
input = Console.ReadLine();
otherwise you aren't assigning anything to input again.

C# Xamarin Wrong If clause being used?

In my C# code (I am currently trying to learn it), I am trying to make a text - console based adventure game. The first 'Section' works, and I copy pasted it over to and changed the name of the variables etc. (Its a repetitive code), but it just wont work.
Here is the code:
using System;
namespace LearningC
{
class MainClass
{
public static void Main (string[] args)
{
lvl_1_start: //LEVEL ONE
Console.WriteLine ("Welcome to AlexAdventureLand.\nPlease press the enter key to start.");
Console.ReadKey ();
Console.WriteLine ("You are a rabbit in a burrow. There is a badger outside. \nPress 1 to leave the burrow. \nPress 2 to wait.");
int lvl_1 = Convert.ToInt32 (Console.ReadLine ());
if (lvl_1 == 1) {
Console.WriteLine ("The badger sees you and eats you. \nYou fail. \n\nPress enter to try again.");
Console.ReadKey ();
goto lvl_1_start;
} else if (lvl_1 == 2) {
Console.WriteLine ("The badger scurries away!");
goto lvl_2_start;
} else {
Console.WriteLine ("You pressed the wrong button. Start again.");
goto lvl_1_start;
}
lvl_2_start: //LEVEL TWO
Console.WriteLine ("Now what do you want to do? \nPress 1 to leave burrow. \nPress 2 to wait.");
Console.ReadKey ();
int lvl_2 = Convert.ToInt32 (Console.Read ());
if (lvl_2 == 1) {
Console.WriteLine ("You leave the burrow and look around.");
Console.ReadKey ();
goto lvl_3_prt_a_start;
} else if (lvl_2 == 2) {
Console.WriteLine ("You wait a little longer. \nYou can hear footsteps around your burrow. You wonder whether it's your friend - troy - or the badger still.");
goto lvl_3_prt_b_start;
} else {
Console.WriteLine ("You pressed the wrong button. Start again.");
goto lvl_2_start;
}
lvl_3_prt_a_start: //LEVEL THREE PART A
Console.WriteLine ("PlaceHolder");
Console.ReadKey ();
lvl_3_prt_b_start:
Console.WriteLine ("PlaceHolder");
Console.ReadKey ();
}
}
}
The problem occurs when running it. The first section works fine, and pressing '1', '2' or any other number works - but on section two, it always comes up with the else section, none of the if or if else clauses. Any quick help would be great. Thanks!
The problem is that you're calling both ReadKey and Read. These each read a single character, so ReadKey gets your selection, and Read just gets your \r (first character of newline). ReadKey returns info about your keypress (which is ignored), and Read returns an int corresponding to the char value you entered (note that int and char are numeric types, and converting one of those ToInt32 is different from parsing a string!).
You should use code like your working code to read input:
int lvl_2 = Convert.ToInt32(Console.ReadLine()); // or, does the same thing:
int lvl_2 = int.Parse(Console.ReadLine());
(the Convert class supports conversions in a wide range of types; if all you need to do is parse a string to an int, int.Parse is the more common option and gives you more choices)
Also, you should avoid gotos in C#. They lend themselves to writing spaghetti code, and overall are a bad idea (except for very rare exceptions). I can see that they're already leading to your method being a God Method. Here's an example that should put you more on the right track:
static void Main(string[] args)
{
Level1();
}
static void Level1()
{
Console.WriteLine("Welcome to AlexAdventureLand.\nPlease press the enter key to start.");
Console.ReadKey();
Console.WriteLine("You are a rabbit in a burrow. There is a badger outside. \nPress 1 to leave the burrow. \nPress 2 to wait.");
int selection = int.Parse(Console.ReadLine());
if (selection == 1)
{
Console.WriteLine("The badger sees you and eats you. \nYou fail. \n\nPress enter to try again.");
Console.ReadKey();
Level1();
}
else if (selection == 2)
{
Console.WriteLine("The badger scurries away!");
Level2();
}
else
{
Console.WriteLine("You pressed the wrong button. Start again.");
Level1();
}
}
static void Level2()
{
Console.WriteLine("Now what do you want to do? \nPress 1 to leave burrow. \nPress 2 to wait.");
int selection = int.Parse(Console.ReadLine());
if (selection == 1)
{
Console.WriteLine("You leave the burrow and look around.");
Console.ReadKey();
Level3A();
}
else if (selection == 2)
{
Console.WriteLine("You wait a little longer. \nYou can hear footsteps around your burrow. You wonder whether it's your friend - troy - or the badger still.");
Level3B();
}
else
{
Console.WriteLine("You pressed the wrong button. Start again.");
Level2();
}
}
static void Level3A()
{
Console.WriteLine("PlaceHolder");
Console.ReadKey();
}
static void Level3B()
{
Console.WriteLine("PlaceHolder");
Console.ReadKey();
}

How to handle key press event in console application

I want to create a console application that will display the key that is pressed on the console screen, I made this code so far:
static void Main(string[] args)
{
// this is absolutely wrong, but I hope you get what I mean
PreviewKeyDownEventArgs += new PreviewKeyDownEventArgs(keylogger);
}
private void keylogger(KeyEventArgs e)
{
Console.Write(e.KeyCode);
}
I want to know, what should I type in main so I can call that event?
For console application you can do this, the do while loop runs untill you press x
public class Program
{
public static void Main()
{
ConsoleKeyInfo keyinfo;
do
{
keyinfo = Console.ReadKey();
Console.WriteLine(keyinfo.Key + " was pressed");
}
while (keyinfo.Key != ConsoleKey.X);
}
}
This will only work if your console application has focus. If you want to gather system wide key press events you can use windows hooks
Unfortunately the Console class does not have any events defined for user input, however if you wish to output the current character which was pressed, you can do the following:
static void Main(string[] args)
{
//This will loop indefinitely
while (true)
{
/*Output the character which was pressed. This will duplicate the input, such
that if you press 'a' the output will be 'aa'. To prevent this, pass true to
the ReadKey overload*/
Console.Write(Console.ReadKey().KeyChar);
}
}
Console.ReadKey returns a ConsoleKeyInfo object, which encapsulates a lot of information about the key which was pressed.
Another solution, I used it for my text based adventure.
ConsoleKey choice;
do
{
choice = Console.ReadKey(true).Key;
switch (choice)
{
// 1 ! key
case ConsoleKey.D1:
Console.WriteLine("1. Choice");
break;
//2 # key
case ConsoleKey.D2:
Console.WriteLine("2. Choice");
break;
}
} while (choice != ConsoleKey.D1 && choice != ConsoleKey.D2);

Threading: Variable Access and Termination of a Thread

Let me start by showing you my code so far:
using System;
using System.Threading;
class MathQuiz
{
static void Main()
{
int score = 0;
string preanswer;
decimal answer = 0;
Console.WriteLine("Welcome to Project5, a MathQuiz project.");
Console.WriteLine("You will be asked 10 questions, and will have 30 seconds to read and answer each one.");
Console.WriteLine("Press any key to begin.");
Console.ReadKey(true);
Console.WriteLine("What is 2 + 2?");
Thread ask = new Thread (new ThreadStart (MathQuiz.prompt));
ask.Start();
Thread.Sleep(3000);
//This is where I want to end the thread if it isn't already done.
if (answer == 4)
{
score = score+1; //Here's where I don't know if my adding is correct.
}
Console.WriteLine("Press any key to move on to the next question!");
Console.ReadKey(true);
}
static void prompt()
{
preanswer = (Console.ReadLine());
if (!decimal.TryParse(preanswer, out answer))
{
Console.WriteLine("That wasn't even a number or decimal!");
}
else
{
answer = decimal.Parse(preanswer);
}
}
}
So, when I try and compile this code, I get CS0103 errors for preanswer and answer in the "prompt" method.
This leads to 3 questions:
What EXACTLY do I have to do to make preanswer and answer accessible to the "prompt" method?
Did I add 1 onto the score variable correctly?
How can I terminate a thread if it is running? (In this case, the "ask" thread wouldn't end until they typed an answer.)
Please just tell me what to change. I don't know coding words and terminology because I just started a few weeks ago. Please try to be as clear as possible.
static string preanswer;
static decimal answer = 0;
static void Main()
{
int score = 0;
//string preanswer;
//decimal answer = 0;
...
etc.
To wait for the thread, use Join()... This will tell the thread which the function is called on to wait for the thread until it joins back:
ask.Join(int);

Categories