I created a menu with sub menus in console. Everything works fine but I wonder if it is not possible to improve the structure of my program. To simplify it and make it more generic.
class MainClass
{
public static void Main(string[] args)
{
MainMenu();
}
public static void MainMenu()
{
Console.WriteLine("Main Menu");
Console.WriteLine("--------------------");
Console.WriteLine("[1] Show activities");
Console.WriteLine("[2] Show teachers");
Console.WriteLine("[3] Show students");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
string choice = Console.ReadLine();
int number;
bool result = Int32.TryParse(choice, out number);
if (result)
{
Console.Clear();
SubMenu(number);
}
else
{
Console.WriteLine("Incorrect choice");
}
}
public static void SubMenu(int mainMenuChoice)
{
switch (mainMenuChoice)
{
case 1:
Console.WriteLine("Activities");
Console.WriteLine("[1] Show all activities");
Console.WriteLine("[2] Find a activity by his code");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 2:
Console.WriteLine("Teachers");
Console.WriteLine("[1] Show all teachers");
Console.WriteLine("[2] Find a teacher by his matricule");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 3:
Console.WriteLine("Students");
Console.WriteLine("[1] Show all students");
Console.WriteLine("[2] Find a student by his matricule");
Console.WriteLine("[3] Return Main Menu");
Console.WriteLine("[4] Exit the program");
Console.WriteLine("--------------------\n");
Console.WriteLine("Please select an option from 1-4\n");
break;
case 4:
Environment.Exit(0);
break;
}
string choice = Console.ReadLine();
int number;
bool result = Int32.TryParse(choice, out number);
if (result)
{
Action(mainMenuChoice, number);
}
else
{
Console.WriteLine("Incorrect choice");
}
}
public static void Action(int menu, int choice)
{
switch (menu)
{
case 1:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
case 2:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
case 3:
switch (choice)
{
case 1:
// Do Stuff
break;
case 2:
// Do Stuff
break;
case 3:
Console.Clear();
MainMenu();
break;
case 4:
Environment.Exit(0);
break;
}
break;
}
}
}
Currently if I have to add a sub menu, I have to add a line to the MainMenu() function, I must add a case in the SubMenu() function and as many as there are choices for this menu in Action().
For only one sub menu it's ok but if I have to add a dozen it quickly becomes unmanageable.
I should probably go through one or more classes but I'm lost on the structure.
I made something quickly to demonstrate one approach to the problem. I commented most of the code, but ask if anything is unclear. The main advantage to me is that you can declare your menus in one place as objects. In my code I have done this explicitly in the Main method, but you could easily write a factory method to generate menus for you.
class Program
{
//represents a line/option in a menu
class MenuItem
{
// displayed in the menu
public string Text { get; set; }
//is there a sub menu
public bool HasSubMenu { get; set; }
// if there's a submenu, what's its id
public int? SubMenuId { get; set; }
//if there isn't a sub menu, what should we do
public Action Action { get; set; }
}
//represents one menu i.e. a collection of options
class Menu
{
public Menu()
{
MenuItems = new List<MenuItem>();
}
public int MenuId { get; set; }
public List<MenuItem> MenuItems { get; set; }
public string Title { get; set; }
public void PrintToConsole()
{
foreach (MenuItem item in MenuItems)
{
Console.WriteLine(MenuItems.IndexOf(item) + " : " + item.Text);
}
}
}
//represents all the menus
class MenuCollection
{
public MenuCollection()
{
Menus = new List<Menu>();
}
public List<Menu> Menus { get; set; }
public void ShowMenu(int id)
{
//get the menu we want to display and call its PrintToConsole method
var currentMenu = Menus.Where(m => m.MenuId == id).Single();
currentMenu.PrintToConsole();
//wait for user input
string choice = Console.ReadLine();
int choiceIndex;
//once we have the users selection make sure its an integer and in range of our menu options
//if not then show an error message and re-display the menu
if (!int.TryParse(choice, out choiceIndex) || currentMenu.MenuItems.Count < choiceIndex || choiceIndex < 0)
{
Console.Clear();
Console.WriteLine("Invalid selection - try again");
ShowMenu(id);
}
else
{
// if the selection is good, then retrieve the corresponding menu item
var menuItemSelected = currentMenu.MenuItems[choiceIndex];
// if there's a sub menu then display it
if (menuItemSelected.HasSubMenu)
{
Console.Clear();
ShowMenu(menuItemSelected.SubMenuId.Value);
}
// otherwise perform whatever action we need
else
{
menuItemSelected.Action();
}
}
}
}
static void Main(string[] args)
{
// build a collection of menus
// can have as deep a structure as you like
// give each menu a unique integer MenuId
// link to other menus by setting HasSubMenu to true, and the SubMenuId to the MenuId of the menu you wish to link to
// or, set HasSubMenu to false, and have an Action performed when the menuitem is selected
MenuCollection collection = new MenuCollection()
{
Menus =
{
new Menu()
{
MenuId = 1,
MenuItems =
{
new MenuItem()
{
Text = "Go to sub menu",
HasSubMenu = true,
SubMenuId = 2
},
new MenuItem()
{
Text = "Print Action",
HasSubMenu = false,
Action = () =>
{
Console.WriteLine("I printed from an action");
}
}
}
},
new Menu()
{
MenuId = 2,
MenuItems =
{
new MenuItem()
{
Text = "Sub menu option 1",
HasSubMenu = false,
Action = () =>
{
Console.WriteLine("Printed from a sub menu");
}
},
new MenuItem()
{
Text = "Back to the top menu",
HasSubMenu = true,
SubMenuId = 1
}
}
}
}
};
collection.ShowMenu(1);
Console.ReadLine();
}
}
I have been making a lot of small CLI tools recently, I only fleshed out Activities, but here's an example of the approach I generally like to take for lots of branching menus/logic:
class Program
{
static T GetChoice<T>(List<Tuple<string, T>> choices)
{
var i = 1;
choices.ForEach(x => Console.WriteLine($"[{i++}]: {x.Item1}"));
var choiceIndex = int.Parse(Console.ReadLine());
return choices[choiceIndex - 1].Item2;
}
static void Main(string[] args)
{
Console.WriteLine("Main Menu: ");
var choices = new List<Tuple<string, Action>>()
{
new Tuple<string, Action>("Show Activities", ShowActivities),
new Tuple<string, Action>("Show Teachers", ShowTeachers),
new Tuple<string, Action>("Show Students", ShowStudents),
new Tuple<string, Action>("Exit", Exit),
};
GetChoice(choices)();
}
static void ShowActivities()
{
Console.WriteLine("Activities: ");
var choices = new List<Tuple<string, Action>>()
{
new Tuple<string, Action>("Show all activities", ShowAllActivities),
new Tuple<string, Action>("Find activity by code", FindActivityByCode),
new Tuple<string, Action>("Return to main menu", () => { Main(null); }),
new Tuple<string, Action>("Exit the program", Exit),
};
GetChoice(choices)();
}
static void ShowTeachers()
{
Console.WriteLine("Teachers: ");
var choices = new List<Tuple<string, Action>>();
}
static void ShowStudents()
{
Console.WriteLine("Students: ");
var choices = new List<Tuple<string, Action>>();
}
static void ShowAllActivities()
{
//Do stuff
}
static void FindActivityByCode()
{
//Do stuff
}
static void ReturnToMainMenu()
{
//Do stuff
}
static void Exit()
{
Environment.Exit(0);
}
}
Related
static void MainWindow()
{
Console.Clear();
Console.WriteLine("Menu");
Console.WriteLine("");
Console.WriteLine("1. Information");
Console.WriteLine("2. Contact");
Console.WriteLine("3. Extra");
Console.WriteLine("q. Exit");
string myOptions;
myOptions = Console.ReadLine();
switch (myOptions)
{
case "1":
Information();
break;
case "2":
Contact();
break;
case "3":
Extra();
break;
case "q":
Exit();
break;
default:
Console.Clear();
Console.WriteLine("Input is wrong");
Console.ReadKey();
MainWindow();
break;
}
Console.ReadLine();
}
I make a console menu and I need a counter that will count wrong entries. if it hits 5 times, the user is thrown back to the main menu.
I was trying to do this with while statement but it didnt work for me.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace ConsoleApp3
{
internal class Program
{
private static readonly IDictionary<char, Action> InputDictionary = new Dictionary<char, Action>
{
{ '1', Information },
{ '2', Contact },
{ '3', Extra },
{ 'q', Exit },
};
static void Main()
{
MainWindow();
}
private static void MainWindow()
{
var inputWasProcessed = false;
while (inputWasProcessed == false)
{
DisplayMainMenu();
var wrongEntries = 0;
while (wrongEntries < 5)
{
if (0 < wrongEntries)
{
Console.WriteLine($"Wrong Entries: {wrongEntries}");
}
inputWasProcessed = ProcessUserInput(Console.ReadKey().KeyChar);
if (inputWasProcessed == false)
{
wrongEntries++;
}
else
{
break;
}
}
}
Console.ReadLine();
}
private static void DisplayMainMenu()
{
Console.Clear();
Console.WriteLine("Menu");
Console.WriteLine();
Console.WriteLine("1. Information");
Console.WriteLine("2. Contact");
Console.WriteLine("3. Extra");
Console.WriteLine("q. Exit");
}
private static bool ProcessUserInput(char selectedOption)
{
if (InputDictionary.TryGetValue(selectedOption, out var action))
{
Console.WriteLine();
Console.WriteLine();
action.Invoke();
return true;
}
Console.Clear();
Console.WriteLine("Input is wrong.");
Console.WriteLine("Try again.");
return false;
}
private static void Information()
{
Console.WriteLine($"{GetCurrentMethod()} implementation.");
}
private static void Contact()
{
Console.WriteLine($"{GetCurrentMethod()} implementation.");
}
private static void Extra()
{
Console.WriteLine($"{GetCurrentMethod()} implementation.");
}
private static void Exit()
{
Console.WriteLine($"{GetCurrentMethod()} implementation.");
}
#region For Demonstration Purposes Only
[MethodImpl(MethodImplOptions.NoInlining)]
private static string GetCurrentMethod() // https://stackoverflow.com/a/2652481/109941
{
var st = new StackTrace();
var sf = st.GetFrame(1);
return sf.GetMethod().Name;
}
#endregion
}
}
I am displaying menu in the console based application using C#. I want that if user press enter key then it should display same menu. Application should not break. I am new to C#
If anyone has idea please share it. It will be helpful to me.
Below is the code.
public static void HospitalMenu()
{
string answer = "";
do
{
Console.Clear();
Console.WriteLine("=============Hospital Management System===================");
Console.WriteLine("1...............Add Patient Information");
Console.WriteLine("2...............Modify Patient Information");
Console.WriteLine("3...............Add Patient Treatment Information");
Console.WriteLine("4...............View Patient History");
Console.WriteLine("5...............Search Patient Info");
Console.WriteLine("6...............Generate Lab Report");
Console.WriteLine("7...............Generate Medical Bills");
Console.WriteLine("8...............Exit");
Console.WriteLine("Select option (between 1 to 8)");
int option = Convert.ToInt32(Console.ReadLine());
switch (option)
{
case 1:
Patient.InsertPatient();
break;
case 2:
Patient.UpdatePatient();
break;
case 3:
PatientTreatment();
break;
case 4:
ViewMenu();
break;
case 5:
SearchMenu();
break;
case 6:
LabMenu();
break;
case 7:
BillMenu();
break;
default:
Environment.Exit(0);
break;
}
Console.WriteLine("Do you want to continue ? (Enter y if yes)");
answer = Console.ReadLine();
} while (answer == "y" || answer == "Y");
}
Thanks in advance.
I'll suggest some changes in your code.
Let's create an Interface that you'll be a contract responsible to show and handle inputs
IMenuHandler.cs
public interface IMenuHandler<TInput>
{
void Show( Action stopApplicationHandler, IMenuHandler<TInput> callerMenu=null);
void HandleInput(TInput input, Action stopApplication, IMenuHandler<TInput> callerMenu);
}
Then let's create your menus.. .
As an example you'll create two, you should modify it for your needs.
MainMenu.cs
public class MainMenu:IMenuHandler<ConsoleKeyInfo>
{
public void Show(Action stopApplicationHandler, IMenuHandler<ConsoleKeyInfo> callerMenu = null)
{
Console.Clear();
Console.WriteLine("=============Hospital Management System===================");
Console.WriteLine("1...............Add Patient Information");
Console.WriteLine("2...............Modify Patient Information");
Console.WriteLine("3...............Add Patient Treatment Information");
Console.WriteLine("4...............View Patient History");
Console.WriteLine("5...............Search Patient Info");
Console.WriteLine("6...............Generate Lab Report");
Console.WriteLine("7...............Generate Medical Bills");
Console.WriteLine("8...............Exit");
Console.WriteLine("Select option (between 1 to 8)");
HandleInput(Console.ReadKey(), stopApplicationHandler, callerMenu ?? this);
}
public void HandleInput(ConsoleKeyInfo input, Action stopApplication, IMenuHandler<ConsoleKeyInfo> callerMenu)
{
switch (input.Key)
{
case ConsoleKey.D1:
new HelpMenu().Show(stopApplication, callerMenu);
break;
case ConsoleKey.D8:
stopApplication.Invoke();
break;
default:
Show(stopApplication, this);
break;
}
}
}
HelpMenu.cs
public class HelpMenu:IMenuHandler<ConsoleKeyInfo>
{
public void Show(Action stopApplicationHandler, IMenuHandler<ConsoleKeyInfo> callerMenu = null)
{
Console.Clear();
Console.WriteLine("Help Menu Example...");
Console.WriteLine("1...............Go back");
Console.WriteLine("2...............Exit");
HandleInput(Console.ReadKey(), stopApplicationHandler, callerMenu );
}
public void HandleInput(ConsoleKeyInfo input, Action stopApplication, IMenuHandler<ConsoleKeyInfo> callerMenu)
{
Console.WriteLine("Help menu handler...");
switch (input.Key)
{
case ConsoleKey.D1:
callerMenu.Show(stopApplication, this);
break;
case ConsoleKey.D2:
stopApplication.Invoke();
break;
default:
Show(stopApplication, callerMenu);
break;
}
}
}
Now we are going to create an wrapper for your application.
Application.cs
public class Application
{
public delegate void OnStopApplicationRequestHandler();
public event OnStopApplicationRequestHandler StopApplicationRequest;
private readonly CancellationTokenSource _cancellationTokenSource;
public Application(CancellationToken? cancellationToken=null, OnStopApplicationRequestHandler? stopApplicationRequestHandler=null)
{
_cancellationTokenSource = cancellationToken != null
? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken.Value)
: new CancellationTokenSource();
StopApplicationRequest += stopApplicationRequestHandler ?? ConfigureDefaultStopApplicationRequestHandler();
}
private OnStopApplicationRequestHandler ConfigureDefaultStopApplicationRequestHandler()
=> () =>
{
Console.WriteLine("Stopping application...");
_cancellationTokenSource.Cancel();
};
public void Run()
{
try
{
while (!_cancellationTokenSource.Token.IsCancellationRequested)
new MainMenu().Show(Stop);
Console.WriteLine("Program has been stopped");
}
//.... You should handle other custom exceptions here
catch (Exception ex)
{
// I'll assume that you will stop your application case it hits this unhandled exception
Console.WriteLine(ex);
Stop();
}
}
private void Stop()
{
StopApplicationRequest?.Invoke();
}
}
Note that this class has an event that will be responsible to handle the application exits.
You should modify it for your needs.
Last but not least
Call your application wrapper in your Program.cs
internal class Program
{
static void Main(string[] args)
{
new Application().Run();
}
}
PS: Don't forget the correct usings....
Hope this helps
A friend and I are doing a programming school project, but we're both new programmers and feel as if we're stuck. For the project we have to create a bank system where you have different options, eg. creating an account, transfering money and so on. However, we're not sure how to utilize the constructor to create an instance of the class. This is what we've got so far.
The constructor and a method for creating an account identifier:
public class Account
{
public int accountID;
public bool accountStatus;
public string[] accountInformation;
private string[] accountSettings;
private string[] debitCardInformation;
private string[] transferHistory;
private double accountBalance;
private double accountLoan;
private double accountDebt;
private double retirementSavings;
public Account(string firstName, string lastName, double startBalance)
{
this.accountID = AccountID();
this.accountStatus = true;
this.accountInformation = new string[] {firstName, lastName};
this.accountSettings = new string[] { };
this.accountBalance = startBalance;
this.accountLoan = 0;
this.accountDebt = 0;
this.retirementSavings = 0;
}
public static int AccountID()
{
Random rn = new Random();
int newAccountID = rn.Next(000000001, 999999999);
return newAccountID;
}
}
The program:
namespace ConsoleApp14
{
class Program
{
static public List<Account> accounts = new List<Account>();
static public int nextID = 0;
static void Main(string[] args)
{
Intro();
Actions();
}
public static void Intro()
{
Console.WriteLine("Please choose one of the following options:\n");
Console.WriteLine("Press '1' to create a new account.");
Console.WriteLine("Press '2' to log in to an existing one.\n");
int accessSystem = Convert.ToInt16(Console.ReadLine());
if (accessSystem == 1)
{
//LogIn();
}
else if (accessSystem == 2)
{
//CreateAccount();
}
else
{
Console.Clear();
Intro();
}
Console.Clear();
}
public static void Actions()
{
Console.WriteLine("Please choose one of the following options:\n");
string[] options = new string[12]
{
"Press '1' to switch between accounts.", "Press '2' to check your balance.", "Press '3' to check your debt.",
"Press '4' to check your loans.", "Press '5' to check your account's status (activated/deactivated).",
"Press '6' to check your account's information.", "Press '7' to check your debit card information.",
"Press '8' to check your account's settings.", "Press '9' to withdraw money.", "Press '10' to transfer money.",
"Press '11' to check your transfer history.", "Press '12' to check your retirement savings."
};
for (int i = 0; i < options.Length; i++)
{
Console.WriteLine(options[i]);
}
Console.WriteLine();
Account test = new Account("Test", "Testerson", 100);
int responseIndex = Convert.ToInt16(Console.ReadLine());
switch (responseIndex)
{
case 1:
//ChangeAccount();
break;
case 2:
//CheckAccountBalance();
break;
case 3:
//CheckAccountDebt();
break;
case 4:
//CheckAccountLoans();
break;
case 5:
//CheckAccountStatus();
break;
case 6:
//CheckAccountInformation();
Console.WriteLine("Endnu ikke implementeret");
break;
case 7:
//CheckDebitCardInformation();
break;
case 8:
//CheckAccountSettings();
break;
case 9:
//WithdrawMoney();
break;
case 10:
//TransferMoney();
break;
case 11:
//CheckTransferHistory();
break;
case 12:
//CheckRetirementSavings();
break;
default:
Console.Clear();
Actions();
return;
break;
}
}
public static void LogIn()
{
}
public static void CreateAccount()
{
}
}
}
I think what you mean is something like this
namespace ConsoltedeTEstes
{
class Program
{
public static void Main(string[] args)
{
//new list of accounts
List<Account> accounts = new List<Account>();
//add a new account on the list
accounts.Add(CreateAccount("first name", "last name", 10));
//Create a single instance using the method
Account accountTeste = CreateAccount("first name", "last name", 15);
}
public static Account CreateAccount(string firstName, string lastName, double startBalance)
{
return new Account(firstName, lastName, startBalance);
}
}
public class Account
{
public int accountID;
public bool accountStatus;
public string[] accountInformation;
private string[] accountSettings;
private string[] debitCardInformation;
private string[] transferHistory;
private double accountBalance;
private double accountLoan;
private double accountDebt;
private double retirementSavings;
public Account(string firstName, string lastName, double startBalance)
{
this.accountID = AccountID();
this.accountStatus = true;
this.accountInformation = new string[] { firstName, lastName };
this.accountSettings = new string[] { };
this.accountBalance = startBalance;
this.accountLoan = 0;
this.accountDebt = 0;
this.retirementSavings = 0;
}
public static int AccountID()
{
Random rn = new Random();
int newAccountID = rn.Next(000000001, 999999999);
return newAccountID;
}
}
}
But note that the Method is literally doing the exact same thing of the constructor
I'm quite new to programming and i'm a bit stuck with my code.
i'm programming a robot and after every position switch i want to write his current position into a ToString method so i can review this afterwards. i'm not sure that a ToString method is the correct way. maybe i need a list or an array?
I'm not asking for the solution, but some help to help me solve this issue.
Thanks for the help!
see my code below:
enum Richting
{
Boven,
Onder,
Links,
Rechts,
}
class Positie
{
public int X { get; set; }
public int Y { get; set; }
public Positie (int x, int y)
{
X = x;
Y = y;
}
}
class Spoor
{
public Robot Robot { get; set; }
public new string ToString()
{
return Robot.Positie.X + "-" + Robot.Positie.Y;
}
public void ToonSpoor()
{
ToString();
}
}
class Robot
{
public Positie Positie { get; set; }
public string Naam { get; set; }
public Robot (string naam, Positie positie1)
{
Naam = naam;
Positie = positie1;
}
public Robot (string naam)
{
Naam = naam;
this.Positie = new Positie(0,0);
}
public Richting Richting;
public virtual void Stap()
{
switch (Richting)
{
case Richting.Boven: Positie.Y++; Spoor.ToString();
break;
case Richting.Onder: Positie.Y--; Spoor.ToString();
break;
case Richting.Links: Positie.X--; Spoor.ToString();
break;
case Richting.Rechts: Positie.X++; Spoor.ToString();
break;
}
}
public virtual void Stap(int aantalStappen)
{
for (int i = 0; i < aantalStappen; i++)
{
switch (Richting)
{
case Richting.Boven:
Positie.Y++;
break;
case Richting.Onder:
Positie.Y--;
break;
case Richting.Links:
Positie.X--;
break;
case Richting.Rechts:
Positie.X++;
break;
}
}
}
public virtual void Draai()
{
switch (Richting)
{
case Richting.Boven: Richting = Richting.Rechts;
break;
case Richting.Onder: Richting = Richting.Links;
break;
case Richting.Links: Richting = Richting.Boven;
break;
case Richting.Rechts: Richting = Richting.Onder;
break;
}
}
public Spoor Spoor { get; set; }
}
class SpecialeRobot : Robot
{
public SpecialeRobot (string naam) : base("")
{
Naam = naam;
this.Positie = new Positie(0, 0);
}
public SpecialeRobot(string naam, Positie positie1) :base("")
{
Naam = naam;
Positie = positie1;
}
public override void Stap()
{
switch (Richting)
{
case Richting.Boven:
Positie.Y = Positie.Y + 2;
break;
case Richting.Onder:
Positie.Y = Positie.Y - 2;
break;
case Richting.Links:
Positie.X = Positie.X - 2;
break;
case Richting.Rechts:
Positie.X = Positie.X + 2;
break;
}
}
public override void Stap(int aantalStappen)
{
for (int i = 0; i < aantalStappen; i++)
{
switch (Richting)
{
case Richting.Boven:
Positie.Y++;
break;
case Richting.Onder:
Positie.Y--;
break;
case Richting.Links:
Positie.X--;
break;
case Richting.Rechts:
Positie.X++;
break;
}
}
}
public override void Draai()
{
switch (Richting)
{
case Richting.Boven:
Richting = Richting.Rechts;
break;
case Richting.Onder:
Richting = Richting.Links;
break;
case Richting.Links:
Richting = Richting.Boven;
break;
case Richting.Rechts:
Richting = Richting.Onder;
break;
}
}
}
class Program
{
static void Main(string[] args)
{
// Aanmaken van een positie-object
Positie positie1 = new Positie(2, 3);
// Aanmaken van een robot
Console.WriteLine("1 ------------------------------------------");
Robot robot1 = new Robot("Bart", positie1);
// ----controles uitvoeren
Console.WriteLine(robot1.Naam == "Bart");
Console.WriteLine(robot1.Positie.X == 2);
Console.WriteLine(robot1.Positie.Y == 3);
Console.WriteLine(robot1.Richting == Richting.Boven);
Console.WriteLine("11 ------------------------------------------");
robot1.Stap();
robot1.Stap();
robot1.Stap();
robot1.Spoor.ToonSpoor(); // 2 - 3 -> 2 - 4 -> 2 - 5
ToString is perfectly ok for your case. But, it's better to override it instead of hiding using the 'new' keyword. So it's better to write:
public override string ToString()
{
return Robot.Positie.X + "-" + Robot.Positie.Y;
}
Also you can see this question that might be useful.
If I understand the question correctly, you want to maintain a log of positions that the robot visited - that is, positions after each call of Robot.Stap()
One way to achieve this is by adding the list of visited positions such as
private List<Positie> visitedPositions;
to the Robot class and adding a record of robot's current position after each call of Robot.Stap()
Then you can get the information about robot's path by outputting the contents of this list.
class Robot
{
private List<Positie> visitedPositions = new List<Positie>();
public void PrintPositions () {
foreach (var pos in visitedPositions) {
Console.WriteLine (pos.X + " " + pos.Y);
}
}
...
public virtual void Stap()
{
switch (Richting)
{
case Richting.Boven: Positie.Y++;
break;
case Richting.Onder: Positie.Y--;
break;
case Richting.Links: Positie.X--;
break;
case Richting.Rechts: Positie.X++;
break;
}
visitedPositions.Add (new Positie (Positie.X, Positie.Y));
}
public virtual void Stap(int aantalStappen)
{
...
visitedPositions.Add (new Positie (Positie.X, Positie.Y));
}
}
class Program
{
static void Main(string[] args)
{
...
Robot robot1;
...
robot1.Stap ();
robot1.PrintPositions ();
}
}
Why not add a private variable inside your Program class and use your class Positie?
You can add this anywhere inside your Program
private Positie position;
Then you can set position it in your Program something like:
class Program
{
private Positie position;
static void Main(string[] args)
{
// Aanmaken van een positie-object
Positie positie1 = new Positie(2, 3);
// Aanmaken van een robot
Console.WriteLine("1 ------------------------------------------");
Robot robot1 = new Robot("Bart", positie1);
// ----controles uitvoeren
Console.WriteLine(robot1.Naam == "Bart");
Console.WriteLine(robot1.Positie.X == 2);
Console.WriteLine(robot1.Positie.Y == 3);
Console.WriteLine(robot1.Richting == Richting.Boven);
Console.WriteLine("11 ------------------------------------------");
robot1.Stap();
position = robot1.Positie; // <- this line
robot1.Stap();
robot1.Stap();
robot1.Spoor.ToonSpoor(); // 2 - 3 -> 2 - 4 -> 2 - 5
therefore, to access your private variable you can directly call position
Console.WriteLine(position.X);
Console.WriteLine(position.Y);
Console.WriteLine("Robot position: (" + position.X.Tostring() + "," + position.X.Tostring() + ")");
EDIT: I just realized that declaring the variable position should be inside Program
I would like to access list (in my program named "section") inside a method(menu choose). I tried 3 ways:
public static void dataBase()
{
List<float> section = new List<float>();
}
// 1st try
// List<float> section = new List<float>();
//
public static void mainMenu()
{
Console.Clear();
Console.WriteLine("Trans->Connector->\n");
Console.WriteLine("Add: \n1. Section \n2. Wled \n3. Regenerator");
menuChoose();
}
public static void menuChoose()
{
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.D1:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
dataBase.section.Add();
section.Add(result);
break;
case ConsoleKey.D2:
Console.WriteLine("2");
break;
case ConsoleKey.D3:
Console.WriteLine("3");
break;
default:
Console.WriteLine("default");
break;
}
}
static void Main(string[] args)
{
int WeldCount;
int ConnectroCount;
//3rd try
// List<float> section = new List<float>();
//
mainMenu();
}
Thank you for your time!
You can't access a member in the local scope of your function outside it. You might want to think about making it a private instance variable inside your class that you will then be able to access from any method declared that belongs to this class, something along these lines:
public class MyClass
{
// this field is accessible from any method declared within this class
private List<Float> section;
public MyClass()
{
section = new List<Float>();
}
private void someMethod()
{
section.Add(2.2);
Console.WriteLine(section[0]); // example
}
}
Well you can make it class level variable (like in your 1st try) and make it static.
However you should use return value from your menuChoose() method. Having all code depend on single static list instance is not ideal.
public static List<float> menuChoose()
{
List<float> selection = new List<float>();
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.D1:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
selection.Add(result);
break;
case ConsoleKey.D2:
Console.WriteLine("2");
break;
case ConsoleKey.D3:
Console.WriteLine("3");
break;
default:
Console.WriteLine("default");
break;
}
return selection;
}
You can to it, if you would implement something like this:
public static class DataBase
{
public static List<float> Section { get; set; }
static DataBase()
{
Section = new List<float>();
}
}
here how to use e.g. in your switch statement:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
DataBase.Section.Add(result);
break;
I didn't get what you try to achieve by dataBase.section.Add(); so I removed it in my example.
I could not use any of your answers so I did this in my way(much worse than yours, for sure)
public class Program
{
public int WeldCount;
public int ConnectroCount;
public List<float> section = new List<float>();
//public List<> TrackElements = new List<>();
public Program()
{
section.Add(0);
}
public void showResults()
{
float allSections = 0;
foreach (float item in section)
{
allSections += item;
}
Console.Clear();
Console.WriteLine("c1 {0}, c2 {1}, c3{2}", WeldCount,ConnectroCount,allSections);
Console.ReadKey();
}
public void finalConstruction()
{
}
public static void mainMenu()
{
Console.Clear();
Console.WriteLine("\n");
Console.WriteLine("Add: \n1. Section \n2. Weld \n3. Regenerator\n4. Show results");
}
public void menuChoose()
{
var key = Console.ReadKey();
switch (key.Key)
{
case ConsoleKey.D1:
case ConsoleKey.NumPad1:
Console.Clear();
Console.WriteLine("Give lenght:");
float result;
float.TryParse(Console.ReadLine(), out result);
section.Add(result);
mainMenu();
menuChoose();
break;
case ConsoleKey.D2:
WeldCount++;
mainMenu();
menuChoose();
break;
case ConsoleKey.D3:
ConnectroCount++;
mainMenu();
menuChoose();
break;
case ConsoleKey.D4:
showResults();
mainMenu();
menuChoose();
break;
default:
Console.WriteLine("wtf did just happend");
break;
}
}
static void Main(string[] args)
{
Program program = new Program();
mainMenu();
program.menuChoose();
}
}
}