for loop keeps looping when there is a break - c#

I'm trying to make a carpark program and one of the functions is to move a vehicle. It is working, the object is changing position in the array, it's just that the loop continues and it crashes because parkingLot[i, j].RegNummer is null the second time it loops through it. How do I stop it from looping again after I have "moved" a car? I want it to break and go back to the menu. (This is in a switch case connected to a menu)
Console.WriteLine("Enter the licensenumber of the vehicle that you want to move: ");
string lNumber = Console.ReadLine();
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 2; j++)
{
if (lNumber == parkingLot[i, j].RegNummer)
{
Console.WriteLine("Enter the space you want to move it to: ");
int space = int.Parse(Console.ReadLine());
int space1 = space - 1;
if (parkingLot[space1, 0] == null)
{
parkingLot[space1, 0] = parkingLot[i, j];
parkingLot[i, j] = null;
Console.WriteLine("The vehicle with licensenumber {0} has been moved to space {1}", lNumber, space);
break;
}
}
else
{
Console.WriteLine("The vehicle with licensenumber {0} could not be found!", lNumber);
break;
}
}
}

Your break statements exit the inner for loop, if you need to exit the outer for loop, I'd suggest using a boolean, and checking if it's true to exit the outer loop. When you meet a condition on the inner for loop, set it to true:
string lNumber = Console.ReadLine();
bool exitOuter = false; //Use boolean to exit outer for loop
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 2; j++)
{
if (lNumber == parkingLot[i, j].RegNummer)
{
Console.WriteLine("Enter the space you want to move it to: ");
int space = int.Parse(Console.ReadLine());
int space1 = space - 1;
if (parkingLot[space1, 0] == null)
{
parkingLot[space1, 0] = parkingLot[i, j];
parkingLot[i, j] = null;
Console.WriteLine("The vehicle with licensenumber {0} has been moved to space {1}", lNumber, space);
exitOuter = true; //Set boolean to true to exit outer for loop
break;
}
}
else
{
Console.WriteLine("The vehicle with licensenumber {0} could not be found!", lNumber);
break;
}
}
//Check boolean to break outer for loop
if(exitOuter)
break;
}

So, the problem is that you break just from the inner loop.
if (parkingLot[space1, 0] == null)
{
parkingLot[space1, 0] = parkingLot[i, j];
parkingLot[i, j] = null;
Console.WriteLine("The vehicle with licensenumber {0} has been moved to space {1}", lNumber, space);
break;
}
You must inform the outer loop that the car has been parked and it must end the task.
You can implement a flag for that.
Console.WriteLine("Enter the licensenumber of the vehicle that you want to move: ");
string lNumber = Console.ReadLine();
bool carParked = false;
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 2; j++)
{
if (lNumber == parkingLot[i, j].RegNummer)
{
Console.WriteLine("Enter the space you want to move it to: ");
int space = int.Parse(Console.ReadLine());
int space1 = space - 1;
if (parkingLot[space1, 0] == null)
{
parkingLot[space1, 0] = parkingLot[i, j];
parkingLot[i, j] = null;
Console.WriteLine("The vehicle with licensenumber {0} has been moved to space {1}", lNumber, space);
carParked = true;
break;
}
}
else
{
Console.WriteLine("The vehicle with licensenumber {0} could not be found!", lNumber);
break;
}
}
if (carParked)
{
break;
}
}

Related

C# how to restart the console application

I am a begginer, and Im trying to make a Tic-Tac-Toe console game.But when O player has won, it shows, only when X player has made a decision.So that, there can be a situation when 2 players have won.I tried to use if statement to stop aplication but it doesn't help. I think I don't need to restart the application, just start Main again. But how??
class Program
{
static void Main()
{
string Player1;
string Player2;
int turnPlayer1;
int turnPlayer2;
while (CheckTheWinner() == false)
{
BoardPlay();
Console.Clear();
BoardPlay();
for ( turnPlayer1 = 0; turnPlayer1 < 1; turnPlayer1++)
{
Console.Write("Player O: Choose your field:");
Player1 = Console.ReadLine();
Player1Choice(Player1);
}
CheckTheWinner();
Console.Clear();
BoardPlay();
for (int i = 0; i < 1; i++)
{
Console.Write("Player X: Choose your field:");
Player2 = Console.ReadLine();
Player2choice(Player2);
}
CheckTheWinner();
Console.Clear();
BoardPlay();
}
}
public static void Player1Choice(string P1)
{
string o = "O";
for (int i = 0; i < position.GetLength(0); i++)
{
Console.ForegroundColor = ConsoleColor.Red;
for (int j = 0; j <= 2; j++)
{
if (position[i, j] == P1)
{
position[i, j] = o;
}
}
};
}
public static void Player2choice(string P2)
{
string x = "X";
for (int i = 0; i < position.GetLength(0); i++)
{
Console.ForegroundColor = ConsoleColor.Red;
for (int j = 0; j <= 2; j++)
{
if (position[i, j] == P2)
{
position[i, j] = x;
}
}
};
}
static bool CheckTheWinner()
{
for (int i = 0; i < 3; i++)
{
if (position[i, 0] == position[i, 1] && position[i, 1] == position[i, 2])
{
return true;
}
if (position[0, i] == position[1, i] && position[1, i] == position[2, i])
{
return true;
}
}
if (position[0, 0] == position[1, 1] && position[1, 1] == position[2, 2])
{
return true;
}
if (position[0, 2] == position[1, 1] && position[1, 1] == position[2, 0])
{
return true;
}
return false;
}
"Starting a new game" is basically "repeating the operation of having a game". Use loops to repeat operations.
First, define the loop condition. For example, a boolean flag indicating to keep playing:
var keepPlaying = true;
Then loop as long as that flag is true:
var keepPlaying = true;
while (keepPlaying)
{
// all of the logic currently in your Main method
}
Then all you need to do is prompt the player if they want another game and update the variable accordingly. For example:
var keepPlaying = true;
while (keepPlaying)
{
// all of the logic currently in your Main method
Console.Write("Would you like to play again? (Y/N): ");
var playerReply = Console.ReadLine();
if (playerReply == "N")
keepPlaying = false;
}
You could perhaps simplify the logic a bit, this is mainly for demonstration. You can also add some logic to check the input, you can add a closing message if the player chooses to quit, add other options, etc.
But the point is that if you want to repeat the game, it's not a matter of restarting the application or re-invoking the Main method, it's just a matter of encapsulating what you want to repeat in a loop.

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.

breaks while loop when all die rolls the same number

using System;
using System.Collections.Generic;
namespace AnyDice
{
class Program
{
static void Main(string[] args)
{
int diceSides;
int rollDie;
int count = 0;
bool keepRolling = true;
List<int> num = new List<int>();
Random random = new Random();
Console.Write("Write the number of sides of your die: ");
diceSides = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Type the numbers of the die");
for (int i = 0; i < diceSides; i++)
{
int rank = 1 + i;
Console.Write(rank + "~~> ");
num.Add(Convert.ToInt32(Console.ReadLine()));
}
num.Sort();
Console.WriteLine("\nHere's the die and its contents");
for (int i = 0; i < num.Count; i++)
{
Console.Write("[");
Console.Write(num[i]);
Console.Write("]");
}
Console.WriteLine("\nHow many times do you want to roll at once");
rollDie = Convert.ToInt32(Console.ReadLine());
while (keepRolling)
{
for (int i = 0; i < rollDie; i++)
{
Console.Write("[");
Console.Write(num[random.Next(num.Count)]);
Console.Write("]");
count++;
}
Console.ReadLine();
}
Console.WriteLine("It took you " + count + " attempts");
Console.ReadLine();
}
}
}
For example if (4,4,4,4) is rolled or (2,2) in any "n" number of column the while loop breaks.
I thought of storing each die rolled value in another arraylist and comparing each value in it. If its all equal then it breaks.. but I have no clue on how to implement it.
We have Linq. It lives in the System.Linq namespace and this might help you.
I'll should two ways of checking if all die are the same:
int first = dies.First();
if (dies.All(i => i == first))
{
// break if all are equals to the first die
}
Or using Distinct we can filter out any copies.
if (dies.Distinct().Count() == 1)
{
// if we only have unique items and the count is 1 every die is the same
}
I am not 100% sure I understand your requirement, but in any case, you should write a separate function that returns a flag indicating whether the array is in a state that should trigger a break.
bool KeepRolling(int[] num)
{
for (int i=0; i<num.Length; i++)
{
if (num[i] >= i) return false;
}
return true;
}
Then just call it from within your loop:
keepRolling = KeepRolling(num);
while (keepRolling)
{
rolls.Clear();
for (int i = 0; i < rollDie; i++)
{
var firstRoll = num[random.Next(num.Count)];
rolls.Add(firstRoll);
Console.Write(firstRoll + " ");
count++;
}
if (rolls.Distinct().Count() == 1)
{
Console.WriteLine("It took you " + count + " attempts");
keepRolling = false;
break;
}
Console.ReadLine();
}

How to add elements to an array based on a condition?

I'm working on this simple C# program adding elements to an array. I allow the user to enter 5 numbers, and if the user enters an INVALID valid I have a message for that. My issue is that whether the users enters an invalid number or not I still want to add 5 numbers to my array.
My code works, but let's say the user enters 3 numbers and then 2 words and I end up having ONLY 3 numbers, but I want the 5 numbers no matter what. What am I doing wrong?
Here's my code:
int[] numbers = new int[5];
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Enter a number: ");
string c = Console.ReadLine();
int value;
if (int.TryParse(c, out value))
{
numbers[i] = value;
}
else
{
Console.WriteLine("You did not enter a number\n");
}
}
for (int i = 0; i < numbers.Length; i++ )
{
Console.Write(numbers[i] + " ");
}
You can reduced increment count by 1, when user inputs wrong/no number.
Also note, you are code currently reading input only for 4(not 5 as question description says.) numbers.
int[] numbers = new int[4];
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Enter a number: ");
string c = Console.ReadLine();
int value;
if (int.TryParse(c, out value))
{
numbers[i] = value;
}
else
{
i--;
Console.WriteLine("You did not enter a number\n");
}
}
for (int i = 0; i < numbers.Length; i++ )
{
Console.Write(numbers[i] + " ");
}
try using do-while
int[] numbers = new int[4];
int i = 0;
do
{
Console.WriteLine("Enter a number: ");
string c = Console.ReadLine();
int value;
if (int.TryParse(c, out value))
{
numbers[i] = value;
i++;
}
else
{
Console.WriteLine("You did not enter a number\n");
}
} while (i < 5);
Console.WriteLine("\nYour entered numbers are\n");
for (int j = 0; j < numbers.Length; j++ )
{
Console.Write(numbers[j] + " ");
}
You could use while loop here. See the below code
int[] numbers = new int[5];
int i = 0;
while (i < 5) {
Console.WriteLine ("Enter a number: ");
string c = Console.ReadLine ();
int value;
if (int.TryParse (c, out value)) {
numbers[i] = value;
i++;
} else {
Console.WriteLine ("You did not enter a number\n");
}
}
for (i = 0; i < numbers.Length; i++) {
Console.Write (numbers[i] + " ");
}
You can reduce the code using while loop. Also its better to change the last for loop to foreach
int[] numbers = new int[5];
int i = 0;
while (i < 5)
{
Console.WriteLine("Enter a number: ");
string c = Console.ReadLine();
int value;
if (!int.TryParse(c, out value)) continue;
numbers[i] = value;
i++;
}
foreach (int t in numbers)
Console.Write(t + " ");

Categories