How to restart array once filled on windows form? [closed] - c#

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I created a form which asked the user to guess the number. I created an array on 100 ints, created a method to get random numbers to fill the array. All is working fine but I am required to create another method which resets the array back to 0 once 100 guesses are made, and it just seems to let me keep going and going in my current set up. How do I make sure my array is filling up and not just restarting with every button click, then how do I reset it? Again this runs great just not meeting all my requirements.
Here is the code from my array and method and where I am calling it at:
int[] rndArray = new int[100];
int wrong = 1;
int right = 1;
public void getNumbers()
{
Random random = new Random();
for (int x = 0; x < rndArray.Length; x++)
{
rndArray[x] = random.Next(1, 100);
}
}
public Form1()
{
getNumbers();
InitializeComponent();
}
Then I have two buttons seeing if the guess was correct and letting them guess again.
private void Guess_Click(object sender, EventArgs e)
{
bool num = true;
for (int x = 0; x < rndArray.Length; x++)
{
if (Convert.ToInt32(textBox1.Text) == rndArray[x])
{
result.Text = "You Win!";
num = true;
}
else
{
result.Text = "Sorry - you loose; the number is: " + rndArray[x];
num = false;
}
}
if (num == true)
correct.Text = "Correct: " + right++;
else
incorrect.Text = "Incorrect: " + wrong++;
mouseHere.Enabled = false;
Guess.Enabled = false;
nextGuess.Enabled = true;
}
private void nextGuess_Click(object sender, EventArgs e)
{
mouseHere.Enabled = true;
Guess.Enabled = true;
nextGuess.Enabled = false;
hint.Text = "??";
textBox1.Text = "";
result.Text = "";
getNumbers();
}
I called the method again so it would not just generate the same number for each guess.

Why not create a GuessingGame class and raise an event when the 100th guess is made? You can reset the array and guess counter.
Something like:
public class GuessingGame {
private int[] RandomNumbers;
private GuessCount = 0;
// constructor
public GuessingGame () {
this.guessCount = 0;
this.randomNumbers = this.RandomNumberGenerator();
}
public void AddGuess(int guess) {
// increment guessCount
// check for a winner and/or 100th guess
// raise a correct guess event if correct
// raise 100th guess event if 100th guess occurs
}
private int[] RandomNumberGenerator() {
// return your array of random numbers
}
...more stuff...
}
You'll want to declare a couple of simple eventhandler classes to do whatever you need them to do and then fire them from your GuessingGame class. That's a bit much to code for you, so I'll let you do that on your own. This should get you started in the right OO direction.
http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx. This is a tutorial on events that is pretty useful.

all you need is a counter :
int count = 0;
private void Guess_Click(object sender, EventArgs e)
{
if (count < 100)
{
count++;
// checks user input ...
}
else
{
count = 0;
// reset the array by getting fresh numbers
getNumbers();
}
}
you can also reset the array in a loop and setting It's members's values to 0 .

Related

new to programing trying to make a number guessing game in c#

Hi so I am new to programing I just started school and I wanted to get a head start on programing so please keep in mind that everything I show you is all self-taught. Here is my question I wanted to make a random number guessing game and for the most part it works but every time you click the button to guess it randoms a different number which I don’t want here is what I have so far
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// number of guesses
int numberOfGesses = 0;
private void btnCalc_Click(object sender, EventArgs e)
{
// make the generator
Random generator = new Random();
//make the number
int number = generator.Next(1, 10);
// get the users guess
int guess = int.Parse(txtInput.Text);
//check the users guess
if (guess == number)
{
lblAnswer.Text = "You got it";
numberOfGesses = 0;
}
else if (guess != number)
{
numberOfGesses = numberOfGesses + 1;
lblAnswer.Text = "try agian you have gessed" + (numberOfGesses) + " times";
}
}
}
I know it keeps creating a new number because every time I press the guess button it starts from the top and makes a new number. I tried to take this block and make it global but I got an error
// make the generator
Random generator = new Random();
//make the number
int number = generator.Next(1, 10);
again im realy new and i found this site when lookinging up some qeustions i had so i thought it would be a good place to help me learn about programing while i wait till i can get into the programing classes thank you for your time.
You likely got an error because C# doesn't allow you to assign a default value of a field based on another field.
public partial class Form1 : Form {
int numberOfGuess = 0;
Random generator = new Random();
int number;
// other methods
}
generator can be initialized before or after number, hence the error. Instead, you can put it in the form intializer (Form1 method), or make another button and click it and generate a new random number:
public partial class Form1 : Form
{
// number of guesses
int numberOfGesses = 0;
Random generator = new Random();
int number;
public Form1()
{
InitializeComponent();
// Generate the random number
number = generator.Next(1, 10);
}
private void btnRandom_Click(object sender, EventArgs e)
{
// Generate a new random number when you click a button on the form
number = generator.Next(1, 10);
}
private void btnCalc_Click(object sender, EventArgs e)
{
// get the users guess
int guess = int.Parse(txtInput.Text);
//check the users guess
if (guess == number)
{
lblAnswer.Text = "You got it";
numberOfGesses = 0;
}
else if (guess != number)
{
numberOfGesses = numberOfGesses + 1;
lblAnswer.Text = "try agian you have gessed" + (numberOfGesses) + " times";
}
}
}
You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that generator will be initialized before number, so the above line might throw a NullReferenceException.
So change the default number value to 0:
Random generator = new Random();
int number = 0;
Initialise in the constructor:
public Form1()
{
InitializeComponent();
number = generator.Next(1, 10);
}
When the button is clicked generate the number since here you will be needing it:
private void btnCalc_Click(object sender, EventArgs e)
{
//take the input & Compare as before.
}

counter for attempts in c#

I am trying to get the counter named "Guesses" to keep a tally of attempts at guessing a random number and output the total attempts at guessing the number. I have tried leaving the counter declaration at 0 and 1 and the number of attempts to guess is always 0 or 1. Help would be appreciated and I will re-post entire working code once it's figured out. Here is my code.
int Answer; // declares the Answer variable outside button event
public frmGuess()
{ // generates random number outside button event so does not change on button click
InitializeComponent();
Random rand = new Random();
Answer = rand.Next(100) + 1; // makes it range 1 to 100
}
private void btnGuess_Click(object sender, EventArgs e)
{
int UserGuess;
int Guesses = 0; // start counter
if (string.IsNullOrEmpty(txtGuess.Text)) // input validation check to make sure not blank and is a whole number integer
{
MessageBox.Show("Please enter a whole number between 1 and 100");
return;
}
else
{
UserGuess = int.Parse(txtGuess.Text); // variable assign and code run
Guesses ++;
if (UserGuess > Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too high, try again.";
}
else if (UserGuess < Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too low, try again.";
}
else
{
lblAnswer.Text = "Congratulations the answer was " + Answer + "!\nYou guessed the number in " + Guesses + " tries.\nTo play again click the clear button."; //victory statement
}//end if
} //end if
}
private void btnClear_Click(object sender, EventArgs e) // clears Answer label and Guess textbox
{
txtGuess.Text = "";
lblAnswer.Text = "";
}
private void btnExit_Click(object sender, EventArgs e) // closes window
{
this.Close();
}
}
}`
Yes indeed! That took care of it. To think I placed the random number outside the button click but didn't do it to the counter - foolishness. Thanks all! Working code is :
{
int Answer; // declares the Answer variable outside button event
int Guesses = 0; // declares counter outside button event
public frmGuess()
{ // generates random number outside button event so does not change on button click
InitializeComponent();
Random rand = new Random();
Answer = rand.Next(100) + 1; // makes it range 1 to 100
}
private void btnGuess_Click(object sender, EventArgs e)
{
int UserGuess;
if (string.IsNullOrEmpty(txtGuess.Text)) // input validation check to make sure not blank and is a whole number integer
{
MessageBox.Show("Please enter a whole number between 1 and 100");
return;
}
else
{
UserGuess = int.Parse(txtGuess.Text); // variable assign and code run
Guesses ++; // adds 1 to attempts but doesn't count textbox blank or mistyping
if (UserGuess > Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too high, try again.";
Guesses++;
}
else if (UserGuess < Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too low, try again.";
Guesses++;
}
else
{
lblAnswer.Text = "Congratulations the answer was " + Answer + "!\nYou guessed the number in " + Guesses + " tries.\nTo play again click the clear button.";
}//end if
} //end if
}
private void btnClear_Click(object sender, EventArgs e) // clears Answer label and Guess textbox
{
txtGuess.Text = "";
lblAnswer.Text = "";
}
private void btnExit_Click(object sender, EventArgs e) // closes window
{
this.Close();
}
}
}
`
You are resetting the counter in your click event.
int Answer; // declares the Answer variable outside button event
int Guesses = 0; // declare this outside button event, and initialize it to 0.
// initialization will happen when the Form object is created.
...
private void btnGuess_Click(object sender, EventArgs e)
{
int UserGuess;
// DO NOT reset the counter here. This line is the culprit that
// resets the counter every time you click the button
//int Guesses = 0; // start counter
...
}
...
It's a scoping issue. You currently define guesses within your event handler where it resets the counter with each button click. If you define it at the form level, even as a property or member variable, that scope will allow the variable to retain its value through multiple button click events.

How to get correct answer for quiz when randomly assigning answers, from a dataset, to a buttons text attribute

I have a quiz that I'm writing and I'm using 4 buttons text attributes to display the multiple choice answers. 1 is correct, the other 3 are wrong.
The answers are from my dataset and then randomly assigning the answers to the buttons text attributes, when the user selects an answer then it moves along to the next question and doing the same thing, as it should.
But what I can't seem to figure out is, since I'm assigning the answers randomly, how do I keep track of answer that was selected? Here is the code...
Label1.Text = ds.Tables[0].Rows[myNum]["Question"].ToString();
string[] array = new string[4] {
ds.Tables[0].Rows[myNum]["CorrectAnswer"].ToString(),
ds.Tables[0].Rows[myNum]["WrongAnswer1"].ToString(),
ds.Tables[0].Rows[myNum]["WrongAnswer2"].ToString(),
ds.Tables[0].Rows[myNum]["WrongAnswer3"].ToString(),
};
// randomize the ordering of the items
System.Random rnd = new System.Random();
array = array.OrderBy(x => rnd.Next()).ToArray();
// each time you run this, the correct answer will be in a different place:
btn1.Text = array[0];
btn2.Text = array[1];
btn3.Text = array[2];
btn4.Text = array[3];
myNum = myNum + 1;
if (myNum == numOfRows)
Response.Redirect("~/Results.aspx");
I have tried this...
ds.Tables[0].Rows[myNum]["CorrectAnswer"].ToString() + "1",
ds.Tables[0].Rows[myNum]["WrongAnswer1"].ToString() + "0",
ds.Tables[0].Rows[myNum]["WrongAnswer2"].ToString() + "0",
ds.Tables[0].Rows[myNum]["WrongAnswer3"].ToString() + "0",
and as expected it didn't work at all, but I tried it any ways.
Any ideas?
Thanks
When you shuffle your array you lose track of the correct solution. This is not what you want. You should always be able to tell from your code which button will be assigned the correct answer. This does not mean you should know which id this button has, but how it gets assigned.
One thing you could do for example is shuffle an array of your button objects, and always assign your correct answer to the first index in that array.
So you create an array of your button objects, shuffle it. You assign the correctAnswerClick handler and the answer string to the first index (0) in that array. You assign the falseClick and wrong answers to index 1, 2 and 3. This way you always know that the correct button has the proper event handler.
The code below is what you want to achieve in Winforms (I don't have ASP installed in VS.Net atm) but it should be easily translated to ASP.Net I think.
button1 to button4 are named btn1 to btn4 in your case.
public partial class Form1 : Form
{
private void Form1_Load(object sender, EventArgs e)
{
var btnns = new List<Button>();
btnns.Add(button1);
btnns.Add(button2);
btnns.Add(button3);
btnns.Add(button4);
//Shuffle the list
Shuffle<Button>(ref btnns);
//Add an event handler for success to your first button
btnns[0].Click += successClick;
btnns[0].Text = "Correct";
for (int i = 1; i < btnns.Count; i++)
{
btnns[i].Click += failedClick;
btnns[i].Text = "Wrong " + i;
}
}
private void failedClick(object sender, EventArgs e)
{
//Add a true value to the viewstate list
AddAnswer(true);
}
private void successClick(object sender, EventArgs e)
{
//Yay, it's correct
AddAnswer(false);
}
public void AddAnswer(bool correctornot)
{
//I am not 100% sure about the code below (not tested), but it should give you an idea
if (Session["listOfAnswers"] != null)
{
var currentList = (List<bool>) Session["listOfAnswers"];
currentList.Add(correctornot);
Session["listOfAnswers"] = currentlist;
}
else
{
var currentlist = new List<bool>();
currentlist.Add(correctornot);
Session["listOfAnswers"] = currentlist;
}
}
public void Shuffle<T>(ref List<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
Answer taken from here: Randomize a List<T>

Global array not being accessed correctly

Below is my current code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public int[] trialArray = new int[10];
public int trialCounter = -1;
private void button1_Click(object sender, EventArgs e)
{
bool button1Click = true;
if (button1Click == true)
{
ITIpanel.Visible = true;
for (int i = 0; i < trialArray.Length; i++) { trialArray[i] = -1; } // Set default value through array
int counter = 0;
Random rnd = new Random();
while (counter < 10 / 2)
{ // Red trials, fill half array
int index = rnd.Next(0, 10 - 1);
if (trialArray[index] == -1) { trialArray[index] = 1; ++counter; } //if unchanged value, change it
}
while (counter < 10)
{
int index = rnd.Next(0, 10);
if (trialArray[index] == -1) { trialArray[index] = 2; ++counter; }
}
}
}
private void ITIpanel_Paint(object sender, PaintEventArgs e)
{
if (ITIpanel.Visible == true)
{
trialCounter += 1;
timer1.Enabled = true;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
ITIpanel.Visible = false;
timer1.Enabled = false;
if (trialArray[trialCounter] == 1) { redstimPanel.Visible = true; }
else { bluestimPanel.Visible = true;}
if (trialCounter == 9) { Application.Exit(); }
}
public int counter = 0;
public event EventHandler Clicked5TimesEvent;
private void OnClicked5TimesEvent()
{ if (Clicked5TimesEvent != null) { Clicked5TimesEvent(this, EventArgs.Empty); } }
private void bluestimPanel_MouseDown(object sender, EventArgs e)
{
//FR requirement
counter++; if (counter % 5 == 0) { redstimPanel.Visible = false; ITIpanel.Visible = true; }
}
private void redstimPanel_MouseDown(object sender, EventArgs e)
{
//FR requirement
counter++; if (counter % 5 == 0) { redstimPanel.Visible = false; ITIpanel.Visible = true; }
}
}
}
As you can see, I am attempting to make a global array with 10 items. On the button click the 10 items are supposed to be altered such that half contain the value 1 and the other half contain the value 2.
Then, on the timer tick, depending on the value in the trialCounter, which determines the part of the array to be accessed, it should display either the redstimPanel or the bluestimPanel.
Therefore, if the 'trialCounter' is equal to 8, and 8 in the TrialArray is equal 1, the 'redstimPanel' should become Visible. Alternatively, if 8 in the 'TrialArray' is equal to 2, the 'bluestimPanel' should become Visible.
This, however, is not working as I would like it to. Thus, there are clearly some issues with my code. Do you all have any suggestions?
You never reset counter, or have the second loop (the one setting the 2s) be the full array.
There is also an error with the random number, rnd.Next(a,b) a - lower bound (inclusive), b - upper bound (exclusive). So it should be rnd.Next(0,10); so you have a chance of populating the last array position.
while (counter < 10 / 2) { // Red trials, fill half array
int index = rnd.Next(0, 10);
if (trialArray[index] == -1) { trialArray[index] = 1; ++counter; } //if unchanged value, change it
}
//Counter on the first loop here is already 5 (it exited the previous loop)
//So allow it to get to 10, and populate the FULL array.
while (counter < 10) {
int index = rnd.Next(0, 10);
if (trialArray[index] == -1) { trialArray[index] = 2; ++counter; }
}
Allow me to give you some tips and some explanations regarding your code:
First of all, you probably wanted that local button1Click variable to know later on whether the button has been clicked or not. For that to work, you should place it outside that function, otherwise it's never going to be used, and will be true with every button click, something like this:
bool button1Click = false;
private void button1_Click(object sender, EventArgs e)
{
if (!button1Click)
{
When you have a condition, you want the code to decide, whether an expression is true or false you may omit the part "== true" because it doesn't add anything new.
You have two whiles. Your idea was to run the counter until 5, with the first piece of code, and then from 5 to 10 the second piece of code. Now let me try to explain what is actually going on. The counter will go on until 5 filling 1s at random indices. Then at 5, the expression in the while will become false and it breaks out from the loop. Since the second while has the very same expression, it simply avoids it and goes on. One of the many solutions would be to have an if in the loop like this:
while (counter < 10)
{
if (counter<5)
{
// fill red
}
else
{
// fill blue
}
}
The way you fill up the values in your array. Have you thought about what's going to happen when the same index will be generated several times? It means it'll overwrite the previous value while certain index will remain -1.

c# - getting the same random number repeatedly [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Random number generator not working the way I had planned (C#)
Hi,
Below is the complete code for a small app I am writing - it returns an ArrayList of alphanumeric codes. The problem I have is that when 'stepping' through the code the e.Result is returned correctly with each item being different. However, if I let the app run without the breakpoints I just get multiple instances of the same variable back:
public partial class AlphaNum : Form
{
public AlphaNum()
{
InitializeComponent();
// Initialise BackGroundWorker Reporting
backgroundWorker1.WorkerReportsProgress = true;
// Initialise BackGroundWorker Cancel
backgroundWorker1.WorkerSupportsCancellation = true;
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
button1.Enabled = false;
}
private int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
public string RandomString(Random r, int len)
{
string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
StringBuilder sb = new StringBuilder();
while ((len--) > 0)
sb.Append(str[(int)(r.NextDouble() * str.Length)]);
return sb.ToString();
}
private string generateCode()
{
Random rnd = new Random();
int length = int.Parse(stringLength.Text);
string code = "";
code = RandomString(rnd, length);
return code;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int quantity = int.Parse(quantityRequired.Text);
ArrayList codes = new ArrayList();
string myText = "";
for (int a = 0; a < quantity; a++)
{
myText = generateCode();
codes.Add(myText);
backgroundWorker1.ReportProgress(((100 / quantity) * a));
}
e.Result = codes;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage; //update progress bar
//Console.WriteLine(time);
//in this example, we log that optional additional info to textbox
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Enabled = true;
ArrayList codes = new ArrayList();
codes = (ArrayList)e.Result;
for (int i = 0; i < codes.Count; i++ )
{
outputText.Text += codes[i].ToString();
outputText.AppendText(Environment.NewLine);
}
}
}
}
Can anyone explain why the result is okay when I effectively slow the process down by stepping my way through but incorrect when it runs without being stopped/slowed down?
Many Thanks
The loop in backgroundWorker1_DoWork is so fast that the Random object generated in generateCode is always seeded with the same value, thus producing the same values. Don't recreate the Random object but assign one to an instance variable in the constructor of your class and only use that one.
You shouldn't create a new Random object every time you need a random number.
Random rnd = new Random();
uses the current time to initialize the LFSR, when the program runs at full speed, the same "current time" gets used many times in a row.

Categories

Resources