How do I jump into another menu without nesting unnecessarily? - c#

I'm stuck with the following code and what I'm trying to achieve now, is to NOT nest switches/if statements any further, which would result in ugly code, I assume. To visualize my intention:
ConsoleKeyInfo keyE = Console.ReadKey();
if (keyE.Key == ConsoleKey.Enter && iMOP == 1){
//Jump to character creation (but not nest this if statement even further)
{
I want to apply this idea to a solved problem which I have already asked before:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.CursorVisible = false;
int iMOP = 1;
Console.WriteLine(" >>New Game");
Console.WriteLine(" Load Game");
Console.WriteLine(" Exit Game");
while (iMOP != 5)
{
{
ConsoleKeyInfo keyInfo = Console.ReadKey();
if (keyInfo.Key == ConsoleKey.UpArrow)
{
iMOP--;
}
else if (keyInfo.Key == ConsoleKey.DownArrow)
{
iMOP++;
}
}
if (iMOP == 0)
{
iMOP = 3;
}
else if (iMOP == 4)
{
iMOP = 1;
}
switch (iMOP)
{
case 1:
Console.Clear();
Console.WriteLine(" >>New Game");
Console.WriteLine(" Load Game");
Console.WriteLine(" Exit Game");
break;
case 2:
Console.Clear();
Console.WriteLine(" New Game");
Console.WriteLine(" >>Load Game");
Console.WriteLine(" Exit Game");
break;
case 3:
Console.Clear();
Console.WriteLine(" New Game");
Console.WriteLine(" Load Game");
Console.WriteLine(" >>Exit Game");
break;
}
}
}
}
The questions would be: How do I realize this? Are there decent tutorials which you could link me to?

If it is going to get too complicated, use a Console based Graphics engine (Is there any console "graphics" library for .Net?).
MonoCurses seem to be very friendly: http://www.mono-project.com/docs/tools+libraries/libraries/monocurses/
But, just for curiosity, something much simpler (from scratch):
Use Classes to Create, Display and Get the user input for your menu.
How it works
It is basically a Menu Class, that displays its MenuItem classes, and draw while wait the user select a option.
This menu class was then inserted in a nested Switch, for the Main Menu levels.
I tried to do something better, needs refactoring, so you can have some idea to improve:
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
class Program
{
static void Main(string[] args)
{
do
{
#region Main Menu
var m = new Menu() { Title = "MAIN MENU" };
m.Menus.Add(new MenuItem() { Title = "New Game", SelectedForegroundColor = ConsoleColor.Green });
m.Menus.Add(new MenuItem() { Title = "Load Game" });
m.Menus.Add(new MenuItem() { Title = "Exit Game", SelectedForegroundColor = ConsoleColor.Yellow });
var result = m.ShowAndWaitUserInput();
//Console.Write("selected was:" + result);
//Console.ReadLine();
#endregion
switch (result)
{
case 0:
#region // Jump to character creation
var m1 = new Menu() { Title = "CHARACTER CREATION" };
m1.Menus.Add(new MenuItem() { Title = "New Character" });
m1.Menus.Add(new MenuItem() { Title = "Load Character" });
m1.Menus.Add(new MenuItem() { Title = "Return" });
var result1 = m1.ShowAndWaitUserInput();
switch (result1)
{
case 0:
#region // CREATE THE NEW CHARACTER
Console.WriteLine("CREATE THE NEW CHARACTER");
Console.ReadKey();
#endregion
break;
case 1:
#region // LOAD CHARACTER
Console.WriteLine("LOAD CHARACTER");
Console.ReadKey();
// Write your code here...
#endregion
break;
case 2:
#region // DO ALMOST NOTHING: RETURNS TO PREVIOUS MENU
#endregion
break;
}
#endregion
break;
case 1:
#region // Load Game code...
Console.WriteLine("LOAD GAME");
Console.ReadKey();
// Write your code here...
#endregion
break;
case 2:
#region // EXIT GAME
#endregion
return;
}
} while (true); // Main Menu
}
}
public class MenuItem
{
public string Title { get; set; }
public ConsoleColor SelectedForegroundColor { get; set; }
public MenuItem()
{
this.SelectedForegroundColor = ConsoleColor.Yellow;
}
}
public class Menu
{
public string Title { get; set; }
public List<MenuItem> Menus { get; set; }
public Menu()
{
this.Menus = new List<MenuItem>();
}
public int ShowAndWaitUserInput()
{
Console.CursorVisible = false;
int selectedMenu = 0;
do
{
Console.Clear();
#region Display Menu and Sub-Menus
{
var i = 0;
// more at http://www.graphics.cornell.edu/~westin/misc/windows_charmap.html
Console.WriteLine(" ╔═══════════════════════════════════════════╗");
Console.WriteLine(" ║ ░ " + this.Title.ToUpper().PadRight(40).Substring(0, 40) + "║");
Console.WriteLine(" ╚═══════════════════════════════════════════╝");
Console.WriteLine("");
//var old_CB = Console.BackgroundColor;
var old_CF = Console.ForegroundColor;
foreach (var menu in Menus)
{
//Console.WriteLine(" New Game");
if (i == selectedMenu)
{
Console.ForegroundColor = menu.SelectedForegroundColor;
Console.Write(" >> ");
}
else
{
Console.ForegroundColor = old_CF;
Console.Write(" ");
}
Console.WriteLine(menu.Title);
i++;
}
Console.WriteLine("");
//Console.BackgroundColor = old_CB;
Console.ForegroundColor = old_CF;
}
#endregion
#region Get User Input
{
ConsoleKeyInfo keyInfo = Console.ReadKey();
if (keyInfo.Key == ConsoleKey.UpArrow)
{
selectedMenu--;
if (selectedMenu < 0) selectedMenu = Menus.Count() - 1;
}
else if (keyInfo.Key == ConsoleKey.DownArrow)
{
selectedMenu++;
if (selectedMenu == Menus.Count()) selectedMenu = 0;
}
else if (keyInfo.Key == ConsoleKey.Enter)
{
return selectedMenu;
}
}
#endregion
} while (true);
}
}
}

Related

How to re-write menu using DRY

I'm doing a school project and I really feel that I can acomplish what I want in my code, however I feel like i -always- repeat my code.
I have tried to put the switch cases into methods but haven't had any success though to out of scope.
I am beginner so sorry for the eyesore code!
However, if anyone have any tips for using methods or something else so I can clean up my code a little better.
So here is a bit of my code, this is the beginning branch of my menu.
I have translated the code roughly to english.
So this is a sub menu in the main method.
string[] flowers = { "Sunflower", "Coleus Tree", "Tomato" };
int[] plant = { 0, 0, 0 };
switch (menuInput03)
{
/////WATER PLANT////
case 1:
Console.Clear();
Console.WriteLine("Press SPACEBAR several times to water plant!");
if (plant[0] < 21)
{
for (int i = plant[0]; i < 21; i++)
{
var keyPressed = Console.ReadKey();
if (keyPressed.Key == ConsoleKey.Spacebar)
{
plant[0] = i;
Console.Clear();
Console.WriteLine("Press SPACEBAR several times to water plant!");
Console.WriteLine("\nWatering plant..");
Console.WriteLine("[" + flowers[0] + " " + plant[0] + "/100]");
}
}
while (true)
{
Console.Clear();
Console.WriteLine("Your plant has been watered!");
Console.WriteLine("[" + flowers[0] + " " + plant[0] + "/100]\n");
Console.WriteLine("To continue press ENTER.");
var keyPressed01 = Console.ReadKey();
if (keyPressed01.Key == ConsoleKey.Enter)
{
Console.Clear();
break;
}
else
{
Console.Clear();
}
}
}
else
{
break;
}
Console.Clear();
break;
case 2:
Console.Clear();
Console.WriteLine("Press SPACEBAR several times to remove weed!");
if (plant[0] > 19)
{
for (int i = plant[0]; i < 51; i++)
{
var keyPressed = Console.ReadKey();
if (keyPressed.Key == ConsoleKey.Spacebar)
{
plant[0] = i;
i++;
Console.Clear();
Console.WriteLine("Press SPACEBAR several times to remove weed!");
Console.WriteLine("\nRipping out weeds..");
Console.WriteLine("[" + flowers[0] + " " + plant[0] + "/100]");
}
}
while (true)
{
Console.Clear();
Console.WriteLine("Your plant has gotten it's weed removed!");
Console.WriteLine("[" + flowers[0] + " " + plant[0] + "/100]\n");
Console.WriteLine("To continue press ENTER.");
var keyPressed01 = Console.ReadKey();
if (keyPressed01.Key == ConsoleKey.Enter)
{
Console.Clear();
break;
}
else
{
Console.Clear();
}
}
}
Console.Clear();
break;`
I came up with the following; don't just copy-paste for school project without understanding what is going on. If some things are not clear do not hesitate to ask follow-up questions.
public record Action
{
public string Title { get; }
public int RequiredHealth { get; }
public string ActionMessage { get; }
public string CompletedMessage { get; }
private Action(string title, int requiredHealth, string actionMessage, string completedMessage)
{
Title = title;
RequiredHealth = requiredHealth;
ActionMessage = actionMessage;
CompletedMessage = completedMessage;
}
public static Action WaterPlant { get; } = new Action(
title: "Press SPACEBAR several times to water plant!",
requiredHealth: 20,
actionMessage: "Watering plant..",
completedMessage: "Your plant has been watered!");
public static Action RemoveWeed { get; } = new Action(
title: "Press SPACEBAR several times to remove weed!",
requiredHealth: 50,
actionMessage: "Ripping out weeds..",
completedMessage: "Your plant has gotten it's weed removed!");
}
static void Main()
{
string[] flowers = { "Sunflower", "Coleus Tree", "Tomato" };
int[] plant = { 0, 0, 0 };
for (var menuInput03 = 1; menuInput03 <= 2; menuInput03++)
{
var action = menuInput03 switch
{
1 => Action.WaterPlant,
2 => Action.RemoveWeed,
};
Console.Clear();
Console.WriteLine(action.Title);
while (plant[0] < action.RequiredHealth)
{
if (Console.ReadKey().Key != ConsoleKey.Spacebar)
{
Console.Write("\b \b");
continue;
}
plant[0]++;
Console.Clear();
Console.WriteLine(action.Title);
Console.WriteLine(action.ActionMessage);
Console.WriteLine($"[{flowers[0]} {plant[0]}/100]");
}
Console.Clear();
Console.WriteLine(action.CompletedMessage);
Console.WriteLine($"[{flowers[0]} {plant[0]}/100]");
Console.WriteLine("To continue press ENTER.");
while (Console.ReadKey().Key != ConsoleKey.Enter)
{
Console.Write("\b \b");
}
Console.Clear();
}
}

Countdown timer with user input to set time c#

I am trying to build a countdown timer that if the selected choice is set time, it will open and prompts the user to enter value to set the time. once the user is done in typing the numbers, it must show choices like this
Press S to start: Press P to pause
This is what I am lacking, I do not know what to code to enable to pause the time and to start it.
using System;
namespace time_console
{
class Program
{
static void Main(string[] args)
{
designNumbers Fancy = new designNumbers();
Program mainMenu = new Program();
mainMenu.RunMainMenu();
}
private void RunMainMenu()
{
string prompt = "Welcome to Neil's Countdown Timer. Select an option";
string[] options = { "Set Time", "Exit" };
Menu mainMenu = new Menu(prompt, options);
int selectedIndex = mainMenu.Run();
switch (selectedIndex)
{
case 0:
SetTime();
break;
case 1:
Exit();
break;
}
}
private void SetTime()
{
Console.SetCursorPosition(4, 4);
Console.WriteLine("enter time in minutes:seconds ");
Console.SetCursorPosition(4, 5);
int m = Convert.ToInt32(Console.ReadLine());
Console.SetCursorPosition(4, 6);
int s = Convert.ToInt32(Console.ReadLine());
for (; ; )
{
if (s == 0 && m == 0)
{
Console.WriteLine("\nTime's up!");break;
}
if (s == 0)
{
s = 60;
m--;
}
System.Console.Clear();
Console.SetCursorPosition(4, 7);
Console.WriteLine(m + ":" + s--);
System.Threading.Thread.Sleep(1000);
}
WriteLine("Press M to return to Menu");
ConsoleKey a;
ConsoleKeyInfo b = ReadKey(true);
a = b.Key;
if(a == ConsoleKey.M)
{
RunMainMenu();
}
}
private void Exit()
{
WriteLine("press any key to exit...");
ReadKey(true);
Environment.Exit(0);
}
}
}

c# endless method switch loop. Trying to execute the method and end it with a return; statement but it loops back to the begining of the method

I am having an issue where my method is running endlessly i have tested and it runs through the do while loop fine and terminates, but despite it having a return; statement. My program is not ending the method and returning to main.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, What would you like to do?\n1. add a phonebook entry.\n2. search for a specific phonebook entry.\n3. see all phonebook entries.\n4. quit.");
var choice = Console.ReadLine();
int Choice;
var END = "";
do
{
if (int.TryParse(choice, out Choice) && Choice >= 1 && Choice <= 4)
{
switch (Choice)
{
case 1:
addName();
Choice = 0;
break;
case 2:
findName();
break;
case 3:
seeNames();
break;
case 4:
END = "123898761hgasdbfasd";
break;
default:
Console.WriteLine("Hello, What would you like to do?\n1. add a entry.\n2. search for a specific entry.\n3. see all entries.\n4. quit.");
break;
}
}
else { Console.WriteLine("Hello, What would you like to do?\n1. add a entry.\n2. search for a specific entry.\n3. see all entries.\n4. quit.");
choice = Console.ReadLine();
}
}while(END != "123898761hgasdbfasd");
}
private static void seeNames()
{
throw new NotImplementedException();
}
private static void findName()
{
throw new NotImplementedException();
}
private static void addName()
{
int place = 1,end = 0;
string name = null, address = null, numer = null;
do {
switch (place)
{
case 1:
Console.WriteLine("What name would you like to add?");
var User = Console.ReadLine();
Console.WriteLine("You entered {0} is that right?", User);
name = User;
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 2; }
else { place = 1; }
break;
case 2:
Console.WriteLine("What address would you like to add?");
User = Console.ReadLine();
address = User;
Console.WriteLine("You entered {0} is that right?", User);
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 3; } else { place = 2; }
break;
case 3:
Console.WriteLine("What phone number would you like to add?");
User = Console.ReadLine();
Console.WriteLine("You entered {0} is that right?", User);
numer = User;
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 4; } else { place = 3; }
break;
case 4:
using (System.IO.StreamWriter file = new System.IO.StreamWriter("Addressbook.txt", true))
{ file.WriteLine("Name : {0} Address: {1} Phone-Numer: {2}", name, address, numer); file.Close(); }
Console.WriteLine("Would you like to subbmit another entry?");
User = Console.ReadLine();
if (User == "y" || User == "Y") { place = 1; }
else { end = 5; return; }
break;
default:
break;
}
} while (end != 5);
return;
}
}
}
After reaching place 4 and telling the program i do not want to input another address it loops back and ask for another name. I cant seem to break this loop and cause the program to go back to the main program(main is a 4 choice menu that call other methods.)

C# How can i use parameter function in my hangman game

I have been asked by my teacher to store my functions inside a parameter driven function and replacing the switch with an if statement. I have no idea how i am supposed to do this. Any help is appreciated.
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
namespace ConsoleApplication6
{
class Hangman
{
public static int lives = 5;
static string[] wordBank = { "study", "cat", "dress", "shoes", "lipstick" };
static ArrayList wordList = new ArrayList(wordBank);
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Title = "C# Hangman";
Console.WriteLine("Hang man!");
string response = "";
do
{
Console.Write("Enter Command (1. Add Words, 2. List Words , 3. Play , 4. Exit) Pick 1-4: ");
response = Console.ReadLine();
switch (response)
{
case "1":
AddWord();
break;
case "2":
ListWords();
break;
case "3":
Play();
break;
case "4":
break;
}
} while (response != "4");
}
static void AddWord()
{
Console.Write("Enter the word to add: ");
String temp = Console.ReadLine();
wordList.Add(temp);
Console.WriteLine("{0} was added to the dictionary!", temp);
}
static void ListWords()
{
foreach (Object obj in wordList)
Console.WriteLine("{0}", obj);
Console.WriteLine();
}
static void AskLives()
{
try
{
Console.WriteLine("please enter number of lives?");
lives = int.Parse(Console.ReadLine());
}
catch
{
AskLives();
}
}
static void Play()
{
Random random = new Random((int)DateTime.Now.Ticks);
string wordToGuess = wordList[random.Next(0, wordList.Count)].ToString();
string wordToGuessUppercase = wordToGuess.ToUpper();
StringBuilder displayToPlayer = new StringBuilder(wordToGuess.Length);
for (int i = 0; i < wordToGuess.Length; i++)
displayToPlayer.Append('-');
List<char> correctGuesses = new List<char>();
List<char> incorrectGuesses = new List<char>();
bool won = false;
int lettersRevealed = 0;
string input;
char guess;
AskLives();
while (!won && lives > 0)
{
Console.WriteLine("Current word: " + displayToPlayer);
Console.Write("Guess a letter: ");
input = Console.ReadLine().ToUpper();
guess = input[0];
if (correctGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was correct!", guess);
continue;
}
else if (incorrectGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was wrong!", guess);
continue;
}
if (wordToGuessUppercase.Contains(guess))
{
correctGuesses.Add(guess);
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuessUppercase[i] == guess)
{
displayToPlayer[i] = wordToGuess[i];
lettersRevealed++;
}
}
if (lettersRevealed == wordToGuess.Length)
won = true;
}
else
{
incorrectGuesses.Add(guess);
Console.WriteLine("Nope, there's no '{0}' in it!", guess);
lives--;
}
Console.WriteLine(displayToPlayer.ToString());
}
if (won)
Console.WriteLine("You won!");
else
Console.WriteLine("You lost! It was '{0}'", wordToGuess);
Console.Write("Press ENTER to exit...");
Console.ReadLine();
}
}
}
Highlight the switch block and select "Quick Actions."
Rename the function after applying the change.

C# Menu System will not work

I'm not sure how to explain this but I'll try my best since I'm new to c# programming.
I have created a Menu System
string sChoice;
//Menu
Console.WriteLine("1 - Instructions");
Console.WriteLine("2 - New User");
Console.WriteLine("3 - Record & Score");
Console.WriteLine("4 - Exit System");
Console.Write("Please enter your choice between 1-4: ");
sChoice = Console.ReadLine();
Pressing 1 will then take you to the instructions section of the console application and so on.
//Instructions
if (sChoice == "1")
{
Console.WriteLine();
Console.WriteLine("*Instructions*");
Console.WriteLine();
I have tried an else statement which will repeat the menu and prompt the user of an invalid key, however this will only repeat itself another 3 times before closing. Is there a way for me to block any other keys other than 1-4 being entered or a solution to my problem
Because as it seems, if any key other than 1-4 is pressed then the console application will simply close.
This question remembers me when I was young and started programming.
Maybe you want someting like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
while (true)
{
int mainMenuOption = OptionMenu("Instructions", "New User", "Record & Score", "Exit System");
switch (mainMenuOption)
{
case 1: Instructions(); break;
case 2: NewUser(); break;
case 3: RecordAndScore(); break;
case 4: Console.WriteLine("Goodbye.."); return;
}
}
}
static void Instructions()
{
// Handle Instructions here
Console.WriteLine("Instrucctions done");
}
static void NewUser()
{
// Handle New User here
Console.WriteLine("New user done");
}
static void RecordAndScore()
{
// handle recorde and score here
Console.WriteLine("Record & score done");
}
static int OptionMenu(params string[] optionLabels)
{
Console.WriteLine("Please Choose an option");
for (int optionIndex = 0; optionIndex < optionLabels.Length; optionIndex++)
{
Console.Write(optionIndex + 1);
Console.Write(".- ");
Console.WriteLine(optionLabels[optionIndex]);
}
while (true)
{
var input = Console.ReadLine();
int selectedOption;
if (int.TryParse(input, out selectedOption) && selectedOption > 0 && selectedOption <= optionLabels.Length)
{
return selectedOption;
}
else
{
Console.WriteLine("Invalid option, please try again");
}
}
}
}
}

Categories