How to determine input when the can have a variable? - c#

I'm working on this commandline based dice. And I want it to be able to output statistics and reset those internal statistics. Currently I have the following classes: Dice and DiceInterface.
I want the user to be able to use the following format for input: "'Throw' to throw the dice, alternate use 'Throw(x)', 'Stat(side)' to see how many times (side) has been thrown, or 'Reset' to reset thrown statistics"
I need a way to determine if the user has typed Throw, Throw(x), Stat(side) or Reset. Throw and Reset are obvious to me but I find it quite difficult to imagine a way to do Throw(x) and Stat(side). Does anyone have any tips or a solution?
Thanks in advance!
using System;
using System.Collections.Generic;
using System.Text;
namespace Oefening_2
{
class DiceInterface
{
static void Main()
{
StartProgram();
}
static void StartProgram()
{
Console.WriteLine("Hello, how many sides would you like the dice to have?");
var input = Console.ReadLine();
if (Int32.TryParse(input, out int number))
{
int desiredSides = number;
Dice NewDice = new Dice(desiredSides);
Console.WriteLine("What would you like to do? ");
Console.WriteLine("Type: 'Throw' to throw the dice, alternate use 'Throw(x)', 'Stat(side)' to see how many times (side) has been thrown, or 'Reset' to reset thrown statistics");
MainIO(NewDice);
}
else
{
Console.WriteLine("That is not an integer! The program will restart now...");
StartProgram();
}
}
static void MainIO(Dice CurrentDice)
{
Console.Write("Input: ");
string input = Console.ReadLine();
//Throw
if (input == "Throw")
{
Console.WriteLine(CurrentDice.Throw());
MainIO(CurrentDice);
}
//Throw(x)
else if(input == "")
//Thrown(side)
//Reset
else if (input == "Reset")
{
CurrentDice.ResetStatistics();
MainIO(CurrentDice);
}
}
}
}
using System;
namespace Oefening_2
{
class Dice
{
public int Sides { get; set; }
private readonly Random _rnd = new Random();
public int[] Thrown;
public Dice(int sides)
{
Sides = sides;
Thrown = new int[sides--];
}
public Dice():this(6)
{
}
public int Throw()
{
int thrownNumber = _rnd.Next(1, Sides);
Thrown[thrownNumber]++;
return thrownNumber;
}
public int NrOfTimesThrown(int side)
{
int result;
result = Thrown[side];
return result;
}
public void ResetStatistics()
{
for(int i = 0 ; i < Sides; i++)
{
Thrown[i] = 0;
}
}
}
}

This can be fairly simply done with StartsWith to check if a string starts with some prefix, and use .Remove to get anything after this prefix:
if(input.StartsWith("Stat"){
var parameterString = input.Remove(0, "Stat".Length);
if(int.TryParse(parameterString , out var side){
...
}
}

If I correctly understood your problem, it could be solved with an approach like this:
Console.WriteLine("Enter a value");
var s = Console.ReadLine();
if(s.Contains('('))
{
int pFrom = s.IndexOf("(");
int pTo = s.LastIndexOf(")");
var myChoice = s.Substring(0, pFrom);
var myValue = s.Substring(pFrom + 1, pTo - pFrom);
Console.WriteLine($"You choosed : {myChoice}");
Console.WriteLine($"With a value of: {myValue}");
}
This is just a brief example of how to "understand" if there is a value and then recover it.
I hope this could help you somehow.

Related

NullReferenceException? Why? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I try to calculate the total collective age of my passengers in calc_total_age() this works before I add a passenger and writes out "0". However when I add a passenger I get NullReferenceException, I have tried different things but I just can't wrap my head around what I'm doing. I need a little shove in the right direction and maybe and explanation of what the he** I am doing and I don't know what my GetAge() does either really I have tried to call it but it doesn't seem to work.
This is all my code:
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program {
public static void Main (string[] args) {
//Console.Clear();
Console.WriteLine("Hi, welcome to the Buss-Simulator!");
Console.ReadKey();
var mybus = new Bus();
mybus.Run();
Console.ReadKey();
}
}
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
class Bus {
public int total_passengers = 0;
public Passenger[] info_passengers;
public int totalAge = 0;
public int totalSeats = 25;
public void Run()
{
info_passengers = new Passenger[25];
string [] menu = new string[]{"1. Pick up passenger.", "2. Show who's on the bus.", "3. Calculate total age of passengers"};
int MenuSelect = 0;
while (true)
{
Console.Clear();
Console.WriteLine("What do you want to do?");
Console.WriteLine();
Console.CursorVisible = false;
if (MenuSelect == 0)
{
Console.WriteLine(menu[0] + " ⭅");
Console.WriteLine(menu[1]);
Console.WriteLine(menu[2]);
}
else if(MenuSelect == 1)
{
Console.WriteLine(menu[0]);
Console.WriteLine(menu[1] + " ⭅");
Console.WriteLine(menu[2]);
}
else if(MenuSelect == 2)
{
Console.WriteLine(menu[0]);
Console.WriteLine(menu[1]);
Console.WriteLine(menu[2] + " ⭅");
}
var keyPressed = Console.ReadKey();
if(keyPressed.Key == ConsoleKey.DownArrow && MenuSelect != menu.Length -1)
{
MenuSelect++;
}
else if (keyPressed.Key == ConsoleKey.UpArrow && MenuSelect >= 1)
{
MenuSelect--;
}
else if (keyPressed.Key == ConsoleKey.Enter)
{
switch (MenuSelect)
{
case 0:
add_passengers();
break;
case 1:
print_passengers();
break;
case 2:
calc_total_age();
break;
}
}
}
}
public void add_passengers()
{
if (total_passengers == 25)
{
Console.WriteLine("\nBus is full!");
System.Threading.Thread.Sleep(2000);
return;
}
try
{
Console.WriteLine("\nType the name, age & gender of your passenger.");
Console.Write("\nName: ");
string name = Console.ReadLine();
Console.Write("\nAge: ");
int age = Convert.ToInt32(Console.ReadLine());
Console.Write("\nGender: ");
string gender = Console.ReadLine();
Passenger passenger = new Passenger(aName: name, aAge: age, aGender: gender);
Array.Resize(ref info_passengers, info_passengers.Length + 1);
info_passengers[info_passengers.Length - 1] = passenger;
}
catch (Exception e)
{
Console.WriteLine("\nFollow instructions.");
System.Threading.Thread.Sleep(2000);
return;
}
total_passengers++;
Console.WriteLine("You boarded 1 Passenger." + "\nThere are " + (totalSeats - total_passengers) + " seats left.");
System.Threading.Thread.Sleep(2000);
return;
}
public void print_passengers()
{
Console.WriteLine();
foreach (var i in info_passengers)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
public void calc_total_age()
{
for (int i = 0; i < total_passengers; i++)
{
totalAge += info_passengers[i].age;
}
Console.WriteLine(totalAge);
Console.ReadKey();
}
}
using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
class Passenger{
public string name;
public int age;
public string gender;
public Passenger(string aName, int aAge, string aGender)
{
name = aName;
age = aAge;
gender = aGender;
}
public override string ToString()
{
return string.Format($"This is {name}, {gender}, {age} years old.");
}
public int GetAge()
{
return age;
}
}
you don't need to resize info_passengers array since it is enough for total passangers. When you add an extra array cell, you add a passanger to the end of arry, but you still have the empty cells in the beginnig of array with null that are causing the exception.
so remove this code
Array.Resize(ref info_passengers, info_passengers.Length + 1);
and fix this
total_passengers++;
info_passengers[ total_passengers-1] = passenger;
and don't forget to remove total_passengers++; from here
Console.WriteLine("You boarded 1 Passenger." + "\nThere are " + (totalSeats - total_passengers) + " seats left.");
and add totalAge=0 in calc_total_age
public void calc_total_age()
{
totalAge=0;
for (int i = 0; i < total_passengers; i++)
{
totalAge += info_passengers[i].age;
}
and it is not a very good idea to hide errors in your catch blok. I would make it
catch (Exception e)
{
Console.WriteLine("\n Error!!! " + e.Message);
System.Threading.Thread.Sleep(2000);
return;
}
The answer to this one is very simple!
You declare:
public Passenger[] info_passengers;
This actually creates a pointer to a Passenger array, which (like all pointers) is initially null. It does not create the actual array itself.
When your code comes to call:
Array.Resize(ref info_passengers, info_passengers.Length + 1);
the method Resize expects the array parameter to point to an array. However, info_passengers is still null. So you get the exception.
I think all you need to do is to initialise info_passengers to an new empty array, like this:
public Passenger[] info_passengers = new Passenger[]();
and then I think it'll all work.

methods program not working of guessing a number

I'm having issues creating a program that is a number guessing program. I think I have the written part right but possibly not the order of it? I have to use multiple methods such as a method for number generator of the number that is supposed to be guessed, a method for collecting the guess input, and method for checking the guess to see if it's right. I've literally have tried just about everything for days but all I get is rather a repeat of, "Enter the number: " even if its right, although it's supposed to repeat if it's too high or low. Or sometimes the console won't print anything. what is wrong? Here is the code:
using System;
namespace GuessTheNumber
{
class Program
{
public static int RandomNumberGenerator()
{
Random random = new Random();
return random.Next(1, 21);
}
public static int InputGetter()
{
Console.Write("Enter in a number: ");
int guess = Convert.ToInt32(Console.ReadLine());
return guess;
}
public static String GuessChecker(int guess, int secretNumber)
{
if(guess > secretNumber)
{
return "Too high!";
}
else if (guess < secretNumber)
{
return "Too low!";
}
else
{
return "Correct";
}
}
static void Main(string[] args)
{
int secretNumber = 10;
Console.WriteLine("" + secretNumber);
while (true)
{
while (InputGetter() != secretNumber)
{
InputGetter();
GuessChecker(InputGetter(), secretNumber);
}
if (GuessChecker(InputGetter(), secretNumber) == ("Correct!"))
{
Console.WriteLine("Would you like to play again?");
String input = Console.ReadLine();
if (GuessChecker(InputGetter(), secretNumber) == ("Yes"))
{
secretNumber = RandomNumberGenerator();
}
else if (GuessChecker(InputGetter(), secretNumber) == ("No"))
{
break;
}
}
}
}
}
}
You are invoking InputGetter() multiple times and your logic is incorrect.
It has nothing to do with Random instance being used.
I have quickly modified your code and it should work now as follows:
New number is generated, if you enter low/high message is displayed, if you enter correct number you are presented with the Would you like to try again message.
EDIT: I did not want to change original code much,In general Comparing strings is bad, you should not use it. Creating enum like and comparing would be much better
class Program
{
public static int RandomNumberGenerator()
{
Random random = new Random();
var generatedNumber = random.Next(1, 21);
Console.WriteLine($"New Number generated! {generatedNumber}");
return generatedNumber;
}
public static int InputGetter()
{
Console.Write("Enter in a number: ");
int guess = Convert.ToInt32(Console.ReadLine());
return guess;
}
public static String GuessChecker(int guess, int secretNumber)
{
if (guess > secretNumber)
{
Console.WriteLine("Too High");
return "Too high!";
}
else if (guess < secretNumber)
{
Console.WriteLine("Too low!");
return "Too low!";
}
else
{
Console.WriteLine("Correct");
return "Correct";
}
}
static void Main(string[] args)
{
int secretNumber = 10;
Console.WriteLine("" + secretNumber);
while (true)
{
int enteredNumber = 0;
do
{
enteredNumber = InputGetter();
} while (GuessChecker(enteredNumber, secretNumber)!="Correct");
Console.WriteLine("Would you like to play again?[Yes/No]");
String input = Console.ReadLine();
if (input=="Yes")
{
secretNumber = RandomNumberGenerator();
}
else
{
break;
}
}
}
}

C# string to array from readline issue

I am doing some C# exercises, the assignment is to check if att Swedish SSN is issued to a woman or a man.
The algorithm checks if the ninth number is equally dividable by 0, then it's a woman or else a man.
If I use a hardcoded "nr" in a string variable, the algorithm works, but if I try to read it from a readline statement, I get the following error:
Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex
This is the code I am using:
//string personnr = "860215-2097";
string personnr = "";
char[] arr;
public void CheckGender(string pnr)
{
arr = personnr.ToCharArray(9, 1);
if (personnr[9] %2 == 0)
{
Console.WriteLine($"Woman!!!");
}
else
{
Console.WriteLine($"Man!!!");
}
}
public void PrintPersonNr()
{
Console.WriteLine("Write a personnr in the format yymmdd-nnnn: ");
string nr = Console.ReadLine();
CheckGender(nr);
}
So it's my PrintPersonNr method that's not working properly I guess..
You can try this:
public enum SSNGender
{
Female,
Male
}
class Program
{
static public Dictionary<SSNGender, string> SSNGenderText
= new Dictionary<SSNGender, string>()
{
{ SSNGender.Female, "Woman" },
{ SSNGender.Male, "Man" },
};
static public SSNGender CheckSSNGender(string pnr)
{
// Here check the validity of the pnr (length, format...)
return pnr[9] % 2 == 0 ? SSNGender.Female : SSNGender.Male;
}
static void Main(string[] args)
{
Console.WriteLine("Write a personnr in the format yymmdd-nnnn: ");
string nr = Console.ReadLine();
var result = CheckSSNGender(nr);
Console.WriteLine(SSNGenderText[result]);
Console.ReadKey();
}
Try following :
public void CheckGender(string pnr)
{
string arr = pnr.Substring(10, 1);
if (arr == "0")
{
Console.WriteLine("Woman!!!");
}
else
{
Console.WriteLine("Man!!!");
}
}
What you need to do is to use the modulus operator and then to check if this number is then divisible by two and if the result is zero then it is even.
There is a fundamental issue as well, you would need to check if the character is a number or not. if it is then the operation would need to then be completed, if not you need to let the user know.
I have modified JDWeng post
public void CheckGender(string pnr)
{
string arr = pnr.Substring(9, 1);
int num =0;
if (int.TryParse(arr, num))
{
if ((num % 2) == "0")
{
Console.WriteLine("Man!!!");
}
else
{
Console.WriteLine("Woman!!!");
}
}
else
{
Console.WriteLine("Not a number!");
}
}
Best of luck in your exercise as well!!!

C# Console.WriteLine not printing in one line

Now if you run this it does not output each Console.WriteLine in one line, why?
I know console.writeline goes to next line when done but the problem is it jumps to next line while printing when it print the exception var it is not in the same line as the rest of the writeline
The error occurs inside the Display() function at the number 6 variable (exception) it is not in the same line as the rest of the writeline, why?
And also there are no line breaks where the error ocurs.
Ans can be any number you like.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace EquationSolver
{
class Program
{
public static string exception = "No Solution Found yet";
public static int go = 40;
public static Decimal x = 0, formul = 0;
public static Decimal pref = -100000, next = 100000,ans;
public static Decimal stepval = next / 10;
public static Decimal prefrem = 1234567890123.1234567890m, nextrem = 1234567890123.1234567890m;
public static Decimal nextremfirst = 0;
public static void Answer()
{
Console.WriteLine("Enter ans");
ans = (Convert.ToDecimal(Console.ReadLine()));
}
public static void Main(string[] args)
{
//Console.WriteLine("Enter ans");
//Answer(Convert.ToDecimal(Console.ReadLine()));
Answer();
//Console.Clear();
while (true)
{
for (var i = 0; i <= go; i++)
{
for (x = pref; x <= next; x += stepval)
{
formul = x;
if (formul < ans)
prefrem = x;
else if (formul > ans)
{
if (nextremfirst == 0)
{
nextrem = x;
nextremfirst += 2;
}
}
else if (formul == ans)
{
AnsFound();
break;
}
else
{
Error();
}
Display();
}
if (formul == ans)
{
AnsFound();
break;
}
if (prefrem != 1234567890123.1234567890m)
pref = prefrem;
if (nextrem != 1234567890123.1234567890m)
next = nextrem;
nextremfirst = 0;
stepval /= 10;
if (formul != ans)
NoAnsyet();
//Console.WriteLine();
}
Finnish();
}
}
public static void Display()
{
//Console.ReadKey();
//Console.WriteLine("Formul: {0} x: {1} Ans: {2} Status: {3}", //formul, x, ans, exception);
//Here is the error:
Console.WriteLine("Pref:{0} Next:{1} Step:{2} Formul:{3} x:{4} Ans:{5} Status:{6}",pref,next,stepval,formul,x,ans,exception);
}
public static void Finnish()
{
if (formul != ans)
Error();
exception = "\ncomplete";
Console.WriteLine(exception);
pref = -100000;
next = 100000;
stepval = next /= 10;
Console.ReadKey();
Console.Clear();
//Console.WriteLine("Enter ans:");
//Answer(Convert.ToDecimal(Console.ReadLine()));
Answer();
}
public static void AnsFound()
{
exception = "\nSolution Found!";
//Console.WriteLine("x: {0} Ans: {1} Status: {2}", x, ans, exception);
//Console.WriteLine("Pref:{0} Next: {1} Stepval: {2} Formul:{3} x:{4} Ans:{5} Status:{}", pref, next, stepval, formul, x, ans, exception);
}
public static void NoAnsyet()
{
exception = "\nNo Solution yet...";
//Console.WriteLine(exception);
}
public static void Error()
{
exception = "\nNo Solution error!!";
Console.WriteLine(exception);
}
}
}
Because you set exception = "\ncomplete"; at different places. The \n at the beginning is a new line character.
Remove the \n
exception = "complete";
Same problem with other texts like "\nSolution Found!".
Using string interpolation makes string formatting more readable:
Replace
Console.WriteLine("Pref:{0} Next:{1} Step:{2} Formul:{3} x:{4} Ans:{5} Status:{6}",
pref, next, stepval, formul, x, ans, exception);
by
Console.WriteLine(
$"Pref:{pref} Next:{next} Step:{stepval} Formul:{formul} x:{x} Ans:{ans} Status:{exception}");
WriteLine writes in a New Line. You should try
Console.Write()
If you want to print right after your previous print.
The value to your variable exception is the reason why the console is printing on a different basically if you put a special character \n means new line hence all the methods you are calling have this special character.
Solution remove special characters and use the Console.WriteLine or Console.Write methods
As per the code provided you have not called the method i made some changes to the code
Edited code
and try to run the code status :No solution found yet
Thanks

C# : Console.Read() does not get the "right" input

I have the following code:
The actual problem is the "non-quoted" code.
I want to get the player amount (max = 4), but when I ask via Console.Read() and I enter any Int from 1 to 4 I get as value: 48 + Console.Read().
They only thing how I can get the "real" input is using Console.ReadLine(), but this does not give me an Integer, no it returns a string, and actually do not know how to convert String (Numbers) to Integers in C#, because I am new, and because I only found ToString() and not ToNumber.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace eve_calc_tool
{
class Program
{
int players;
int units;
int active_units;
int inactive_units;
int finished_units;
int lastDiceNumber = 0;
bool game_state;
public static void Main(string[] args)
{
int count_game = 0;
//Console.Title = "Mensch ärger dich nicht";
//Console.WriteLine("\tNeues Spiel wird");
//Console.WriteLine("\t...geladen");
//System.Threading.Thread.Sleep(5000);
//Console.Clear();
//Console.WriteLine("Neues Spiel wird gestartet, bitte haben sie etwas Geduld");
//Console.Title = "Spiel " + count_game.ToString();
//Console.Clear();
//string prevText = "Anzahl der Spieler: ";
//Console.WriteLine(prevText);
string read = Console.ReadLine();
/*Program game = new Program();
game.players = read;
game.setPlayers(game.players);
if (game.players > 0 && 5 > game.players)
{
game.firstRound();
}*/
string readagain = read;
Console.ReadLine();
}
/*
bool setPlayers(int amount)
{
players = amount;
if (players > 0)
{
return true;
}
else
{
return false;
}
}
bool createGame()
{
inactive_units = units = getPlayers() * 4;
active_units = 0;
finished_units = 0;
game_state = true;
if (game_state == true)
{
return true;
}
else
{
return false;
}
}
int getPlayers()
{
return players;
}
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock (syncLock)
{ // synchronize
return random.Next(min, max);
}
}
int rollDice()
{
lastDiceNumber = RandomNumber(1,6);
return lastDiceNumber;
}
int firstRound()
{
int[] results = new int[getPlayers()];
for (int i = 0; i < getPlayers(); i++)
{
results[i] = rollDice();
}
Array.Sort(results);
return results[3];
}
*/
}
}
You can use
int convertedNumber = int.parse(stringToConvert)
or
int convertedNumber;
int.TryParse(stringToConvert, out covertedNumber)
to convert strings to integers.
You should really use TryParse instead so that you can catch if the user doesn't input a number. int.Parse will throw an exception if it tries to convert a string that is not numeric.
int convertedNumber = 0;
if (!int.TryParse(stringToConvert, out convertedNumber))
{
// this code will execute if the user did not put
// in an actual number. For example, if the user entered "a".
}
The TryParse method returns a boolean value which will tell you whether the conversion was successful. If it was successful, the converted value will be passed through the out parameter.
To convert your string to an integer, use int.Parse(yourString).
The reason you get "48 + Console.ReadKey" is that Console.ReadKey returns the code of the key that was pressed - in this case, the ANSI value of the number character that was pressed.

Categories