Reputation: 25
I have this code which runs the way it is supposed to do. But I want to implement something extra if a user clicks either 1, 2 or 3 once the first value has been inserted. As you can see if a user press 2 the second time, a list of players by first name will show (at least that is my intention). So my question is if this can be done by inserting a switch-case condition inside of the previous? I have tried something like this: See further below for more code.
var isValidMenuItem = false;
while (!isValidMenuItem)
isValidMenuItem = Menu();
Console.WriteLine();
Console.ReadKey(true);
}
private static bool Menu()
{
Console.WriteLine("You have now entered the 2017 Wimbledon tournament!" + "\n" + "\n");
Console.Write("Choose one of the 6 options:" + "\n" + "Press 1 for Default tournament:" + "\n" + "Press 2 for Women's single:" + "\n" +
"Press 3 for Men's single:" + "\n" + "Press 4 for Women's double:" + "\n" + "Press 5 for Men's double:" + "\n" +
"Press 6 for Mix double:" + "\n" + "Insert your choice...: ");
var userValue = Console.ReadKey().KeyChar;
Console.WriteLine();
switch (userValue)
{
case '1':
Console.WriteLine("\n"+ "You have entered a default tournament");
break;
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
break;
case '3':
Console.WriteLine("\n" + "You have entered men's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
break;
case '4':
Console.WriteLine("\n" + "You have entered women's double");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
break;
case '5':
Console.WriteLine("\n" + "You have entered men's double");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
break;
case '6':
Console.WriteLine("\n" + "You have entered mix double");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
break;
default:
Console.WriteLine("\n" + "Sorry! You have to choose one of the 6 tournament options");
return false;
}
Like this: ... But it doesn't seem to work? Do you guys have any ideas?
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
{
switch (userValue)
{
case '1':
Console.WriteLine("Hello");
break;
}
break;
}
Upvotes: 2
Views: 107
Reputation: 236318
First of all, you don't need nested switches here. You have to select two things in a consecutive way:
So, you can create the enum for tournament type:
public enum TournamentType
{
Default,
SingleWomen,
SingleMen,
DoubleWomen,
DoubleMen,
DoubleMix
}
Then you need to get selected option. You can use switch statement here, but you can also create an option selector class:
public class OptionSelector<T>
{
private readonly List<Option> options = new List<Option>();
public T SelectedOption { get; private set; }
public OptionSelector<T> WithOption(T value, string title)
{
options.Add(new Option { Value = value, Title = title });
return this;
}
public bool SelectOption()
{
if (!options.Any()) return true;
Console.WriteLine($"Choose one of the {options.Count} options:");
for(int i = 0; i < options.Count; i++)
Console.WriteLine($" {i + 1} - {options[i].Title}");
Console.Write("Your choice: ");
var key = Console.ReadKey().KeyChar;
Console.WriteLine();
int choice = key - '0';
if (!Char.IsDigit(key) || choice == 0 || options.Count < choice) {
Console.WriteLine($"Sorry, only digits 1..{options.Count} are allowed");
return false;
}
SelectedOption = options[choice - 1].Value;
return true;
}
private class Option {
public T Value { get; set; }
public string Title { get; set; }
}
}
Few lines of code, but good functionality - this class allows to build a set of options in the fluent way and then accept user input. If input is valid, then selected option will be available via SelectedOption
property. Otherwise verbose error message will be displayed. Nice thing here is that options selector is a generic class. Each option can be literally anything - integer, string, enum value, or even a method. With this class all your code can be collapsed to:
Console.WriteLine($"You have now entered the 2017 Wimbledon tournament!\n");
var tournamentTypeSelector = new OptionSelector<TournamentType>()
.WithOption(TournamentType.Default, "Default tournament")
.WithOption(TournamentType.SingleWomen, "Women's single")
.WithOption(TournamentType.SingleMen, "Men's single")
.WithOption(TournamentType.DoubleWomen, "Women's double")
.WithOption(TournamentType.DoubleMix, "Mix double");
while (!tournamentTypeSelector.SelectOption()) { /*Console.Clear();*/ }
var tournamentType = tournamentTypeSelector.SelectedOption;
var actionSelector = new OptionSelector<Action>()
.WithOption(() => StartTournament(tournamentType), "Start the tournament")
.WithOption(() => Console.WriteLine("Not implemented"), "List players by first name")
.WithOption(() => Console.WriteLine("Not implemented"), "List players by last name");
while (!actionSelector.SelectOption()) { /*Console.Clear();*/ }
actionSelector.SelectedOption(); // invoke selected action
Woo-hoo! No switches at all
First selector here selects tournament type. Second selector selects an actionto be invoked. And the nice thing here is that you can pass arguments to those actions (e.g. tournament type). Btw StartTournament
is the method which contains corresponding functionality:
private static void StartTournament(TournamentType tournamentType)
{
// your code here
Console.WriteLine("Tournament started");
}
Check the Fiddle to see how it works. Note that fiddle dont support Console.ReadKey
so you should press enter each time.
Upvotes: 0
Reputation: 45
Switch inside a switch should work!
int x = 1;
switch(x)
{
case 1: // Enters Here cause x = 1
Console.WriteLine("test"); //prints
switch(x) // x still = 1
{
case 1: //enters here cause x = 1
Console.WriteLine("works"); //prints
break;
}
break;
default:
Console.WriteLine("doesnt work");
break;
}
(Output will be: "test" "works")
you just happened to write weird "{}", is that the problem?
If you want to enter different Switch cases you have to change the value of the switch(value) to enter different cases.
In your case thats:
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
//Ask for a new input here = (NEWVALUE)
switch (NEWVALUE)
{
case '1':
Console.WriteLine("Hello");
break;
}
break;
Upvotes: 0
Reputation: 727077
Apart from hurting readability, nesting a switch
inside another switch
is fine. The language fully supports it.
In your case your switch
does not work because you are switching on a variable that has not changed since entering the outer switch, so the construct is effectively useless. Add code to modify userValue
before entering the nested switch, like this:
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
var userChoice = Console.ReadKey().KeyChar; // <<<<<==== Add this line
switch (userChoice) {
case '1':
Console.WriteLine("Hello");
break;
}
break;
Upvotes: 0
Reputation: 2917
You need to re-read the value first.
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
userValue = Console.ReadKey().KeyChar;
{
switch (userValue)
{
case '1':
Console.WriteLine("Hello");
break;
}
}
break;
Upvotes: 0
Reputation: 373
It seems to me there is an extra curly brackets there? Isn't it? Shouldn't it be:
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
switch (userValue)
{
case '1':
Console.WriteLine("Hello");
break;
default
return false;
}
break;
Upvotes: 0
Reputation: 11
The switch statement itself should be fine as is.
The problem lies within the variable userValue. You only evaluate var userValue = Console.ReadKey().KeyChar;
once, so the value is set to that one key value.
For instance, in your example, the outer switch statement enters case '2', because that is what userValue is set to. But then, when entering the inner switch statement, it uses the same value AGAIN since the ReadKey() function is not evaluated again. So then your switch statement will see "userValue" as 2 without even expecting or waiting for any input at all, so it just falls out of the switch.
EDIT here: You could just call the ReadKey() function again to solve this, or use a second variable:
//Inner switch statement:
//{ (bracket is redundant)
userValue = Console.ReadKey().KeyChar;
switch (userValue)
{
// switch body here...
}
//}
Upvotes: 1
Reputation: 478
There are two things in your code
First
if your switch value is the same, as it is in your code, it can´t work, because one variable can only have one value.
Second
Remove the brackets
case '2':
Console.WriteLine("\n" + "You have entered women's single");
Console.Write("Press 1 to start the tournament:" + "\n" + "Press 2 to list the players by first name:" + "\n" +
"Press 3 to list the players by last name:" + "\n" + "Insert your choice...: ");
//{ <- remove
switch (userValue)
{
case '1':
Console.WriteLine("Hello");
break;
}
break;
//} <- remove
Upvotes: 0