Logic trouble with loop - c#

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

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.

NumericUpDown ValueChanged preventDefault?

I want to create a form that allows the user to set a certain amount of points in five different fields (NumericUpDown). When that amount of points reaches 0, the user can't add any more. (I still want the user to be able to remove points, though.)
Here is my code so far:
private void calculateValue() {
decimal tempValue = CMB_num_Aim.Value + CMB_num_Reflexes.Value +
CMB_num_Positioning.Value + CMB_num_Movement.Value + CMB_num_Teamwork.Value;
controlValue = currentValue - tempValue;
MyBox.CMB_tb_cv.Text = controlValue.ToString();
}
This Method (calculateValue) is calculates how many points the user have left (controlValue).
private void CMB_num_Aim_ValueChanged(object sender, EventArgs e) {
calculateValue();
if (controlValue < 0) {
//Prevent Default here
MessageBox.Show("You are out of points!");
}
}
This method (CMB_num_Aim_ValueChanged) fires when the value of the NumericUpDown control has changed. I have one of these for each field, each doing the same thing.
The method fires as expected, but I can't prevent it from happening - the user can apply more points than they have. How can I prevent the user from applying more points?
(I thought about making a mouseUp method, but I don't know if the user will use the mouse or if he will type in the value using the keyboard.)
Seems like you want to create a point distribution system between some skills - aim, movement, teamwork etc. You can do that easily by setting Maximum value of NumericUpDown control when you enter it. Subscribe all skill updown controls to the same event handler:
private void SkillNumericUpDown_Enter(object sender, EventArgs e)
{
var skill = (NumericUpDown)sender;
var availablePoints = 42;
var maxSkillPoints = 20; // usually you cannot assign all points to one skill
var unassignedPoints = availablePoints - SkillPointsAssigned;
skill.Maximum = Math.Min(maxSkillPoints, unassignedPoints + skill.Value);
if (unassignedPoints == 0)
{
MessageBox.Show("You are out of points!");
return;
}
if (skill.Value == maxSkillPoints)
{
MessageBox.Show("Skill maximized!");
return;
}
}
private decimal SkillPointsAssigned =>
CMB_num_Aim.Value +
CMB_num_Reflexes.Value +
CMB_num_Positioning.Value +
CMB_num_Movement.Value +
CMB_num_Teamwork.Value;
Benefit - you will not be able to input illegal value neither by arrows nor manually.
Replace
if (controlValue < 0) {
By
if (controlValue <= 0) {

Random number generator Issue

First off I want to say that I am still a beginner with C#, so when explaining information to me, please do not use complex jargon that I will not understand.
Second, I have done most of the work and I am not asking for others to finish my work, I am just asking for help because I do not understand what is wrong/why it is not working.
Third, my program is incomplete, and I cannot finish it unless my random generator is working.
So with that being said, the issue that I am having is when I try to run the program, the system underlines the word "random" in the beginning of my code and says
"A field initializer cannot reference the non-static field, method, or
property".
Why is it doing this? If I put the two line of code inside "Public Guess()" part then the compiler runs fine, it just then says my "if" statement wont work because the container "random" doesn't exist. I'm not sure of what else I could do and I would really, really, appreciate some help.
My code is as follows:
public partial class Guess : Form
{
/*This is a "Guess the number" program. Then this program is run,
* I want to create two containers for the "TryParse" portion of this program
and then I want a number to be randomly generated for the user to guess, then
I want one last container to count how many guess it took the user.*/
string number;
int guess;
Random random;
int randomnumber;
int counter;
public Guess()
{
/*Once the program is initalized, I want the 2nd button hidden until the first one
is clicked with a value in the textbox*/
InitializeComponent();
btnexe2.Hide();
random = new Random();
randomnumber = random.Next(0, 101);
}
private void btnClose_Click(object sender, EventArgs e)
{
//This closes the program//
Close();
}
private void btnexe1_Click(object sender, EventArgs e)
{
/*This is where I will be doing most of my variable checking. First,
I want to check if the user left the textbox empty, if it is then
display a message box saying to enter a number.*/
if (string.IsNullOrEmpty(tbnumber.Text))
{
MessageBox.Show("Please enter a number from 0-100.");
}
else
{/*If it is not empty, then I want the system to determine if the variable
that has been entered can be converted to a int.*/
number = Convert.ToString(tbnumber.Text);
if (Int32.TryParse(number, out guess))
{
/*If the value can be converted, then i want the system to see if
it is lower, higher, or equal to the random value. Then I want the fist button hidden,
and the second one shown. Then I want to record how many times the user guessed.*/
if (guess < randomnumber)
{
btnexe1.Hide();
btnexe2.Show();
this.BackColor = System.Drawing.Color.LightSeaGreen;
lbloutput.Text = "Too Low";
counter=counter + 1;
}
else if (guess > randomnumber)
{
btnexe1.Hide();
btnexe2.Show();
this.BackColor = System.Drawing.Color.SlateBlue;
lbloutput.Text = "Too High";
counter = counter + 1;
}
else
{
lbloutput.Text = "Good Guess";
counter = counter + 1;
}
}
else
{
/*If the value cannot be converted to a int, then display a message box saying so.*/
MessageBox.Show("This is not a number. Please enter a number between 0-100.");
}
}
}
private void btnexe2_Click(object sender, EventArgs e)
{/*I want to check if the user left the textbox empty, if it is then
display a message box saying to enter a number.*/
if (string.IsNullOrEmpty(tbnumber.Text))
{
MessageBox.Show("Please enter a number from 0-100.");
}
else
{/*If it is not empty, then I want the system to determine if the variable
that has been entered can be converted to a int.*/
number = Convert.ToString(tbnumber.Text);
if (Int32.TryParse(number, out guess))
{
/*If the value can be converted, then I want the system to see if
it is lower, higher, or equal to the random value. Then I want to record how
many times the user guessed.*/
if (guess < randomnumber)
{
lbloutput.Text = "Too Low";
this.BackColor = System.Drawing.Color.LightSeaGreen;
counter = counter + 1;
}
else if (guess > randomnumber)
{
lbloutput.Text = "Too High";
this.BackColor = System.Drawing.Color.SlateBlue;
counter = counter + 1;
}
else
{
lbloutput.Text = "Good Guess";
counter = counter + 1;
lblcounter.Text = "You guessed " + counter + " times.";
}
}
else
{
/*If the value cannot be converted to a int, then display a message box saying so.*/
MessageBox.Show("This is not a number. Please enter a number between 0-100");
}
}
}
}
Change your code like this. You are trying to call method Next in the class which is not allowed and when you move complete code inside constructor then your variables scope exist only inside that constructor so variable accessed in another method will not work. So solution is to define variable at class level but initialize it in constructor
Random random;
int randomnumber;
public Guess()
{
/*Once the program is initalized, I want the 2nd button hidden until the first one
is clicked with a value in the textbox*/
InitializeComponent();
btnexe2.Hide();
random = new Random();
randomnumber = random.Next(0, 101);
}
You should initialize variables inside a method (initialization means adding a value to a variable - using "new" keyword);
Try something like this:
class Guess {
Random random;
int randomNumber;
public Guess() {
random = new Random();
randomnumber = random.Next(0, 101);
//Rest of the code
}
}
I think this answer can help you. You can not use an instance variable to initialize another instance variable because the order you write them is not per definition the order the compiler creates them.
A field initializer cannot reference the nonstatic field, method, or property
try changing this
Random random = new Random();
int randomnumber = random.Next(0, 101);
public Guess()
{
/*Once the program is initalized, I want the 2nd button hidden until the first one
is clicked with a value in the textbox*/
InitializeComponent();
btnexe2.Hide();
}
to this
private Random _Random;
private int _RandomNumbrer;
public Guess()
{
_Random = new Random();
_RandomNumbrer = random.Next(0, 101);
/*Once the program is initalized, I want the 2nd button hidden until the first one
is clicked with a value in the textbox*/
InitializeComponent();
btnexe2.Hide();
}
youre nearly there with what youre trying to do

Addition in Button Event C#

private void button2_Click(object sender, EventArgs e)
{
int a,sum=0;
a = 10;
sum = sum + a;
MessageBox.Show( sum + "Sum Result");
}
Every time I click on the button I get the answer 10. I want to store result. Suppose I click 5 times then there should be 50.The above code for better understanding should give you some idea of what I'm going for.
Other option if possible I get this result outside of the button event by some method. I am new in C# so feeling lot of problem.
As #tnw tried to tell you - move sum outside the function like this:
private sum = 0;
private void button2_Click(object sender, EventArgs e)
{
sum = sum + 10;
MessageBox.Show( sum + "Sum Result");
}
This should work
explanation
The problem you face is that every variable declared inside a function will get initialized every time you call this function and is discarded when you exit the function.
With the variable beeing outside you made it a field of your class and it will be kept in memory as long as the instance you are using (for example the instance of your form) will be.
It is because sum=0; gets re-initialized every time you call the function. Try setting it as a global variable inside the Class and then call it.
This way, when ever the function will be called, the value of sum won't get back to 0, but will increment from where it was left.
// somewhere above
int sum = 0;
// then the function
private void button2_Click(object sender, EventArgs e)
{
sum = sum + 10;
MessageBox.Show(sum + " = Sum Result");
}
..since you're not using a or b. I have removed them. However, if you're using them inside the function (in a code which you haven't posted) please add them back.
Each time you called the function, you created new variable called sum and if gets deleted at the end of the function. So, each time you pressed the button, sum had a value of 0 in it as initially. Adding 10 to it, would always return 10.
Global variables are declared inside the class itself. Every variable inside the function (such as this one) would be recreated each time you call the function and will have the value you're providing it with. So it is a better approach to write the variables globally, whose value is required next time.

C# textbox user input processed by a button object [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# GUI application that stores an array and displays the highest and lowest numbers by clicking a button
This is updated from 13 hours ago as I have been researching and experimenting with this for a few. I'm new to this programming arena so I'll be short, I'm teaching myself C# and I'm trying to learn how to have integers from a user's input into a textbox get calculated from a button1_Click to appear on the form. Yes, this is a class assignment but I think I have a good handle on some of this but not all of it; that's why I'm turning to you guys. Thanks for all of the advice guys.
I'm using Microsoft Visual Studio 2010 in C# language. I'm using Windows Forms Application and I need to create a GUI that allows a user to enter in 10 integer values that will be stored in an array called from a button_Click object. These values will display the highest and lowest values that the user inputted. The only thing is that the array must be declared above the Click() method.
This is what I have come up with so far:
namespace SmallAndLargeGUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void inputText_TextChanged(object sender, EventArgs e)
{
this.Text = inputText.Text;
}
public void submitButton_Click(object sender, EventArgs e)
{
int userValue;
if(int.TryParse(inputText.Text, out userValue))
{
}
else
{
MessageBox.Show("Please enter a valid integer into the text box.");
}
int x;
x = Convert.x.ToString();
int squaredResults = squared(x);
int cubedResults = cubed(x); squared(x);
squaredLabel.Text = x.ToString() + " squared is " + squaredResults.ToString();
cubedLabel.Text = x.ToString() + " cubed is " + cubedResults.ToString();
}
public static int squared(int x)
{
x = x * x;
return x;
}
public static int cubed(int x)
{
x = x * squared(x);
return x;
}
}
}
Now I can't run this program because line 38 shows an error message of: 'System.Convert' does not contain a definition for 'x' Also I still have to have an array that holds 10 integers from a textbox and is declared above the Click() method. Please guys, any help for me? This was due yesterday.
As a couple of comments have mentioned, there really isn't enough information here to provide you with a useful answer. There are two main User Interface frameworks in .Net for windows applications. One of these is commonly referred to as "WinForms" and the other is "WPF" or "Windows Presentation Foundation."
I'm going to go with you are most likely using WinForms as it is the older of the two technologies. The approach here can be used on both sides with a little tweaking. Setting text in a text box is very similar to setting text programaticly on a label. You can get more detail on that on MSDN: How to: Display Text on a Windows Form; How to: Use TextBox Controls to Get User Input.
If you are using WPF the "back end" code is pretty much the same. You just need to make sure your textbox has an x:Name="userInputTextBox" so you can reference it in your code behind. Be mindful that your users can input "1", "3" or "abcd" in the field. Ensuring your app doesn't bomb is most likely outside of the assignment but feel free to look up C# int.TryParse(...) and "Try Catch" :-)
Your button handler could look like this:
void btnUserClick_Click(object sender, System.EventArgs e)
{
int userValue;
if(int.TryParse(txtUserInput.Text, out userValue))
{
// We have the value successfully, do calculation
}
else
{
// We don't have the users value.
MessageBox.Show("Please enter a valid integer into the text box.")
}
}
In your retrieveInput_Click handler you are assigning the min/max numbers to a local int. Once you determine your min/max numbers in the logic, you will need to assign those local integers to a UI element for display.
Since we don't have any details on your specific UI choices, one simple solution could be to add 2 labels to your form, and then in the code you would place the result in the label:
for (int i = 0; i < numbers.Length; ++i)
{
if (numbers[i] < min)
min = numbers[i];
if (numbers[i] > max)
max = numbers[i];
}
// Assign Minimum to Label1
Label1.Text = "Minimum Value: " + min.ToString();
// Assign Maximum to Label2
Label2.Text = "Maximum Value: " + max.ToString();
define the textbox named textbox1 or txt_name
you can write the button1_Click function :
int i_value = Convert.ToInt16(txt_name.Text);
ok. I haven't try catch the exceptions.... :(
maybe above answer is right.
btw, i think this question mainly focus on how to get int type from text box. right?

Categories

Resources