Error in parsing an input string to int value in c# - c#

First if works great
Second if throws an exception
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a number and click enter, continue doing this process ");
Console.WriteLine("When you finish, just click enter without giving any input");
int i = 0;
int[] numbersArray;
List<int> numbersList = new List<int>();
while (true)
{
String numInput = Console.ReadLine();
numbersList.Add(Int32.Parse(numInput));
numbersArray = numbersList.ToArray();
if (i >= 1)
{
if (numbersArray[i] < numbersArray[i - 1])
{
Console.WriteLine("Your series is not going up!");
break;
Environment.Exit(0);
}
if (numbersArray[i] > numbersArray[i - 1])
{
if (numInput == "") {
break;
}
}
}
i++;
}
Console.WriteLine("You entered this series: ");
for (int j = 0; j < numbersArray.Length; j++)
{
Console.WriteLine(" " + numbersArray[j]);
}
Console.WriteLine("The length of the series youve entered is: " + numbersArray.Length);
}
}

You can't parse a string wihout digits like numInput = ""
EDIT: Try this code:
static void Main(string[] args)
{
Console.WriteLine("Enter a number and click enter, continue doing this process ");
Console.WriteLine("When you finish, just click enter without giving any input");
int i = 0;
int[] numbersArray = new []{1};
List<int> numbersList = new List<int>();
while (true)
{
String numInput = Console.ReadLine();
if (numInput == null || !numInput.All(char.IsDigit)) continue;
if (numInput != "")
{
numbersList.Add(Int32.Parse(numInput));
numbersArray = numbersList.ToArray();
if (i >= 1)
{
if (numbersArray[i] < numbersArray[i - 1])
{
Console.WriteLine("Your series is not going up!");
break;
Environment.Exit(0); // <-- Code is unreachable!
}
}
i++;
}
else if(i >= 1)
{
break;
}
}
Console.WriteLine("You entered this series: ");
foreach (int t in numbersArray)
{
Console.WriteLine(" " + t);
}
Console.WriteLine("The length of the series youve entered is: " + numbersArray.Length);
Console.ReadLine();
}

I assume you are trying to look at a index not existing.
Not sure of your language but I guess numbersArray[0] is the first index and numbersArray[1] is the second. So when you input your first number then you try to look at numbersArray[1] which doesn't exist.

Related

return and while in function

This function accepting input and telling the user whether the input is number or not a number.
static string isnum()
{
Console.WriteLine("Write a number please");
string a = Console.ReadLine();
string nums = "123456789";
int cnt = 0;
for (int i = 0; i < a.Length; i++)
{
for (int j = 0; j < nums.Length; j++)
{
if (a[i] == nums[j])
{
cnt++;
break;
}
}
}
if (cnt == a.Length)
{
Console.WriteLine(a + " is a number");
return a;
}
else
{
Console.WriteLine(a + " is not a number");
return "";
}
}
isnum();
I would like this function to repeat herself if the input is not a number, till the input will be a number, and then to stop.
This function working now, but she's working only one time.
When I'm trying to add a while block to the function to make her run again and again till the input is number I'm getting the "not all code paths return a value" error.
is it because a "return" statement ends a function, and therefore prevent her to run again?
how can I solve that?
Thank you very much!
You can fix this with creating a loop arround it and do not return when it's not a number.
static string isnum()
{
// just loop forever.
while (true)
{
Console.WriteLine("Write a number please");
string a = Console.ReadLine();
string nums = "123456789";
int cnt = 0;
for (int i = 0; i < a.Length; i++)
{
for (int j = 0; j < nums.Length; j++)
{
if (a[i] == nums[j])
{
cnt++;
break;
}
}
}
if (cnt == a.Length)
{
Console.WriteLine(a + " is a number");
return a;
}
else
{
Console.WriteLine(a + " is not a number");
// don't return here
}
}
}
In this case the best approach is to use do while because you want your code to at least run once.
you have one problem in your code which is returning when variable is not a number. see these modifications:
static string isnum()
{
do{
Console.WriteLine("Write a number please");
string a = Console.ReadLine();
string nums = "123456789";
int cnt = 0;
for (int i = 0; i < a.Length; i++)
{
for (int j = 0; j < nums.Length; j++)
{
if (a[i] == nums[j])
{
cnt++;
break;
}
}
}
if (cnt == a.Length)
{
Console.WriteLine(a + " is a number");
return a;
}
else
{
Console.WriteLine(a + " is not a number");
}
}while(true);
}
Call it in a while loop, and loop until the result is a number:
string result = "";
while (result == "")
{
result = isnum();
}
Console.WriteLine("result is a number: " + result);
Instead of looping you can try querying the a string with a help of Linq:
using System.Linq;
...
static string isnum() {
// Keep asking user until he/she provides a number
while (true) {
Console.WriteLine("Write a number please");
string a = Console.ReadLine();
// Number is
// 1. Has at least one character
// 2. All characters of number are digits
if (a.Length > 0 && a.All(c => c >= '0' && c <= '9')) {
Console.WriteLine($"{a} is a number");
// we have a proper number, let's return int
return a;
}
Console.WriteLine($"{a} is not a number");
}
}

How to make a game move continuously

I'm trying to program a game called NIM (https://plus.maths.org/content/play-win-nim). I've got halfway through, however, when a player makes a move, the board will simply reset to normal for the next move. Any thoughts on how I can make another move to the board and it takes into account the previous move?
static string underline = "\x1B[4m";
static string reset = "\x1B[0m";
static string firstMove;
static bool gameStatus = true;
static void Main(string[] args)
{
Introduction();
InitialBoardSetUp();
PlayingGame();
}
static void Introduction()
{
Console.WriteLine("\t\t\t\t\t" + underline + "Welcome to NIM!\n"+ reset);
Thread.Sleep(1000);
Console.WriteLine(underline + "The rules are as follows:\n" + reset);
Thread.Sleep(1000);
Console.WriteLine(" - Each player takes their turn to remove a certain number of 'blocks' from a stack, of which there are 7.");
Console.WriteLine(" - This happens until there is only 1 'block' remaining. With the winner being the one to remove the last 'block'.\n");
Thread.Sleep(1500);
}
static void InitialBoardSetUp()
{
Console.WriteLine(underline + "This is how the board is formatted:\n" + reset);
Thread.Sleep(750);
Console.Write(" ");
for (int i = 1; i <= 7; i++)
{
Console.Write(" " + i + " ");
}
Console.Write("\n\n");
for (int i = 1; i <= 7; i++)
{
Console.Write(" " + i + " ");
for (int j = 1; j <= 7; j++)
{
Console.Write("███ ");
}
Console.Write("\n");
}
Console.Write("\n\n");
Thread.Sleep(1000);
}
static void WhoGoesFirst()
{
string[] PossibleChoices = { "Computer", "You" };
Random WhoGoesFirst = new Random();
int WGFIndex = WhoGoesFirst.Next(0, 2);
firstMove = PossibleChoices[WGFIndex];
Console.WriteLine("Randomly selecting who goes first...");
Thread.Sleep(1000);
Console.WriteLine("{0} will go first!\n", firstMove);
Thread.Sleep(1000);
}
static void ComputerMove()
{
Random CompStack = new Random();
int CompStackSelection = CompStack.Next(1, 8);
Random CompRemoved = new Random();
int CompRemovedSelection = CompRemoved.Next(1, 8);
Console.WriteLine("Computer is making its move... ");
Thread.Sleep(1000);
Console.WriteLine("Computer has decided to remove {0} blocks from stack number {1}.\n", CompRemovedSelection, CompStackSelection);
Thread.Sleep(1000);
Console.Write(" ");
for (int i = 1; i <= 7; i++)
{
Console.Write(" " + i + " ");
}
Console.Write("\n\n");
for (int i = 1; i <= 7; i++)
{
Console.Write(" " + i + " ");
for (int j = 1; j <= 7; j++)
{
if (j == CompStackSelection && i <= CompRemovedSelection)
{
Console.Write(" ");
}
else
{
Console.Write("███ ");
}
}
Console.Write("\n");
}
Console.Write("\n\n");
Thread.Sleep(1000);
}
static void PlayerMove()
{
Console.Write("Which stack do you wish to remove from?: ");
int PlayerStackSelection = Convert.ToInt32(Console.ReadLine());
// Exception Handling - Can't be greater than 7 or less than 1.
Console.Write("How many blocks do you wish to remove?: ");
int PlayerRemovedSelection = Convert.ToInt32(Console.ReadLine());
// Exception Handling - Can't be greater than 7 or less than 1.
Console.WriteLine();
Console.Write(" ");
for (int i = 1; i <= 7; i++)
{
Console.Write(" " + i + " ");
}
Console.Write("\n\n");
for (int i = 1; i <= 7; i++)
{
Console.Write(" " + i + " ");
for (int j = 1; j <= 7; j++)
{
if (j == PlayerStackSelection && i <= PlayerRemovedSelection)
{
Console.Write(" ");
}
else
{
Console.Write("███ ");
}
}
Console.Write("\n");
}
Console.Write("\n\n");
Thread.Sleep(1000);
}
static void PlayingGame()
{
int gameNumber = 1;
while (gameStatus == true)
{
Console.WriteLine(underline + "Round " + gameNumber+ ":\n" + reset);
WhoGoesFirst();
if (firstMove == "Computer")
{
ComputerMove();
}
else
{
PlayerMove();
}
gameNumber += 1;
playAgain();
}
}
static void playAgain()
{
Console.Write("Do you wish to play again? (Y/N): ");
char playAgain = Convert.ToChar(Console.ReadLine());
Console.WriteLine();
if (playAgain == 'Y')
{
gameStatus = true;
}
else if (playAgain == 'N')
{
gameStatus = false;
}
}
In PlayingGame() you need to create a game loop.
static void PlayingGame()
{
int turn = // randomly choose 0 or 1 (whose turn is it)
bool finished = false;
while(!finished)
{
if(turn==0)
{
ComputerMove();
} else {
PlayerMove();
}
finished = CheckForEndOfGame();
turn = 1 - turn;
}
}
I do strongly suggest to create a Game class that handles the logic of the game and separate the UI (like messages etc) from the game mechanics. This is C# after all, and object oriented approaches are strongly encouraged.
You need to keep track of that game board and whose turn it is and what has been played in this Game class and display on the screen things based on the values (the state) of the game.

Console.ReadLine() not exiting Program in c#

I have an assignment where I have to create code to display factors and whether a number is a perfect and/or prime number. I think I have all the code right to run my program, but when I get to the last line (Console.ReadLine()) I expect to hit enter and then exit the program. Currently, when I hit enter, the program displays whether it is a prime number and/or perfect number over and over again (each time you hit enter). So basically, it executes everything after the while loop over and over again.
Keep in mind, I'm very new to C#, so some of my syntax and readability may be weird. I am only interested in answers that will help me solve the ReadLine issue. My instructors will help me with making my code more readable and organized.
Thanks for your advice! Here is my code. I commented where the ReadLine isn't closing the program:
using System;
namespace Factorizer.UI
{
class Program
{
static void Main(string[] args)
{
string input;
int num, i, x = 0, sum = 0;
while (true)
{
Console.Write("Enter a number: ");
input = Console.ReadLine();
if (int.TryParse(input, out num))
{
Console.Write("\nThe factors are: ");
for (i = 1; i <= num; i++)
{
if (num % i == 0)
{
Console.Write("{0} ", i);
}
}
break;
}
else
{
Console.WriteLine("\nThat was not a valid number!\n");
}
}
for (i = 1; i < num; i++)
{
if (num % i == 0)
{
sum = sum + i;
}
if (sum == num)
{
Console.Write("\n\n{0} is a perfect number.\n", num);
}
else
{
Console.Write("\n\n{0} is not a perfect number.\n", num);
}
for (i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
x++;
break;
}
}
if (x == 0 && num != 1)
{
Console.Write("\n{0} is a prime number.", num);
}
else
{
Console.Write("\n{0} is not a prime number.", num);
}
Console.ReadLine(); //this isn't closing the program!
}
}
}
}
Console.ReadLine() is inside the for loop. Move it down after the next bracket.
Just put Console.ReadLine(); after the for, it's inside the for block that's why it keeps printing and remove the for that you have after the while block, like this:
string input;
int num, i, x = 0, sum = 0;
while (true)
{
Console.Write("Enter a number: ");
input = Console.ReadLine();
if (int.TryParse(input, out num))
{
Console.Write("\nThe factors are: ");
for (i = 1; i <= num; i++)
{
if (num % i == 0)
{
Console.Write("{0} ", i);
}
}
break;
}
else
{
Console.WriteLine("\nThat was not a valid number!\n");
}
}
/*for (i = 1; i < num; i++)
{*/
if (num % i == 0)
{
sum = sum + i;
}
if (sum == num)
{
Console.Write("\n\n{0} is a perfect number.\n", num);
}
else
{
Console.Write("\n\n{0} is not a perfect number.\n", num);
}
for (i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
x++;
break;
}
}
if (x == 0 && num != 1)
{
Console.Write("\n{0} is a prime number.", num);
}
else
{
Console.Write("\n{0} is not a prime number.", num);
}
Console.ReadLine(); //this isn't closing the program!
//}

Is there a way to enter number without showing them immediately?

I want to enter 10 numbers, and then show them in 1 line like this:
1,4,5,2,456,23,... and so on..
and it keeps writing them as I am entering them, and in the end when it's supposed to show all numbers in 1 line it shows only the last one.
I know it's possible with random numbers but when I enter them on my own I don't know how not to show them at all or keep them in 1 line and if it is even possible?
int a;
int x;
Console.WriteLine("a:");
a = int.Parse(Console.ReadLine());
x = 10;
for (int i = 0; i < x; i++)
{
a = int.Parse(Console.ReadLine());
}
Console.ReadKey();
you can use
Console.ReadKey(true)
it reads a key from console and does not show it.
you can use this to read word from console without showing it
public static string ReadHiddenFromConsole()
{
var word = new StringBuilder();
while (true)
{
var i = Console.ReadKey(true);
if (i.Key == ConsoleKey.Enter)
{
Console.WriteLine();
break;
}
if (i.Key == ConsoleKey.Backspace)
{
if (word.Length > 0)
{
word.Remove(word.Length - 1, 1);
Console.Write("\b \b");
}
}
else
{
word.Append(i.KeyChar);
Console.Write("*");
}
}
return word.ToString();
}
You can use this code:
static void Main(string[] args)
{
int length = 10;
int[] myNumbers = new int[length];
for (int i = 0; i < length; i++)
{
Console.Write("Enter number:" );
myNumbers[i] = Convert.ToInt32(Console.ReadLine());
Console.Clear();
}
Console.WriteLine("Your numbers: {0}", string.Join(",", myNumbers));
}
i dont know how to write them at the end all in 1 line?
Well you need to save them as they are entered:
int num;
var nums = new List<int>();
while (nums.Count < 10)
{
Console.Write("Enter: ");
if (int.TryParse(Console.ReadLine(), out num))
{
nums.Add(num);
Console.Clear();
}
}
Console.WriteLine(string.Join(", ", nums));

Keeping track of what the user inputs

This is my hangman code, and its almost good up to the point where it displays the guessed letters. It only displays the most recent guessed letter but I want it to continue on from whats left off. Such as if a person guess "A" and then "L" then Guessed letters are A, L.
I tried using a for loop after "Guessed letters are" but then it gives me the output
"A, A, A, A, A". What should I do to fix this problem?
class Hangman
{
public string[] words = new string[5] { "ARRAY", "OBJECT", "CLASS", "LOOP", "HUMBER" };
public string[] torture = new string[6] { "left arm", "right arm", "left leg", "right leg", "body", "head" };
public char[] guessed = new char[26];
int i;
public void randomizedWord()
{
Random random = new Random();
int index = random.Next(0, 5);
char[] hidden = new char[words[index].Length];
string word = words[index];
Console.WriteLine(words[index]);
Console.Write("The word is: ");
for (i = 0; i < hidden.Length; i++)
{
Console.Write('-');
hidden[i] = '-';
}
Console.WriteLine();
int lives = 6;
do
{
Console.WriteLine("Guess a letter: ");
char userinput = Console.ReadLine().ToCharArray()[0];
index++;
guessed[index] = userinput;
Console.WriteLine("Guessed letters are: " + guessed[index]);
bool foundLetter = false;
for (int i = 0; i < hidden.Length; i++)
{
if (word[i] == userinput)
{
hidden[i] = userinput;
foundLetter = true;
Console.WriteLine("You guessed right!");
}
}
for (int x = 0; x < hidden.Length; x++)
{
Console.Write(hidden[x]);
}
if (!foundLetter)
{
Console.WriteLine(" That is not a correct letter");
lives--;
if (lives == 5)
{
Console.WriteLine("You lost a " + torture[0]);
}
else if (lives == 4)
{
Console.WriteLine("You lost the " + torture[1]);
}
else if (lives == 3)
{
Console.WriteLine("You lost your " + torture[2]);
}
else if (lives == 2)
{
Console.WriteLine("You lost the " + torture[3]);
}
else if (lives == 1)
{
Console.WriteLine("You lost your " + torture[4]);
}
else
{
Console.WriteLine("You lost your " + torture[5]);
Console.WriteLine("You lose!");
break;
}
}
bool founddash = false;
for (int y = 0; y < hidden.Length; y++)
{
if (hidden[y] == '-')
{
founddash = true;
}
}
if (!founddash)
{
Console.WriteLine(" You Win! ");
break;
}
Console.WriteLine();
} while (lives != 0);
}
I was going to post on your other thread Hangman Array C#
Try changing this line
Console.WriteLine("Guessed letters are: " + guessed[index]);
To
Console.WriteLine("Guessed letters are: " + string.Join(" ", guessed).Trim());
I had a play with your hangman game and came up with this solution (while we are doing your homework). Although not related to the question.
public class HangCSharp
{
string[] words = new string[5] { "ARRAY", "OBJECT", "CLASS", "LOOP", "HUMBER" };
List<char> guesses;
Random random = new Random();
string word = "";
string current = "";
int loss = 0;
readonly int maxGuess = 6;
int highScrore = 0;
public void Run()
{
word = words[random.Next(0, words.Length)];
current = new string('-', word.Length);
loss = 0;
guesses = new List<char>();
while (loss < maxGuess)
{
Console.Clear();
writeHeader();
writeLoss();
writeCurrent();
var guess = Console.ReadKey().KeyChar.ToString().ToUpper()[0];
while (!char.IsLetterOrDigit(guess))
{
Console.WriteLine("\nInvalid Guess.. Please enter a valid alpha numeric character.");
Console.Write(":");
guess = Console.ReadKey().KeyChar;
}
while (guesses.Contains(guess))
{
Console.WriteLine("\nYou have already guessed {0}. Please try again.", guess);
Console.Write(":");
guess = Console.ReadKey().KeyChar;
}
guesses.Add(guess);
if (!isGuessCorrect(guess))
loss++;
else if (word == current)
break;
}
Console.Clear();
writeHeader();
writeLoss();
if (loss >= maxGuess)
writeYouLoose();
else
doYouWin();
Console.Write("Play again [Y\\N]?");
while (true)
{
var cmd = (Console.ReadLine() ?? "").ToUpper()[0];
if (cmd != 'Y' && cmd != 'N')
{
Console.WriteLine("Invalid Command. Type Y to start again or N to exit.");
continue;
}
else if (cmd == 'Y')
Run();
break;
}
}
bool isGuessCorrect(char guess)
{
bool isGood = word.IndexOf(guess) > -1;
List<char> newWord = new List<char>();
for (int i = 0; i < word.Length; i++)
{
if (guess == word[i])
newWord.Add(guess);
else
newWord.Add(current[i]);
}
current = string.Join("", newWord);
return isGood;
}
void writeCurrent()
{
Console.WriteLine("Enter a key below to guess the word.\nHint: {0}", current);
if (guesses.Count > 0)
Console.Write("Already guessed: {0}\n", string.Join(", ", this.guesses));
Console.Write(":");
}
void writeHeader()
{
Console.WriteLine("Hang-CSharp... v1.0\n\n");
if (highScrore > 0)
Console.WriteLine("High Score:{0}\n\n", highScrore);
}
void writeYouLoose()
{
Console.WriteLine("\nSorry you have lost... The word was {0}.", word);
}
void doYouWin()
{
Console.WriteLine("Congratulations you guessed the word {0}.", word);
int score = maxGuess - loss;
if (score > highScrore)
{
highScrore = score;
Console.WriteLine("You beat your high score.. New High Score:{0}", score);
}
else
Console.WriteLine("Your score:{0}\nHigh Score:{1}", score, highScrore);
}
void writeLoss()
{
switch (loss)
{
case 1:
Console.WriteLine(" C");
break;
case 2:
Console.WriteLine(" C{0} #", Environment.NewLine);
break;
case 3:
Console.WriteLine(" C\n/#");
break;
case 4:
Console.WriteLine(" C\n/#\\");
break;
case 5:
Console.WriteLine(" C\n/#\\\n/");
break;
case 6:
Console.WriteLine(" C\n/#\\\n/ \\");
break;
}
Console.WriteLine("\n\nLives Remaining {0}.\n", maxGuess - loss);
}
}
Can be run as new HangCSharp().Run();
The index variable is being set to a random number when the random word is selected in this line.
int index = random.Next(0, 5);
Then that index is being used to store the guesses in the do..while loop. However, since index starts from a random number between 0 and 5 you see unexpected behaviour.
Set index to 0 in the line before the do..while loop and the for loop (or the alternatives suggested elsewhere) should work e.g. as so
index = 0;
int lives = 6;
do
{
// rest of the code

Categories