Positioning the counter, More logic than coding - c#

I am trying to make the users to select a maximum of 4 toppings. Pressing a button they will change the color of the button and add it to a list which will be displayed.Also, the user can delete the topping by pressing again on the same button. I managed to get all of these sorted, the problem is that when the user adds the last topping and the program does not allow him to delete it anymore. I was changing constantly the position of the if statement or the counter but nothing. I presume is a logic problem however I could not find it. Please give me a hand
private void labelTuna_Click(object sender, EventArgs e)
{
if (counter < 4)
{
if (!My_Pizza.Items.Contains(tuna))
{
My_Pizza.Items.Add(tuna);
labelTuna.BackColor = Color.Green;
counter++;
}
else
{
My_Pizza.Items.Remove(tuna);
labelTuna.BackColor = Color.LightSteelBlue;
counter--;
}
}
else
{
MessageBox.Show("You have more than 4 toppings, Remove then replace one");
}

If you want just make your code work this will do.
if ( counter >= 4 && !My_Pizza.Items.Contains(tuna) )
{
MessageBox.Show("You have more than 4 toppings, Remove then replace one");
{
else
{
if (!My_Pizza.Items.Contains(tuna))
{
My_Pizza.Items.Add(tuna);
labelTuna.BackColor = Color.Green;
counter++;
}
else
{
My_Pizza.Items.Remove(tuna);
labelTuna.BackColor = Color.LightSteelBlue;
counter--;
}
}
Your error was not to check if one of the topping preset was the tuna.
Having said that the code is a bit messy even.
You don't need the counter variable, just check My_Pizza.Items.Count
And also as you have written the program you need to write almost duplicate code for each topping.
A function with a parameter will be better.

Related

How to use functions step by step

Sorry for the strange title, I just don't know how to name this question.
So I have such a function say().
void say(string printedText) {
gameText.text = printedText;
}
And I need to use it several times. Something like this:
say("test text 1");
say("test text 2");
say("test text 3");
...
I need to change text by clicking Space button. Of course I need to use something like this:
if(Input.GetKeyDown(KeyCode.Space)) {
...
}
But I can't understand how to show text step by step. So for example if I click Space button once I should see "test text 1". Next click should show me "test text 2" etc.
How can I realise it? Thanks in advance.
Depending on your needs you could store different texts in a List<string> or maybe even Queue<string> and do
List example
// Add your texts in the editor or by calling texts.Add(someNewString)
public List<string> texts = new List<string>();
private int index = 0;
if(Input.GetKeyDown(KeyCode.Space))
{
// have a safety check if the counter is still within
// valid index values
if(texts.Count > index) say(texts[index]);
// increase index by 1
index++;
}
Array example
Basically the same as the List<string> but you can't add or remove elements "on the fly" (at least not that simple)
public string[] texts;
private int index = 0;
if(Input.GetKeyDown(KeyCode.Space))
{
// have a safety check if the counter is still within
// valid index values
if(texts.Length > index) say(texts[index]);
// increase index by 1
index++;
}
Queue example
public Queue<string> texts = new Queue<string>();
for adding a new text to the end of the queue do
texts.Enqueue(someNewString);
and then
if(Input.GetKeyDown(KeyCode.Space))
{
// retrieves the first entry in the queue and at the same time
// removes it from the queue
if(texts.Count > 0) say(texts.Dequeue());
}
Simple counter
If it is really just about having a different int value then yes simply use a field
private int index;
if(Input.GetKeyDown(KeyCode.Space))
{
// uses string interpolation to replace {0} by the value of index
say($"test text {0}", index);
// increase index by one
index++;
}
define a class field like this:
int count = 0;
and now everytime space is hit:
if(Input.GetKeyDown(KeyCode.Space)) {
say("test text " + count);
count = count + 1;
}
This Code:
if(Input.GetKeyDown(KeyCode.Space)) {
...
}
only works for Unity, In Visual Studio you'll have to create an Event to whatever object you want to do this, for example, if you want to call a void each time you press spacebar youll have to do this, it is easy: (Image below)
In the propieties window press the bolt icon and after double click on the event you want to create (samples): TextChanged, LocationChnaged, MouseMove, etc...
I will use KeyDown on the TextBox object
image
Now in your code this void should be generated
image
Inside this void i writed the code and this is how it looks:
(put int n = 1 before voids)
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Space)
{
//int n = 1; must be defined
textBox1.Text = "test text " + n;
n++;
}
}
Now each time you'll press or stay pressed spacebar the textbox will be filled with "test text " and the value will be 1 more each time.

Detecting first or second Mouse Button Release?

I want to know how to detect if the user has released the mouse button the first time, or the times after that:
Pseudo-Code:
if *first* (Input.GetMouseButtonUp(0))
{
do something
}
if *second, third, fourth..etc.* (Input.GetMouseButtonUp(0))
{
do something else
}
I really have no idea on how to accomplish this. I'm sure it's pretty simple though!
This is only an idea, but you could do this using a flag variable, like this:
private static bool WasFirstTimeReleased = false;
if (Input.GetMouseButtonUp(0))
{
if (!WasFirstTimeReleased)
{
WasFirstTimeRelease = true;
//do your stuff for first time
}
else
{
//do your stuff for all other times
}
}
Generally, you have to remember somewhere how many times button was released. Just create field in yours class:
private int clicks = 0;
then:
if (Input.GetMouseButtonUp(0))
{
if(clicks == 0)
{
// do something on first click
}
else
{
// do something on further click
}
clicks++;
}
If the object where you store clicks counter is created each time you press mouse button then mark counter using static word.
Keep track of mouse clicks:
int _leftUp;
void Update()
{
var leftUp = Input.GetMouseButtonUp(0);
if (leftUp) _leftUp++;
// etc ...
}
Easiest way to accomplish this would be to use a counter to check the number of times the user has released the button.
private int releaseCounter = 0;
And then in an if statement:
if (Input.GetMouseButtonUp(0)) {
releaseCounter++;
//If you know on which release you want the code to be executed,
//replace the x with that number.
if (releaseCounter == x) {
//your code here
}
//If you want the code to be executed at set intervals.
//replace the x with the interval number.
if(releaseCounter%x == 0) {
//your code here
}
}
Hope I helped.

Logic trouble with loop

I am creating a windows form that is a random number guessing game. I've made these before in C++ and never had an issue, however I have a big one here- I have no idea how to get the user back to input a number after the loop has began running. Here is my code:
private void btnGuess_Click(object sender, EventArgs e)
{
int guess = 0;
int count = 0;
int accumulator = 0; // accumulator
Random rand = new Random();
int number = rand.Next(1, 100);
txtAnswer.Focus();
while (guess != number)
{
guess = int.Parse(txtAnswer.Text);
if (guess < number)
{
MessageBox.Show("Too Low! Guess again!");
txtAnswer.Text = "";
txtAnswer.Focus();
count++;
accumulator++;
}
else if (guess > number)
{
MessageBox.Show("Too High! Try again!");
txtAnswer.Text = "";
txtAnswer.Focus();
count++;
accumulator++;
}
else
{
MessageBox.Show("Correct! you guessed the number in " + accumulator + " tries!");
break;
}
}
}
}
}
I just filled the while loop arguments with something for you guys, even though i know it won't work. Basically, I need to run the loop, get feedback (if the users guess was too high or low) then get the user to be able to input another number BEFORE the loop runs again. I don't know how to get that to happen with a text box control which is where the input will be. Any ideas?
You should not loop inside in the btnGuess_Click. Instead you need to store the state (the number, count, and the accumulator variables) in the scope of the form itself.
Initialize the random number when the form loads, or using some kind of start button.
Then inside the guess button handler, read the text box value and compare it to the number variable, such as what you are doing currently.
What you are building is more a console style application. So there is 1 main loop that is executing all the code.
In forms applications it is an event driven environment. So the user gets a form, presses a button, the form is evaluated and then the method handling ends.
So you have on a class level some variables for counts, in the constructor you add the initialization and the method for submit will be something like
private void btnGuess_Click(object sender, EventArgs e)
{
//Increment counters
//Check
//Show feedback
//Leave the button click code
}
For some more info, check this out:
https://msdn.microsoft.com/en-us/library/dd492132.aspx

How do I validate text entry to include only numbers?

I want to obligate the person who is using my program to enter only numbers in the text label in c#. How can i do that?
example :
number of equations : (he should only enter a number)
This code to obligate him to enter a number between 2 and 10 but i need a code for letters
if (int.Parse(txt1.Text) < 2 || int.Parse(txt1.Text) > 10)
{
l6.ForeColor = System.Drawing.Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
}
put this (or a variation of this, according to what you want to let the user to enter) in the textbox keypress event, so basically you will manage key presses in this textbox..
Add System.Media library to use the beep if the user enters wrong key, or remove it from the code...
if ((e.KeyChar >= '0') && (e.KeyChar <= '9') && (txt1.Text.Length < 10))
{
}
else if (e.KeyChar == 0x08)
{
//BACKSPACE CHAR
}
else if (txt1.SelectionLength > 0)
{
//IF TEXT SELECTED -> LET IT OVERRIDE
}
else
{
e.Handled = true;
SystemSounds.Beep.Play();
}
if (txt1.Text.Trim().Length > 0)
{
// Parse the value only once as it can be quite performance expensive.
Int32 value = Int32.Parse(txt1.Text)
if ((value >= 2) && (value <= 10))
{
l6.ForeColor = Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
// Clear the text...
txt1.Text = "";
}
else
{
// Your code here...
}
}
But, IMHO, TryParse is even better as it can handle bad string formats in a better way:
if (txt1.Text.Trim().Length > 0)
{
Int32 value;
if (!Int32.TryParse(txt1.Text, out value))
{
l6.ForeColor = Color.Red;
l6.Text = "Svp choisir un nombre entre 2 et 10 ... Soyez Logique!";
// Clear the text...
txt1.Text = "";
}
else
{
// Your code here...
}
}
What GUI do you use?
Using Winforms there are two ways that come to mind:
I recommend: Use a numericUpDown Control instead of a textBox. This way the user can only enter numbers and has nice Up/Down arrows to change the value. Plus you get handling of cursor keys.
Implement an Validating event handler.
Checking the various methods to insert text in a textbox to avoid non number chars is not an easy task and more often than not it fails somewhere. For example what about text pasted from the clipboard?, what about Backspace, Delete, Left, Right arrows keys?.
In my opinion it is better to follow a different approach.
Use the Validating event and let the user type or paste whatever he wants. At the validation event do you checks and advise the user or add a special errorProvider to signal the error:
private void l6_Validating(object sender, CancelEventArgs e)
{
int isNumber = 0;
if (l6.Text.Trim().Length > 0)
{
if (!int.TryParse(l6.Text, out isNumber))
{
e.Cancel = true;
errorProvider1.SetError(l6, "Svp choisir un nombre entre 2 et 10 ...";);
}
else
{
errorProvider1.SetError(l6, "");
}
}
}
}

c# panel image only updates half the time

For my programming class we are required to make a memory match game. When the player clicks on a panel an image is displayed. The player clicks on two panels, if the images match they are removed, if they are different they are turned face down.
The problem I am having with this is that only the image from the first panel gets displayed, even though I am using the same line of code to display the images from both panels, and use Thread.Sleep to pause the program after the second tile has been picked. I don't understand why this is happening, any help would be appreciated.
private void tile_Click(object sender, EventArgs e)
{
string tileName = (sender as Panel).Name;
tileNum = Convert.ToInt16(tileName.Substring(5)) - 1;
//figure out if tile is locked
if (panelArray[tileNum].isLocked == false)
{
pickNum++;
//although the following line of code is used to display the picture that is stored in the tile array
//what is happening is that it will only display the picture of the first tile that has been picked.
//when a second tile is picked my program seems to ignore this line completely, any ideas?
panelArray[tileNum].thisPanel.BackgroundImage = tiles[tileNum].tileImage;
if (pickNum == 1)
{
pick1 = tileNum;
panelArray[tileNum].isLocked = true;
}
else
{
pick2 = tileNum;
UpdateGameState();
}
}
}
private void UpdateGameState()
{
Thread.Sleep(1500);
if (tiles[pick1].tag == tiles[pick2].tag)//compares tags to see if they match.
{
RemoveTiles();
}
else
{
ResetTiles();
}
pickNum = 0;
guess += 1;
guessDisplay.Text = Convert.ToString(guess);
if (correct == 8)
{
CalculateScore();
}
}
try this:
(sender as Panel).BackgroundImage = tiles[tileNum].tileImage;
you have to be sure that your tile_Click method is associated to both panel...

Categories

Resources