I am trying to make a menu with different options on replit where the user can choose an option.
I am making the options on seperate files, so I later can call for the methods from those files instead of writing everything in the main file.
One of these menuoptions will have an option with a random generator which will generate a random string.
I created the method on another file, But when it gave me an error (7036) when i tried to call it to the main method.
I have pasted an example of the code here below, But you can also access and run the code on this link: https://replit.com/#AY2002/testc22#main.cs Which will be easier to understand. I am a begginer and, Therefore seeking a simple answer.
Thank you!
//MAIN replit FILE
using System;
using System.Collections.Generic;
namespace Namespace1 {
// This is the main file where the menu is built. the menu is working fine.
// the menu have 4 options and an exit option, which will be divided into 4 different replit files and one of them will have a method that randomly generates a string. you can see the method when you scroll down near to the bottom of the main file.
class Program {
public static void Main (string[] args)
{
string[] Menuchoises = new string [] {"Choise1","Choise2","Choise3","Choise4","Choise5"};
int x = 0;
while (true){
Console.Clear();
Console.WriteLine("welcome to menu");
Console.WriteLine();
Console.CursorVisible = false;
if(x == 0) {
Console.WriteLine(" " + Menuchoises[0] + " {");
Console.WriteLine(Menuchoises[1]);
Console.WriteLine(Menuchoises[2]);
Console.WriteLine(Menuchoises[3]);
Console.WriteLine(Menuchoises[4]);
}
else if(x == 1) {
Console.WriteLine(Menuchoises[0]);
Console.WriteLine(" " + Menuchoises[1] + " {");
Console.WriteLine(Menuchoises[2]);
Console.WriteLine(Menuchoises[3]);
Console.WriteLine(Menuchoises[4]);
}
else if(x == 2) {
Console.WriteLine(Menuchoises[0]);
Console.WriteLine(Menuchoises[1]);
Console.WriteLine(" " + Menuchoises[2] + " {");
Console.WriteLine(Menuchoises[3]);
Console.WriteLine(Menuchoises[4]);
}
else if(x == 3) {
Console.WriteLine(Menuchoises[0]);
Console.WriteLine(Menuchoises[1]);
Console.WriteLine(Menuchoises[2]);
Console.WriteLine(" " + Menuchoises[3] + " {");
Console.WriteLine(Menuchoises[4]);
}
else if(x == 4) {
Console.WriteLine(Menuchoises[0]);
Console.WriteLine(Menuchoises[1]);
Console.WriteLine(Menuchoises[2]);
Console.WriteLine(Menuchoises[3]);
Console.WriteLine("\t" + Menuchoises[4] + " {");
}
var key = Console.ReadKey();
if (key.Key == ConsoleKey.DownArrow && x != Menuchoises.Length -1) {
x++;
}
else if (key.Key == ConsoleKey.UpArrow && x>=1) {
x--;
} else if (key.Key == ConsoleKey.Enter) {
switch (x) {
case 0:
Menuchoise1();
break;
case 1:
Menuchoise2();
break;
case 2:
Menuchoise3();
break;
case 3:
Menuchoise4();
break;
case 4:
Menuchoise5();
break;
}
}
}
}
public static void Menuchoise1() {
// Class2.second is the name of the second class which will be the method that will appear when you choose the 1st option in the menu.
// The second class is in the second file which you`ll see below the main file
// The CS 7036 error seems to be appearing here
Class2.second();
Console.Clear();
Console.ReadKey();
}
public static void Menuchoise2() {
Console.Clear();
Console.ReadKey();
}
public static void Menuchoise3() {
Console.Clear();
Console.ReadKey();
}
public static void Menuchoise4() {
Console.Clear();
Console.ReadKey();
}
public static void Menuchoise5() {
Console.Clear();
Console.WriteLine("press enter to exit the menu");
Console.ReadKey();
Console.Clear();
Environment.Exit(1);
}
}
}
// SECOND replit FILE
//this is the second file where i have the random value generator.
using System;
using System.Collections.Generic;
namespace Namespace1 {
// class name of the second file
public class Class2 {
// the string[]args function that will later be put in the main file in order to use this method in the menu
public static string second(string[] Random) {
string[] RandomChoises = new string [4];
// list on options which will be randomly generated
RandomChoises[0] = "C1";
RandomChoises[1] = "C2";
RandomChoises[2] = "C3";
RandomChoises[3] = "C4";
RandomChoises[4] = "C5";
for (int i = 0; i < RandomChoises.Length; i++)
{
Console.WriteLine(RandomChoises[i]);
}
// the choises are randomly generated here
Random rnd = new Random();
int Randomanswer = rnd.Next(1,RandomChoises.Length);
Console.WriteLine("You got the answer: " + RandomChoises[Randomanswer]);
return Convert.ToString(Randomanswer);
}
}
}
As mentioned in the comments, the problem is that the second method takes a parameter, but is not called with one. Since the parameter is not used it should be removed. Cleaning up the class a bit should give you something like:
public static class RandomHelpers{
public static string GetRandomValue() {
// use collection initializer
string[] choices= new []{"C1","C2","C3","C4","C5"}
// use foreach loop
foreach(var choice in choices){
Console.WriteLine(choice );
}
// You should probably not recreate the random object for each method call
// But this should work fine for demonstration purposes
Random rnd = new Random();
// start from zero
int randomIndex = rnd.Next(0,RandomChoises.Length);
var randomValue = choices[randomIndex];
// You should probably just return the random value,
// and let the caller print it to console.
Console.WriteLine("You got the answer: " + randomValue );
// Either return the index as an int, or the value as a string
// Do not convert numbers to strings unless you are writing to the console/file
return randomValue ;
}
}
This should work better. As you get more experience you should find better ways to split functionality into reusable methods.
You have an issue with the way you are defining the array in second.cs. You either need explicitly say how many elements your array will have, like this:
string[] RandomChoice = new string[5];
Or you can leave the number out and let the compiler infer it from the number of elements you put in the {}, like this:
string[] RandomChoises = new string[] { "C1", "C2", "C3", "C4", "C5" };
You can read more details about declaring arrays in C# here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/
After you fix that see JonasH answer about the method parameters in second().
Related
I'm building a program that the dices generates random numbers. I decided to write down in other methods while calling it in the main method. I'm trying to replay the game and break out of the loop by writing in a seperate method. For some reason it won't work and the console shows me an error to which I will show you the picture below.
static void Main(string[] args)
{
Console.WriteLine("Hey! Welcome to Tina's Dice Game");
Console.WriteLine("Let's Start!");
PlayGame();
PlayAgain();
RollDice();
static void PlayGame()
{
while (true)
{
int Dice1 = RollDice();
int Dice2 = RollDice();
Console.WriteLine("Dice 1 = " + Dice1);
Console.WriteLine("Dice 2 = " + Dice2);
Console.WriteLine("I got " + Dice1 + " and " + Dice2);
if (Dice1 % 2 == 0 && Dice2 % 2 == 0)
{
Console.WriteLine("Evens are better than odds");
}
else
{
Console.WriteLine("Odds are still cool.");
}
}
}
}
public static void PlayAgain()
{
Console.WriteLine("Do you want to play it again? (Yes or No)");
string answer = Console.ReadLine();
if (answer == "Yes")
{
PlayGame();
} else
{
break;
}
}
public static Random random = new Random();
public static int RollDice()
{
int Dice = random.Next(2, 4);
return Dice;
}
The console prints out:
The first issue is with you're not closing your Main method.
Add a closing bracket (}) before the static void PlayGame() line (and then remove the extraneous bracket after the PlayGame() function's definition).
You might want to reindent your code (that would have made the error glaringly obvious) - there's surely a menu item for that in your IDE.
Secondly, you can't use break when you're not in a loop; you'd use return to "break out" of a function.
Thirdly, you have an infinite loop without break in your PlayGame() method; you'll never get to that PlayAgain() call.
I sense that you are learning so here I give you something similar to what you appear to be trying. I will annotate with comments in the code but here is a basic rundown:
in the static void Main() you output some text first
Then in my version I create a boolean variable doIt and set it to "true" so that I can use that in the loop; looping until it is no longer true - and since I set it to true initially it does one "game" play with PlayGame();
Next I call the PlayAgain method which I changed to return a boolean from your players answer, setting "doIt" to the value: doIt = PlayAgain();
It starts the while loop again and if doIt is still true, plays again, otherwise it goes to the next statement (the "Goodbye") then returns exiting the program.
I formatted a bit and here is everything with LONG comments:
using System;
public class Program
{
static void Main()
{
Console.WriteLine("Hey! Welcome to Tina's Dice Game");
Console.WriteLine("Let's Start!");
bool doIt = true;
while (doIt)
{
PlayGame();
doIt = PlayAgain();
}
Console.WriteLine("Goodbye!");
return;
}
// here you had PayGame inside Main() so I left it there
// the main difference is I now call it ONLY from Main()
// since the other public methods cannot "see" it
// this fixes one of the issues
static void PlayGame()
{
bool doingWell = true;
while (doingWell)
{
int dice1 = RollDice();
int dice2 = RollDice();
Console.WriteLine("Dice 1 = " + dice1);
Console.WriteLine("Dice 2 = " + dice2);
Console.WriteLine("I got " + dice1 + " and " + dice2);
doingWell = (dice1 % 2 == 0 && dice2 % 2 == 0);
if (doingWell)
{
Console.WriteLine("Evens are better than odds");
}
else
{
Console.WriteLine("Odds are still cool.");
}
}
}
// public method, this returns a boolean from the check: answer == "Yes"
// goAgain is set to the true/false value of the condition it checked,
// returning true only when "Yes" is the answer
// Anything else like "YES","yes", "yep", or "no" returns false
// since this is a case sensitive comparison
// reference: https://learn.microsoft.com/en-us/dotnet/csharp/how-to/compare-strings
public static bool PlayAgain()
{
Console.Write("Do you want to play it again? (Yes or No)");
string answer;
answer = Console.ReadLine();
Console.WriteLine($"You said:{answer}");
var goAgain = answer == "Yes";
return goAgain;
}
// I put the "random" in the roll dice method so we create a new one each time
public static int RollDice()
{
Random random = new Random();
int dice = random.Next(2, 4);
return dice;
}
}
I'm currently in programming 101 and I've been stuck for a long time with an issue.
My assignment wants me to create a class with a bunch of methods to run with a switch case( as a menu).
If I press 1 (add passenger), it does what it's supposed to do the first time, but the second time, it just restarts the array.
I can't seem to save my answer to the array and then move on to the next spot in the array.
Would someone please explain how I'm supposed to "call" the array and save in it outside my for-loop in method add_pass?
using System;
namespace bussen
{
class buss
{
public int[] passagerare;
public int numbof_passagerare;
public void Run()
{
int nmr = 0;
do
{
Console.WriteLine("options:");
Console.WriteLine("1 add passenger");
Console.WriteLine("2 print out all passengers");
Console.WriteLine("3 calc average age");
Console.WriteLine("0 close program");
nmr = int.Parse(Console.ReadLine());
switch (nmr)
{
case 1:add_pass();
break;
case 2:all_pass();
break;
case 3:
break;
case 0:
break;
}
} while (nmr != 0);
}
public void add_pass()
{
if (passagerare.Length < 5)
{
for (int i = 0; i < passagerare.Length; i++)
{
Console.WriteLine("type age of passenger");
int numbof_passenger = int.Parse(Console.ReadLine());
passagerare[i] = numbof_passenger;
break;
}
}
else if(passagerare.Length >= 5)
{
Console.WriteLine("buss is full");
}
}
public void all_pass()
{
foreach(int index in passagerare)
{
Console.WriteLine(index);
}
}
}
class Program
{
static void Main(string[] args)
{
var minbuss = new buss();
minbuss.Run();
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
It's starting over because you're telling it to start over. The for loop starts at 0 every time.
for (int i = 0; i < passagerare.Length; i++)
{
Console.WriteLine("type age of passenger");
int numbof_passenger = int.Parse(Console.ReadLine());
passagerare[i] = numbof_passenger;
break;
}
You need to find the length of the array and append the new entry. Try using a List instead of any array.
The issue was within the add_pass method, where i used a for - loop to add passengers. each time i pressed number 1 in the menu to call the method , the loop restarted the array wich i was saving the integers to.To get this right i just called the method without a loop like shown below. Thanks everybody for your help!
public void add_pass()
{
if (numbof_passagerare < 5)
{
Console.WriteLine("how old is the passenger");
int age = int.Parse(Console.ReadLine());
passagerare[numbof_passagerare++] = age;
}
else if(numbof_passagerare == 5)
{
Console.WriteLine("buss is full!");
}
I'm new to Programming. Now I have to learn C# List Items.
My Expectation:
Create an Empty List
Get the Input value for this list from the user through the console
Window.
My Program:
using System;
using System.Collections.Generic;
namespace Indexof_in_List
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Implementation of IndexOf Method with List");
Console.WriteLine();
//If the user entered empty value or nothing in the console window, the window will exit automatically
//Create an Empty List
List<int> name = new List<int>();
Console.WriteLine("Enter the Input values for the List");
//Get the Inputs for the List from the Console Window
for (int n = 0; n < name.Count; n++)
{
bool check;
string input = Console.ReadLine();
check = int.TryParse(input, out int val);
if (check)
{
name[n] = val;
}
else
{
Environment.Exit(0);
}
}
//Implement Index of any number in the list items which you have entered to the console
Console.WriteLine("The Index of value 10 is = {0}",name.IndexOf(10));
Console.WriteLine();
Console.WriteLine("The Index of value 1000 is ={0}", name.IndexOf(1000));
Console.WriteLine();
Console.ReadKey();
}
}
}
Output:
Could Anyone Tell me the solution for this C# Logic? And also tell me the reason for this failure?
And Tell me, whether my Logic is correct or not?
Your code has a few issues:
Count retrieves the current number of items in your list.
You have created your list using the default constructor, so the Capacity is also 0. Because of this you can't loop from 0 to name.Capacity.
You are trying to add items using an index. You can only access existing items using the name[index] syntax.
The simplest solution is to initialize the list as you are, and simply add items:
List<int> name = new List<int>();
for (int i = 0; i < 10; ++i)
{
bool check;
string input = Console.ReadLine();
check = int.TryParse(input, out int val);
if (check)
{
name.Add(val);
}
else
{
Environment.Exit(0);
}
}
This will read 10 numbers one after the other and add them to the list.
Thank you for your valuable Comments. Finally, I have done the final changes based on your feedback.
My Code:
using System;
using System.Collections.Generic;
namespace Indexof_in_List
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Implementation of IndexOf Method with List");
Console.WriteLine();
//Create an Empty List
List<int> name = new List<int>();
//If the user entered empty value or nothing in the console window, the window will exit automatically
Console.WriteLine("Enter the Input values for the List");
//Get the Inputs for the List from the Console Window
for (int n=0;n<5;n++)
{
bool check=false;
string input = Console.ReadLine();
check = int.TryParse(input, out int val);
if (check)
{
name.Add(val) ;
}
else
{
Environment.Exit(0);
}
}
if (name.Count != 0)
{
//Implement Index of any number in the list items which you have entered to the console
int index1 = name.IndexOf(10);
Console.WriteLine("The Index of value 10 is = {0}", name.IndexOf(10));
if (index1!=-1)
{
Console.WriteLine("The number 10 found in the List");
}
else
{
Console.WriteLine("The Number 10 found in the List");
}
int index2 = name.IndexOf(1000);
Console.WriteLine("The Index of value 1000 is ={0}", name.IndexOf(1000));
if (index2 != -1)
{
Console.WriteLine("The number 1000 found in the List");
}
else
{
Console.WriteLine("The Number 1000 not found in the List");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
So I have a console game application which generates a random string of x length and the user has to input the same random string before time runs out or they lose.The time is just an int which is held in Game class. Here is the class I use to draw the template:
class Template
{
public static void DrawGameplay() //draws gameplay screen , the main method used to print
{
Console.WriteLine("=====================BOMB DEFUSE========================");
if (Game.level < 10)
{
Console.WriteLine("====================== Level {0} =========================", Game.level);
if(Game.level < 6)
{
Body(16);
}
else
{
Body(13);
}
}
else
{
if (Game.level == 10) //10 special case
{
Console.WriteLine("====================== Level {0} ========================", Game.level);
Body(13);
}
else
{
Console.WriteLine("====================== Level {0} ========================", Game.level);
Body(11);
}
}
}
public static void TimeLine() //draws the time line in the middle , feeds drawgameplay
{
Console.WriteLine("");
Console.WriteLine("");
if (Game.time > 9)
{
Console.WriteLine("====================== Time: {0} ========================", Game.time);
}
else
{
Console.WriteLine("====================== Time: {0} =========================", Game.time);
}
Console.WriteLine("");
}
public static void Body(int spaces) //prints everything under the top (game title and lvl) , feeds drawgameplay
{
Console.WriteLine("");
Words.Spaces(spaces);
Game.PrintList();
TimeLine();
Words.Spaces(spaces);
}
}
Then I have this player class:
class Player
{
public static List<char> inputList = new List<char>(); //the list of inputted chars that is used to compare to the defuse code
static char[] arrayChar;
static string typed;
public static void GetInputList() //populates list with letters person typed during time
{
typed = Console.ReadLine();
typed.TrimEnd(); //Gets rid of any extra spaces at the end
arrayChar = typed.ToArray();
inputList = arrayChar.ToList();
}
public static void Print() // prints inputed letters
{
foreach (var letter in inputList)
{
Console.Write(letter);
}
}
}
How do I make it so I can update the time visual as the timer counts down without interfering with the users input? Right now I have the timeline visual in between the randomly generated string and the users input. Thanks for looking.
I tried it only out of curiosity.
Here is a small example how to run a application and get keys entered by user:
static void Main()
{
StringBuilder msg = new StringBuilder(10);
var endTime = DateTime.Now.AddSeconds(10);
while (endTime > DateTime.Now)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo key = Console.ReadKey();
msg.Append(key.KeyChar);
}
Thread.Sleep(1);
Console.Write("\r Enter the message within {0} seconds; message = {1}", (endTime - DateTime.Now).Seconds, msg);
}
}
But remember, there are many problems with this code. The happy scenario will work, but there are many things, that will cause problems (non standard/not expected user behaviour is only one of possible problems).
I'm trying to get a user to input 1 value into the array, and then exit to main menu, then the next person to enter a value gets his put into the next bracket, not replace slot 0, currently it just loops the first array bracket and replaces the number. Help would be much appreciated
static void Main(string[] args)
{
int[] myArray = new int[10];
while (true)
{
int enteredNumber;
Startmenu();
enteredNumber = Convert.ToInt32(Console.ReadLine());
if (enteredNumber == 1)
{
for (int i = 0; i < myArray.Length; i++)
{
Console.WriteLine("Insert Number:");
myArray[i] = Convert.ToInt32(Console.ReadLine());
}
Console.Clear();
Console.WriteLine("blabla");
Thread.Sleep(2000);
Console.Clear();
}
if (enteredNumber == 9)
{
if (Login(1234, 3) == true)
{
foreach (int number in myArray)
{
Console.WriteLine(number);
}
}
}
}
}
One problem I think you have in that code is that you're trying to do too much in one method. You might want to break out discreet operations into separate methods, which will both enable code reuse and also serve to make your code more readable.
First, you need a method that will get an int from the user. Let's write a helper method that does that, which takes in a string that will be displayed as a prompt to the user, and which will continue to prompt them until they enter a valid int. We can use int.TryParse to determine if they enter a valie int. It takes a string argument to parse, and an out int that will contain the parsed value if it succeeds. The method itself returns true if it was successful:
private static int GetIntFromUser(string prompt)
{
int result;
do
{
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out result));
return result;
}
You don't show the code for ShowMenu, but it probably gives the user some menu choices, and I've added the functionality where it returns the menu choice entered by the user:
private static int ShowMenu()
{
int menuChoice;
do
{
Console.Clear();
Console.WriteLine("Main Menu:");
Console.WriteLine("1. Input an array item");
Console.WriteLine("9. Print the numbers\n");
menuChoice = GetIntFromUser("Enter your choice (1 or 9): ");
} while (menuChoice != 1 && menuChoice != 9);
return menuChoice;
}
Now, another thing you seem to be missing that might help here, is to add a "pause" to the program after printing out the array items, so the user has a chance to see them. I think this is probably the main problem. Currently you write them all out to the screen, then the while loop runs again and you don't get a chance to see it. Here's a helper method that asks the user to press a key when they're ready, and then waits for the user to press a key:
private static void WaitForUserInput()
{
Console.Write("\nPress any key to continue...");
Console.ReadKey();
}
We can also put the code to populate the array in a separate method. Since you want to enable the user to populate only one item at a time, we will need to keep track of which item is the next one to populate, so we'll set a class-level variable for that, and make use of it in the method. We'll populate that item, then increment the variable. Of course we have to first make sure the next item is not greater than the number of items available:
private static int NextIndexToPopulate = 0;
private static void PopulateNextArrayItem(int[] array)
{
if (array == null) return;
if (NextIndexToPopulate >= array.Length)
{
Console.WriteLine("The array is full; no items left to enter.");
WaitForUserInput();
}
else
{
array[NextIndexToPopulate] = GetIntFromUser("Enter number to insert: ");
NextIndexToPopulate++;
}
}
And another method can be used to print out the array:
private static void PrintArray(int[] array)
{
if (array == null)
{
Console.WriteLine("The array is null - nothing to print.");
}
else
{
Console.WriteLine("Here are the array items entered:");
for (int i = 0; i < NextIndexToPopulate; i++)
{
Console.WriteLine(array[i]);
}
}
}
You also didn't show the Login code, so here's a dummy method I'll use that always returns true:
private static bool Login(int first, int second)
{
return true;
}
Now, with all that extra stuff encapsulated in methods, our main code becomes a little more readable, there's less chance for errors, and when there are errors, it's more clear what they are:
private static void Main()
{
int[] myArray = new int[10];
while (true)
{
int enteredNumber = ShowMenu();
if (enteredNumber == 1)
{
PopulateNextArrayItem(myArray);
}
else if (enteredNumber == 9)
{
if (Login(1234, 3))
{
PrintArray(myArray);
WaitForUserInput();
}
}
}
}