So I am working on a project for school that in a guessing game for a randomly generated number between 1-100. The only trouble I am having at the moment is that every time the user enters a new number the generated number also changes. I tried putting the code to generate the number in the form loader but then I can't access it later in the program. Here's what I have so far.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void guessButton_Click(object sender, EventArgs e)
{
int userGuess;
userGuess = int.Parse(guessText.Text);
Random rand = new Random();
int number = rand.Next(1, 100);
label2.Text = "" + number;
if (userGuess > number)
{
resultLabel.Text = "Your guess is too high";
}
else if (userGuess < number)
{
resultLabel.Text = "Your guess is too low.";
}
else if (userGuess == number)
{
resultLabel.Text = "That is correct!";
}
guessText.Clear();
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
As it currently stands, the Random number is overwritten every time the guessButton_Click function is run.
You are declaring Random inside the guessButton_Click function, that is called every time the guess button is clicked (that's also a memory leak!).
To fix, declare it as a global variable, in the namespace:
Edit: The below code compiles properly, and works perfectly.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
int number = new Random().Next(1, 100);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void guessButton_Click(object sender, EventArgs e)
{
int userGuess;
userGuess = int.Parse(guessText.Text);
label2.Text = "" + number;
if (userGuess > number)
{
resultLabel.Text = "Your guess is too high";
}
else if (userGuess < number)
{
resultLabel.Text = "Your guess is too low.";
}
else if (userGuess == number)
{
resultLabel.Text = "That is correct!";
}
guessText.Clear();
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
You are getting a new random number every button click try the following:
public partial class Form1 : Form
{
Random rand;
int number;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
rand = new Random();
number = rand.Next(1, 100);
}
private void guessButton_Click(object sender, EventArgs e)
{
int userGuess;
userGuess = int.Parse(guessText.Text);
label2.Text = "" + number;
if (userGuess > number)
{
resultLabel.Text = "Your guess is too high";
}
else if (userGuess < number)
{
resultLabel.Text = "Your guess is too low.";
}
else if (userGuess == number)
{
resultLabel.Text = "That is correct!";
}
guessText.Clear();
}
}
Related
I have an onLoad event and it contains the variable which takes data from the database and now I need to pass that string to an onclick event of a button so that whenever it is pressed I can perform operations. I need to access word variable from load to onclick.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public string word, alphabets;
public int chances, score;
public Form2()
{
InitializeComponent();
}
public void Form2_Load(object sender, EventArgs e)
{
chances = 8;
score = 0;
alphabets = "abcdefghijklmnopqrstuvwxyz";
Random rnd = new Random();
int wordid = rnd.Next(1, 127);
label12.Text = chances.ToString();
label13.Text = score.ToString();
try
{
string myConnection1 = "datasource=localhost;port=3306;username=root;password=amit;";
MySqlConnection myConn1 = new MySqlConnection(myConnection1);
myConn1.Open();
int count = 0;
var cmd = new MySqlCommand(" select words from gamers.gamewords where id='" + wordid + "';", myConn1);
string word = (string)cmd.ExecuteScalar();
int length = word.Length;
label4.Text = length.ToString();
label7.Text = alphabets;
label14.Text = word;
myConn1.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void button1_Click(object sender, EventArgs e)
{
//Code for Game Begins
int i = 0, j = 0;
int lengthcount = 0;
string choice = textBox1.Text;
string guess;
label14.Text = word + "**";
// for (i = 0; i<word.Length; i++)
/* {
if (word[i] == choice[0])
{
label14.Text = "Good Guess! You Scored a point";
lengthcount++;
score += 5;
guess = choice;
label9.Text= guess;
}
else
{
chances--;
guess = "______";
if (chances == 0)
{
label14.Text = "You Lost the Game! Turns Over";
button1.Enabled = false;
}
else
{
label14.Text = "Sorry! Try Again";
}
}
}*/
}
}
}
You can call the button1_Click like a method, but you can't pass a value to it directly, because the Click event are handled by the default EventHandler, so you have just the two parameters: object sender and EventArgs e:
button1_Click(sender, e);
But you can use a property (or a field / variable) in the Form2 class, to hold an value from the Form2_Load method, and after read then in the button1_Click method:
public partial class Form2 : Form
{
// ...
private string ValueToHold { get; set; }
// ...
public void Form2_Load(object sender, EventArgs e)
{
// ...
ValueToHold = "something";
// ...
}
public void button1_Click(object sender, EventArgs e)
{
// ...
// Use the ValueToHold here!
// ...
}
}
This question already has answers here:
How do you pass an object from form1 to form2 and back to form1?
(4 answers)
Closed 5 years ago.
I'm supposed to make a math practice program for kids. They should be able to choose 1 operation and the amount of digits (1, 2 or 3 digit) the numbers will have. It then has to out put 10 random questions according to the selection made by the kid, then once they have completed the quiz, it should display their results and which questions they got wrong.
I have two selections being made on form1, operations and # of digits, which are assigned numbers (1. (*) 2. (/) 3. (+) 4. (-)). All i need to do is communicate the operation number and # of digits to form2, where the questions will be generated and displayed.
Here's my code for form1 so far:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form1 : Form
{
public static int operation = 0;
public static int digits = 0;
public Form1()
{
InitializeComponent();
}
// this is to make sure only one box is checked for both selections. Starts here
private void label1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void MulCB_CheckedChanged(object sender, EventArgs e)
{
if ( MulCB.Checked == true)
{
operation = 1;
DivCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void DivCB_CheckedChanged(object sender, EventArgs e)
{
if (DivCB.Checked == true)
{
operation = 2;
MulCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void AddCB_CheckedChanged(object sender, EventArgs e)
{
if (AddCB.Checked == true)
{
operation = 3;
DivCB.Checked = false;
SubCB.Checked = false;
MulCB.Checked = false;
}
}
private void SubCB_CheckedChanged(object sender, EventArgs e)
{
if (SubCB.Checked == true)
{
operation = 4;
DivCB.Checked = false;
AddCB.Checked = false;
MulCB.Checked = false;
}
}
private void oneDCB_CheckedChanged(object sender, EventArgs e)
{
if(oneDCB.Checked == true)
{
digits = 1;
twoDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void twoDCB_CheckedChanged(object sender, EventArgs e)
{
if ( twoDCB.Checked == true)
{
digits = 2;
oneDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void threeDCB_CheckedChanged(object sender, EventArgs e)
{
if (threeDCB.Checked == true)
{
digits = 3;
oneDCB.Checked = false;
twoDCB.Checked = false;
}
}
private void button8_Click(object sender, EventArgs e)
{
// operations: 1. (*) 2. (/) 3. (+) 4. (-)
// digits are as number indicates.
// Second window popup.
Form2 settingsForm = new Form2();
settingsForm.Show();
}
}
}
Here's form2, naked pretty much.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void FinishedBtn_Click(object sender, EventArgs e)
{
}
}
}
This might work.
There are comments in the code.
The workflow is creating a new instance of the class Form2 and setting two public variables. Public means that they can be accessed from outside of the class (see here, if you want). Then the method Show() is called and the Form appears. In the Form2 code, the public variables now have the values previously specified and can be used.
Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// this is to make sure only one box is checked for both selections. Starts here
private void label1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void MulCB_CheckedChanged(object sender, EventArgs e)
{
if ( MulCB.Checked == true)
{
operation = 1;
DivCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void DivCB_CheckedChanged(object sender, EventArgs e)
{
if (DivCB.Checked == true)
{
operation = 2;
MulCB.Checked = false;
AddCB.Checked = false;
SubCB.Checked = false;
}
}
private void AddCB_CheckedChanged(object sender, EventArgs e)
{
if (AddCB.Checked == true)
{
operation = 3;
DivCB.Checked = false;
SubCB.Checked = false;
MulCB.Checked = false;
}
}
private void SubCB_CheckedChanged(object sender, EventArgs e)
{
if (SubCB.Checked == true)
{
operation = 4;
DivCB.Checked = false;
AddCB.Checked = false;
MulCB.Checked = false;
}
}
private void oneDCB_CheckedChanged(object sender, EventArgs e)
{
if(oneDCB.Checked == true)
{
digits = 1;
twoDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void twoDCB_CheckedChanged(object sender, EventArgs e)
{
if ( twoDCB.Checked == true)
{
digits = 2;
oneDCB.Checked = false;
threeDCB.Checked = false;
}
}
private void threeDCB_CheckedChanged(object sender, EventArgs e)
{
if (threeDCB.Checked == true)
{
digits = 3;
oneDCB.Checked = false;
twoDCB.Checked = false;
}
}
private void button8_Click(object sender, EventArgs e)
{
// operations: 1. (*) 2. (/) 3. (+) 4. (-)
// digits are as number indicates.
// Second window popup.
// it's the question form, right?
Form2 questionForm = new Form2();
//"Write" your settings in the other form's variables
//You will have to write code that finds out which checkbox is which number! For now its fixed.
questionForm.operation = 2;
questionForm.digits = 1;
questionForm.Show();
//Hide Form1
this.Hide();
}
}
}
Form2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FinalProject
{
public partial class Form2 : Form
{
public static int operation;
public static int digits;
public Form2()
{
InitializeComponent();
}
//do NOT paste this. It can be added by creating an event handler
// you also might not need this, but this method is called when this Form appears. It's an example.
// https://msdn.microsoft.com/en-us/library/zwwsdtbk(v=vs.80).aspx
private void Form2_Load(object sender, EventArgs e)
{
//here you can use your variables for example (also anywhere within this class!)
//e.g.
Textbox1.Text = (string)operation;
}
private void FinishedBtn_Click(object sender, EventArgs e)
{
}
}
}
I have a Class and a Form. This is the code I have in my form:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Tamagotchi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
label3.Text = "doplntamboredom";
}
private void button2_Click(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
label6.Text = GetMood();
}
}
}
That last part (label6.Text = GetMood()) is making error:
The name 'GetMood' does not exist in the current context.
And this is the code I have in my class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tamagotchi
{
class Mazlicek
{
private int hunger = 1;
private int boredom = 1;
private string mood;
public string GetMood()
{
return mood;
}
private void Moods(int hunger, int boredom, string strHunger, string strBoredom)
{
if ((boredom + hunger) > 15)
{
mood = "Angry!";
}
else if ((boredom + hunger) > 10 && (boredom + hunger) < 15)
{
mood = "Frustrated..";
}
else if ((boredom + hunger) > 5 && (boredom + hunger) < 11)
{
mood = "Fine.";
}
else
{
mood = "Happy!";
}
}
}
}
I have no idea why there is this problem. I'm making it with Visual Studio 2015 and it is all in one project.
You probably mean to have an instance of Mazlicek in your form. In that way you can call methods on it.
So, start by instantiating the variable mazlicek to an instance of type Mazlicek:
public partial class Form1 : Form
{
private Mazlicek mazlicek = new Mazlicek();
...
}
Now we have an instantiated object, you can can call methods on it and set properties to remember its state. You have to reference it by its variable name mazlicek:
private void button3_Click(object sender, EventArgs e)
{
label6.Text = mazlicek.GetMood();
}
Use
label6.Text = Mazlicek.GetMood();
and change it to
static class Mazlicek
and
private static string mood;
and
public static string GetMood()
{
return mood;
}
I have two issues with this piece of code. I 'm having trouble because the submit button event doesn't recognize the variable calculated in the text box event, and because the text box event isn't recognizing my if statements as statements. You can see where I'm having trouble in the comments below.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int points;
int userInput = int.Parse(textBox1.Text);
if (userInput == 0)
{
points == 5; //I CANNOT COMPILE BECAUSE APPARENTLY I AM NOT ALLOWED TO USE
THIS AS A STATEMENT?
}
if (userInput == 1)
{
points == 10;
}
if (userInput == 2)
{
points == 20;
}
if (userInput ==3)
{
points == 30;
}
else
{
points == 40;
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show = ("You have been awarded" + textBox1.points + "points");
} //I WANT TO BE ABLE TO RETRIEVE THE POINTS CALCULATED USING THE CALCULATION IN
TEXT BOX, BUT I CANNOT COMPILE THE BUTTON EVENT DOES NOT RECOGNIZE THE POINTS
VARIABLE
private void label1_Click(object sender, EventArgs e)
{
}
}
}
The == symbol is a comparison symbol not an assignment symbol
You need to use
if (userInput == 2) // this is a comparison
{
points = 20; // this is an assignment
}
First you have declared points local to the TextChanged event, so it won't be accessible in your button click event.
textBox1.points is not right since int points declaration has nothing to do with the TextBox, you may declare points as a class variable, something like
public partial class Form1 : Form
{
int points =0;
public Form1()
{
InitializeComponent();
}
//......//
this would then work out as
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show( string.Format("You have been awarded {0} points",this.points));
}
Also you do assignment using = sign, so points = 5; would be the right thing to do
To add value to variable you should write:
points = 5;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication11
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public int points=0;
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
int userInput = int.Parse(textBox1.Text);
if (userInput == 0)
{
points = 5;
}
if (userInput == 1)
{
points = 10;
}
if (userInput == 2)
{
points = 20;
}
if (userInput ==3)
{
points = 30;
}
else
{
points = 40;
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show = ("You have been awarded" + points.ToString() + "points");
}
private void label1_Click(object sender, EventArgs e)
{
}
}
}
As already stated - you confussed with assignment operator and with global/local variables.
But there is several other "errors" in your code. User input might be simple text - so there will be exception, you should use int.TryParse instead of int.Parse. Also there are plenty of ifs in your code - but they cannot fire all together, I recomend use switch. And of course you should try to name your constants somehow, it will make your code much more readable!
Overral your code might look like this:
int pointsAvarded = 0;
private void textBox1_TextChanged(object sender, EventArgs e)
{
pointsAvarded = 0; //so you can be sure to use the latest input
int userInput = 0;
if (int.TryParse(textBox1.Text, out userInput))
switch (userInput)
{
case 0:
points = 5;
break;
case 1:
points = 10;
break;
...
default:
points = 40;
break;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (pointsAvarded != 0)
MessageBox.Show("You have been awarded" + pointsAvarded + "points");
}
So I have the following code, and It works nearly flawlessly, except for the fact that no matter what I do I cannot get the parts that are like: for (int.parse(txtGuess.Text) == numbGen) it will not recognize 'numbGen' no matter where I place it in the code. I cannot place it inside the button click function because I don't want the number to change, unless they've gotten it correct or re-opened the form.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class rndNum : Form
{
public rndNum()
{
}
private void rndNum_Load(object sender, EventArgs e)
{
int numbGen = RandMake(0, 100);
}
private void txtGuess_TextChanged(object sender, EventArgs e)
{
}
private void btnEval_Click(object sender, EventArgs e)
{
int guesses = 0;
while (txtGuess.Text != "")
{
if (int.Parse(txtGuess.Text) == numbGen)
{
MessageBox.Show("You got it!", "Congratulations!");
break;
}
else if (int.Parse(txtGuess.Text) > numbGen)
{
MessageBox.Show("Sorry, but you're too high. The number was " + numbGen + "!", "Please try again.");
txtGuess.Clear();
txtGuess.Focus();
guesses++;
break;
}
else if (int.Parse(txtGuess.Text) < numbGen)
{
MessageBox.Show("Sorry, but you're too low. The number was " + numbGen + "!", "Please try again.");
txtGuess.Clear();
txtGuess.Focus();
guesses++;
break;
}
}
}
private static int RandMake(int min, int max)
{
Random mkRnd = new Random();
return mkRnd.Next(min, max);
}
}
}
numbGen must be a class member.
Change
private void rndNum_Load(object sender, EventArgs e)
{
int numbGen = RandMake(0, 100);
}
to
private int numbGen;
private void rndNum_Load(object sender, EventArgs e)
{
numbGen = RandMake(0, 100);
}
actually you don't need to put the initialization in Form.Load, you can initialize a class member directly.
public partial class rndNum : Form
{
private int numbGen = RandMake(0, 100);
public rndNum()
{
}
and to further refine: if you want to make sure the values is not changed you can make it readonly
public partial class rndNum : Form
{
private readonly int numbGen = RandMake(0, 100);
public rndNum()
{
}
int numbGen;
private void rndNum_Load(object sender, EventArgs e)
{
numbGen = RandMake(0, 100);
}
try this!!!
The others already commented on the scoping issue you noticed. But your RandMake method is flawed too. You should not create an instance of Random for each number, but reuse the instance.
The problem here is that new Random() uses the time as seed, and the time only changes every few milliseconds. This means that if you call RandMake several times within that time interval you will get the same "random" number.
This doesn't seem to be a immediate problem because you only call it once, but you should be aware of this in the future.
When you put numbGen's declaration on the inside of a method, the number only exist in that functions scope. You have to place it outside like this:
int numbGen;
private void rndNum_Load(object sender, EventArgs e)
{
numbGen = RandMake(0, 100);
}