Why won't the printing message print in my C# code? - c#

I am trying to print out the message "printing..." to the txtMessage.Text text box before the loop runs but it never does print to the text box before the loop runs. Any idea why?
else
{
txtMessage.Text = "Printing...";
for (int i = numberCopies; i != 0; i--)
{
int paper = Convert.ToInt32(lblPaperAmount.Text);
paper--;
if (paper == 480 || paper == 380 || paper == 400 || paper == 200)
{
MessageBox.Show("There is a paper Jam! Please remove the Jam and then hit the ok button to continue!", "Important Message", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
lblPaperAmount.Text = Convert.ToString(Convert.ToInt32(lblPaperAmount.Text) - 1);
lblTonerAmount.Text = Convert.ToString(Convert.ToInt32(lblTonerAmount.Text) - 1);
Thread.Sleep(1000);
}
txtMessage.Text = "Job is completed!";
}

Try adding a call to Refresh after setting the text. It's possible you're entering the loop quickly enough the refresh does not happen until you exit.
else
{
txtMessage.Text = "Printing...";
txtMessage.Refresh(); //force the control to redraw
for (int i = numberCopies; i != 0; i--)
{
int paper = Convert.ToInt32(lblPaperAmount.Text);
paper--;
if (paper == 480 || paper == 380 || paper == 400 || paper == 200)
{
MessageBox.Show("There is a paper Jam! Please remove the Jam and then hit the ok button to continue!", "Important Message", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
lblPaperAmount.Text = Convert.ToString(Convert.ToInt32(lblPaperAmount.Text) - 1);
lblTonerAmount.Text = Convert.ToString(Convert.ToInt32(lblTonerAmount.Text) - 1);
Thread.Sleep(1000);
}
txtMessage.Text = "Job is completed!";
}

Your code is running in a single thread. You should set your text to "Printing..." then spin off a new thread to do your paper jam for loop.
Please see this question and the top 3 answers.

Related

C# Go to beginning of loop (continue or break?)

This program randomly creates a number between 1 and 50 that the user needs to guess. I want to restart the while loop when the user's guess is incorrect. I have tried using break and continue to do this, but either I am doing it wrong or it is not the best solution. Also, when the user input is incorrect they are asked if they want to guess again. I also tried exiting that loop with break or continue with similar results. Any suggestions?
Console.WriteLine("I am thinking of a whole number between 1 and 50. Enter your guess.");
string userGuess;
Random rnd = new Random();
int compNum = rnd.Next(1, 50);
int guessToInt;
int numOfTries = 0;
string cont;
bool correct = false;
//TODO Delete this line when finished
Console.WriteLine($"Answer " + compNum);
//Trying to get new user input if guess is wrong
while (correct == false)
{
//correct = false;
numOfTries++;
userGuess = Console.ReadLine();
guessToInt = Int32.Parse(userGuess);
if (guessToInt == compNum)
{
numOfTries++;
correct = true;
Console.WriteLine($"Your guess is correct! The number was " + compNum + ". Congratulations. It only took you " + numOfTries + " guess(es).");
}
else if (guessToInt < 1 || guessToInt > 50)
{
Console.WriteLine("Incorrect input. Enter a whole number between 1 and 50. Try again.");
//numOfTries++;
correct = false;
continue;
}
else if (guessToInt != compNum)
{
//How do I get new user input?
Console.WriteLine("Your guess is incorrect. Would you like to try again? Y or N?");
//numOfTries++;
correct = false;
cont = Console.ReadLine();
if (cont == "Y")
{
continue;
}
else Console.WriteLine("Bye."); Environment.Exit(0);
}
}
Few problems:
You don't have to set the boolean to false each time. It is already set to false at start
else Console.WriteLine("Bye."); Environment.Exit(0);
Since you didn't add curly brackets (which I strongly advise you to never do),
Only the first command will operate under the statement.
The "Environment.Exit" will always occur.
For the rest, I added the fixes to your code.
Console.WriteLine("I am thinking of a whole number between 1 and 50. Enter your guess.");
string userGuess;
Random rnd = new Random();
int compNum = rnd.Next(1, 50);
int guessToInt;
int numOfTries = 0;
string cont;
bool correct = false;
//TODO Delete this line when finished
Console.WriteLine($"Answer " + compNum);
//Trying to get new user input if guess is wrong
while (correct == false)
{
//correct = false;
numOfTries++;
userGuess = Console.ReadLine();
guessToInt = Int32.Parse(userGuess);
if (guessToInt == compNum)
{
numOfTries++;
correct = true;
Console.WriteLine($"Your guess is correct! The number was " + compNum + ". Congratulations. It only took you " + numOfTries + " guess(es).");
}
else if (guessToInt < 1 || guessToInt > 50)
{
Console.WriteLine("Incorrect input. Enter a whole number between 1 and 50. Try again.");
//numOfTries++;
//**correct = false; --> No need, correct was already false
//**continue; --> No need, will continue anyway
}
else if (guessToInt != compNum)
{
//How do I get new user input?
Console.WriteLine("Your guess is incorrect. Would you like to try again? Y or N?");
cont = Console.ReadLine();
//numOfTries++;
//**correct = false; --> No need, correct was already false
//** if (cont == "Y") --> No need, will continue anyway
//** {
//** continue;
//** }
// else Console.WriteLine("Bye."); Environment.Exit(0); -->
//** "else" without brackets will
if (cont != "Y")
{
break;
}
Console.WriteLine("Enter your next guess:");
}
}
NOTE: I haven't touched the "numOfTries" feature since not mentioned in the question

MessageBox.Show being displayed too fast

I'm trying to create my own version of "Fleet battle", but I'm stuck at 99.9%. And here is why. After a ship was destroyed, its color should change to red and then a MessageBox "You won" or "You lost" should come. So now, if the AI destroys my last ship, everything is going fine, all the ships are becoming red one by one and then comes this "You lost" message. But in the opposite case - if I win, the AI ships are becoming red, but the last cell of the last ship becomes red after I click "OK" at the MessageBox "You won". I'm using the same algorithm in both cases and wondering what I'm doing wrong with it. Here is the AI part:
// AI hits a ship
if ((arrayOccupiedCellsBattlefield1[rowIndex, columnIndex] == "1") || (arrayOccupiedCellsBattlefield1[rowIndex, columnIndex] == "2") ||
(arrayOccupiedCellsBattlefield1[rowIndex, columnIndex] == "3") || (arrayOccupiedCellsBattlefield1[rowIndex, columnIndex] == "4"))
{
AIHuntingAShip = true;
dataGridView1.Rows[rowIndex].Cells[columnIndex].Value = " X";
arrayShipsHitbyAIMap[rowIndex, columnIndex] = " X"; // AI marks the burning enemy ships
dataGridView1.Rows[rowIndex].Cells[columnIndex].Style.BackColor = Color.Red;
arrayAITakenShots[transformCoordinatesToCellNumber(rowIndex, columnIndex)] = transformCoordinatesToCellNumber(rowIndex, columnIndex);
storeRowIndex = rowIndex;
storeColumnIndex = columnIndex;
arrayShipsHitbyAIXY[detectedShipLength] = transformCoordinatesToCellNumber(rowIndex, columnIndex);
detectedShipLength++;
if (detectedShipLength == int.Parse(arrayOccupiedCellsBattlefield1[rowIndex, columnIndex])) // AI destroys a ship (the array stores the length of the ship in each of the ship's cells)
{
for (int i = 0; i < detectedShipLength; i++) // placing " o"s around the destroyed ship
{
restrictArea(int.Parse(tranformCellNumberToCoordinates(arrayShipsHitbyAIXY[i])[0].ToString()),
int.Parse(tranformCellNumberToCoordinates(arrayShipsHitbyAIXY[i])[1].ToString()),
dataGridView1,
arrayShipsHitbyAIMap,
arrayAITakenShots);
}
detectedShipLength = 0;
AIHuntingAShip = false;
playerShips--;
textBox6.Text = playerShips.ToString();
if (playerShips == 0)
{
MessageBox.Show("You lost!", "Try it again!", MessageBoxButtons.OK);
dataGridView2.Enabled = false;
}
}
and here is my part:
// player hits a ship
if ((arrayOccupiedCellsBattlefield2[e.RowIndex, e.ColumnIndex] != null) && (arrayOccupiedCellsBattlefield2[e.RowIndex, e.ColumnIndex] != " ."))
{
dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = " X";
arrayShipsHitbyPlayerMap[e.RowIndex, e.ColumnIndex] = " X";
dataGridView2.Rows[e.RowIndex].Cells[e.ColumnIndex].Style.BackColor = Color.Red;
arrayPlayerTakenShots[transformCoordinatesToCellNumber(e.RowIndex, e.ColumnIndex)] = transformCoordinatesToCellNumber(e.RowIndex, e.ColumnIndex);
int shipIdent = int.Parse(arrayOccupiedCellsBattlefield2[e.RowIndex, e.ColumnIndex][0].ToString()); // ship ID
int playersShipLength = int.Parse(arrayOccupiedCellsBattlefield2[e.RowIndex, e.ColumnIndex][1].ToString()); // ship length
arrayForPlayersShipsXY[shipIdent] += e.RowIndex.ToString() + e.ColumnIndex.ToString() + ";"; // save the coordinates of this particular ship
arrayForPlayerCounters[shipIdent]++; // increase this particular cell counter basing on the "shipIdent"
if (arrayForPlayerCounters[shipIdent] == playersShipLength) // ship destroyed, so mark the area with " o"
{
for (int i = 0; i < playersShipLength; i++)
{
string xy = extractXYForPlayersShip(arrayForPlayersShipsXY[shipIdent])[i].ToString();
int x = int.Parse(xy.ToString()[0].ToString());
int y = int.Parse(xy.ToString()[1].ToString());
restrictArea(x, y, dataGridView2, arrayShipsHitbyPlayerMap, arrayPlayerTakenShots);
}
AIShips--;
textBox7.Text = AIShips.ToString();
}
if (AIShips == 0)
{
dataGridView2.Enabled = false;
MessageBox.Show("You won!", "Congrats!", MessageBoxButtons.OK);
}
}
Does anybody have an idea? Thank you for your help.
The algorithms might seem the same, but they are not. There is a lot of repeated code, and it is hard to make sure they both do the "same thing". Try and break out parts of this code into smaller methods so you can reuse them.
Without seeing everything, I think this is the issue:
AI:
if (...) //Ship is destroyed
{
// ...
if (ships == 0)
{
MessageBox.Show(...);
}
}
Player
if (...) //ship is destroyed
{
// ...
}
if (ships == 0)
{
MessageBox.Show(...);
}
MessageBox.Show is called inside vs. outside the "ship destroyed" if block.
This question is not exactly the best for StackOverflow because the code is fairly messy and not simplified. Check out this link for how to ask good questions. But keep at it!
As you said both algorithms are equal but windows refresh your form after you hit the 'OK' button.
So I suggest refresh it yourself before displaying msgbox.
if (AIShips == 0)
{
dataGridView2.Refresh(); // <-------- +
dataGridView2.Enabled = false;
MessageBox.Show("You won!", "Congrats!", MessageBoxButtons.OK);
}
Your code is a bit messy I'm not sure about the grid view name, If your problem is about the first one, try this: dataGridView1.Refresh();

How do I get my button to go through it's code again after clicking it once already?

I have a button in my application that is a submit button. This button is supposed to verify the card number entered in the form.
After the third wrong entry the application is supposed to end. All of the necesssary code is there. But when I run it and I put an error in there on purpose, the message box will show, but then when I fix the text box and click the submit button again, nothing happens.
How can I get the button to work again?
private void submitOrderButton_Click(object sender, EventArgs e)
{
counter += 1;
string cardFirstFour = verifyTextBox.Text;
if (counter <= 3)
{
if (verifyTextBox.TextLength == 1298 || verifyTextBox.TextLength == 12765 ||
verifyTextBox.TextLength == 4512 || verifyTextBox.TextLength == 4567 &&
verifyTextBox.TextLength == 8901 || verifyTextBox.TextLength == 8933)
{
if (verifyTextBox.TextLength == 4 || cardTextBox2.TextLength == 4 ||
cardTextBox3.TextLength == 4 || cardTextBox4.TextLength == 4)
{
if (securityCodetextBox.TextLength == 3)
{
if (DateTime.Now.Month < monthNumericUpDown.Value &&
DateTime.Now.Year < yearNumericUpDown.Value)
{
Hide();
confirmation.ShowDialog();
}
else if (counter > 3)
{
this.Hide();
MessageBox.Show("Invalid card info: Too many wrong entries. Order canceled", "Invalid Entry",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Invalid card info: Check your card and try again.", "Invalid Entry",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
}
}
I don't think your if conditions are correct.
You have this
if (counter <= 3) {
...
else if (counter > 3)
...
}
So the else if condition above will never be reached. You should structure it like this:
if (counter <= 3) {
} else if (counter > 3) {
}
Also I would be more specific and rename counter to invalidCounter and only increment it when the information is invalid, not on every button click.

How to count the total amount of integers in a list box and display them into a label C#

Within my system in C# I have a list box that the user can add up to 30 integers into. I have also added 5 different labels, these being: maximum entries allowed:, first value:, middle value:, last value:, and Count:, count being the total amount of integers that are in the list box. I am looking to see how to code these labels so that the values are displayed in each label. Can anyone help? This is the code that I have for the 'Add integer to list box'.
int acceptedNum = 0;
if (txtInsert.Text != "")
{
if (lstIntegers.Items.Contains(txtInsert.Text))
{
if (!(int.TryParse(txtInsert.Text, out acceptedNum) && acceptedNum < 0 || acceptedNum >= 100))
{
lstIntegers.Items.Add(txtInsert.Text);
txtInsert.Clear();
txtInsert.Focus();
bubbleSort();
}
else
{
MessageBox.Show("Please input value between 1-100", "error", MessageBoxButtons.OK);
txtInsert.Text = "";
}
}
else
{
MessageBox.Show("Number already exists in list", "error", MessageBoxButtons.OK);
}
}
else
{
MessageBox.Show("Please input value between 1-100", "error", MessageBoxButtons.OK);
}
if (lstIntegers.Items.Count == 30)
{
MessageBox.Show("Maximum number of entries exceeded", "error", MessageBoxButtons.OK);
//button enabled was false however couldn't then add another
btnInsert.Enabled = true;
}
}
You can use List.Sort to get the correct sort, no need for the bubbleSort method. You can use Enumerable.First,Last and simple math to get the first,last and middle values:
int acceptedNum;
bool validNumber = int.TryParse(txtInsert.Text, out acceptedNum);
if (!validNumber || acceptedNum < 1 || acceptedNum > 100)
{
MessageBox.Show("Please input value between 1-100", "error", MessageBoxButtons.OK);
return;
}
List<int> existingNumbers = lstIntegers.Items.Cast<Object>().Select(System.Convert.ToInt32).ToList();
if (existingNumbers.Contains(acceptedNum))
{
MessageBox.Show("Number already exists in list", "error", MessageBoxButtons.OK);
return;
}
existingNumbers.Add(acceptedNum);
existingNumbers.Sort(); // Quicksort with 30 items
int firstValue = existingNumbers.First();
int lastValue = existingNumbers.Last();
int middleValue = existingNumbers[existingNumbers.Count / 2];
int count = lstIntegers.Items.Count;
int maxNumbers = 30;
if (count == maxNumbers)
{
MessageBox.Show("Maximum number of entries exceeded", "error", MessageBoxButtons.OK);
btnInsert.Enabled = false;
}
lstIntegers.Items.Clear();
lstIntegers.Items.AddRange(existingNumbers.Cast<object>().ToArray());
I've shown you also how to prevent "spaghetticode" by inversing the conditions and returning early.

While Loop Crash in C# game

I am creating a Kinect Text Adventure game for a project. I know the code isn't that great, but the project features more on effects of the game than the game itself, so it doesn't have to be complicated. This section of code is used to progress through the game using certain skeletal positions. The problem I am having is that I am trying to use a while loop so that depending on the current value of f, it will go to that specific room. The only problem is when I use a while loop, it always crashes before it's even started. I'm not sure what the problem is
private void ProcessGesture(Joint head, Joint handleft, Joint handright)
{
while (f!=0)
{
if (handright.Position.Y > head.Position.Y && handleft.Position.Y > head.Position.Y && f == 1)
{
txtBox1.Text = "You find yourself at the foot of a large mountain, with a gaping cave at the front. \nYou have come here to find the Lost Sword of Gaia and you have heard that it lies \nhere in the Cave of Borlak the Red. You can move east";
f = 2;
this.btnangle.Visibility = Visibility.Hidden;
this.slider1.Visibility = Visibility.Hidden;
this.Degree.Visibility = Visibility.Hidden;
this.helpbtn.Visibility = Visibility.Hidden;
}
if (handright.Position.X > 0.3 && f == 2)
{
txtBox1.Text = "You walk up to the entrance of the cave and spot and \nlittle goblin wearing a suit of armour and holding a spear. \n'I'm so bored' he says. 'What I need is a good high five'\nYou can go west";
f = 3;
this.sadGoblin.Visibility = Visibility.Visible;
}
if ((f == 3 && handright.Position.Y > head.Position.Y) || (f == 3 && handleft.Position.Y > head.Position.Y))
{
Uri uri1 = new Uri("/SkeletalTracking;component/Resources/hgoblin.jpg", UriKind.Relative);
ImageSource source1 = new BitmapImage(uri1);
this.sadGoblin.Source = source1;
txtBox1.Text = "'Ah, thank you kind stranger, for that I shall let you in'.\n The goblin steps to the side ";
f = 4;
}
if (f == 4 && handright.Position.Y > head.Position.Y && handleft.Position.Y > head.Position.Y)
{
this.sadGoblin.Visibility = Visibility.Hidden;
txtBox1.Text = "You are now in the main hall of the mountain. You can hear chanting and singing from the north.\nYou see a statue in the middle of the room and two doors to the left and right of it";
f = 5;
}
if (f == 5 && handleft.Position.X < -0.3)
{
txtBox1.Text = "This is Borlak's treasure room. In here are all of the things he has colleted over the years\nSome bought and some not so bought.\nYour eyes are drawn to a necklace in a glass case in the center of the room.\nThere is also a picture of Borlak holding a giant chunk of ham\nYou can go east";
f = 6;
}
if (f == 6 && handright.Position.X > 0.3)
{
f = 5;
}
//else if (f == 5 && handright.Position.X > 0.3)
// {
// txtBox1.Text = "";
// }
}
}
Instead of using a while loop use a switch statement:
int caseSwitch = 1;
switch (caseSwitch)
{
case 1:
Console.WriteLine("Case 1");
break;
case 2:
Console.WriteLine("Case 2");
break;
default:
Console.WriteLine("Default case");
break;
}
Where do you exit the loop? Looks like you're stuck in an infinite loop. Games usually a check like this every update. I don't think you should stay in this loop all in one frame of game play. You should check what f is and decide what to do each frame.
Edit: also, please post what error you get. It would be easier to tell what happens.
In my opinion, take away the while loop, and just let it check 'f' every frame.
The default value of f is 0. If f is not being set ( >=1 ) before this method is called then it would not enter the while loop.
Since all the code isn't shown, and there is no error shown, could "crash" mean immediate exit?

Categories