How to keep a running score? - c#

I am making a mini test and I am not sure how to go about making a running score that will update the current score after the user submits the test. The score can fluctuate by 25 points depending on if the question goes from wrong to right, and vice versa.
public partial class _Default : System.Web.UI.Page
{
private int totalScore = 0;
public void IncrementScore()
{
totalScore += 25;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblHeader.Text = "quiz not taken";
}
else
{
lblHeader.Text = "Score: " + totalScore;
}
}
protected void Submit_Click(object sender, EventArgs e)
{
/***************************************************************************/
if (IsValid)
if (txtAnswer.Text.Equals("primary", StringComparison.InvariantCultureIgnoreCase))
{
lblQuestionResult1.ForeColor = System.Drawing.Color.Green;
lblQuestionResult1.Text = "Correct";
}
else
{
lblQuestionResult1.ForeColor = System.Drawing.Color.Red;
lblQuestionResult1.Text = "Incorrect";
}
/***************************************************************************/
if (ddList.SelectedItem.Text.Equals("M:N"))
{
lblQuestionResult2.ForeColor = System.Drawing.Color.Green;
lblQuestionResult2.Text = "Correct";
}
else
{
lblQuestionResult2.ForeColor = System.Drawing.Color.Red;
lblQuestionResult2.Text = "Incorrect";
}
/***************************************************************************/
if (RadioButton4.Checked == true)
{
lblQuestionResult3.ForeColor = System.Drawing.Color.Green;
lblQuestionResult3.Text = "Correct";
}
else
{
lblQuestionResult3.ForeColor = System.Drawing.Color.Red;
lblQuestionResult3.Text = "Incorrect";
}
/***************************************************************************/
lblQuestionResult4.ForeColor = System.Drawing.Color.Red;
lblQuestionResult4.Text = "Incorrect";
if (Answer2.Checked && Answer3.Checked && !Answer1.Checked && !Answer4.Checked)
{
lblQuestionResult4.ForeColor = System.Drawing.Color.Green;
lblQuestionResult4.Text = "Correct";
}
}
}

The approach of incrementing
private int totalScore = 0;
will not work because you get a new instance of _Default for every HTTP request.
You can keep your running score in Session.
However, I would instead suggest always recalculating the total score when needed by looping through the answers and score associated with each answer as needed. This simplifies the logic if people go back and change an answer (assuming it is permitted to do that).

Modify it to something like see, check syntax, was not using VS
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lblHeader.Text = "quiz not taken";
}
else
{
Session["TotalScore"] = ""+totalScore; //Storing it in a session
lblHeader.Text = "Score: " + Session["TotalScore"];
}
}
//increment method
if(Session["TotalScore"]!=null)
{
totalScore += 25;
}
else
{
totalScore=int.Parse(Session["TotalScore"])+25;
}

Related

Why are the values still adding up after i clear the output label?

I'm not sure what is going on. I thought I had it set up to clear the output label at the end. Everytime I clear it, the program still remembers the previous number and adds to it. I honestly have no idea what is going on.
Also on a side note, how do I put set up radiobuttons to be used in the this method?
First coding class so i'm still kind of a beginner.
private double oilandlube()
{
if (checkBox1.Checked == true)
{
Oil_change = 26;
}
if (checkBox2.Checked == true)
{
Lube_job = 18;
}
return Oil_change + Lube_job;
}
private void Oiltype ()
{
if (radioButton1.Checked)
{
Regular = 0;
}
if (radioButton2.Checked)
{
Mixed = 10;
}
else
{
Mixed = 0;
}
if (radioButton3.Checked)
{
Full_Synthetic = 18;
}
else
{
Full_Synthetic = 0;
}
}
private void carwash()
{
if (radioButton4.Checked)
{
none = 0;
}
if (radioButton5.Checked)
{
complimentary = 0;
}
if (radioButton6.Checked)
{
Full_service = 6;
}
else
{
Full_service = 0;
}
if (radioButton7.Checked)
{
Premium = 9;
}
else
{
Premium = 0;
}
}
private double flushes()
{
if (checkBox3.Checked == true)
{
Radiator_flush = 30;
}
if (checkBox4.Checked == true)
{
Transmission_flush = 80;
}
return Radiator_flush + Transmission_flush;
}
private double misc()
{
if (checkBox5.Checked == true)
{
inspection = 15;
}
if (checkBox6.Checked == true)
{
replace_muffler = 100;
}
if (checkBox7.Checked == true)
{
tire_rotation = 20;
}
return inspection + replace_muffler;
}
private double partsandlabor()
{
double.TryParse(textBox1.Text, out parts);
double.TryParse(textBox2.Text, out labor);
return parts + labor;
}
private double tax()
{
return partsandlabor() * taxes;
}
private void summary()
{
service = oilandlube() + flushes() + misc();
total_parts = partsandlabor();
double total_tax = tax();
double grand_total = service + total_parts + total_tax;
label7.Text = service.ToString("c");
label8.Text = total_parts.ToString("c");
label9.Text = total_tax.ToString("c");
label10.Text = grand_total.ToString("c");
}
private void button3_Click(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click(object sender, EventArgs e)
{
oilandlube();
carwash();
flushes();
misc();
partsandlabor();
summary();
}
private void ClearOilandlube()
{
checkBox1.Checked = false;
checkBox2.Checked = false;
}
private void ClearMisc()
{
checkBox5.Checked = false;
checkBox6.Checked = false;
checkBox7.Checked = false;
}
private void ClearFlushes()
{
checkBox3.Checked = false;
checkBox4.Checked = false;
}
private void ClearSummary()
{
label7.Text = "";
label8.Text = "";
label9.Text = "";
label10.Text = "";
}
private void button2_Click(object sender, EventArgs e)
{
ClearOilandlube();
ClearMisc();
ClearFlushes();
ClearSummary();
radioButton1.Checked = false;
radioButton2.Checked = false;
radioButton3.Checked = false;
radioButton4.Checked = false;
radioButton5.Checked = false;
radioButton6.Checked = false;
radioButton7.Checked = false;
textBox1.Text = "0";
textBox2.Text = "0";
}
}
}
When you clear the contents of your controls, you should also clear the values of the backing variables, so they don't retain their previous values. You should be able to just set them back to zero in your Clear methods.
For example, oil and lube might look like:
private void ClearOilandlube()
{
checkBox1.Checked = false;
checkBox2.Checked = false;
Oil_change = 0;
Lube_job = 0;
Mixed = 0;
Regular = 0;
Full_Synthetic = 0;
}
It looks like you're holding state of some your variables globally so you can access them elsewhere.
Mixed = 10;
You'll have to reset that to some default value as well.

Stopping the calculations because of predicted error

I am unsure how to ask this question as I can't quite well translate it.
I am currently working on my own Windows Form Application that will calculate the dimensions of a given package in inches (written all together in string format) and calculate the dimensions in centimeters, milimeters or even meters and at this point I was wondering what if someone entered wrong dimensions and given measures can not be parsed.
Something like Environment.Exit(), but without closing the application just stopping calculations and writing a message that an error has occured.
If there is a question like this answered, please do link it because I haven't been able to find it.
namespace PretvaranjeDimenzija
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public double mjera = 1;
public bool pogreska = false;
public string mjeraKratica = " cm";
public string dimenzijeIspis = "";
private void buttonIzracunaj_Click(object sender, EventArgs e)
{
string dim = textBoxDimenzije.Text;
if (dim.Contains('.'))
{
dim = dim.Replace('.', ',');
}
if (dim.Length != 0)
{
if (dim.IndexOf('x') != -1)
{
string[] multiDim = dim.Split('x');
double[] multiDimCentimetara = new double[multiDim.Length];
bool[] uspjeh = new bool[multiDim.Length];
for (int i = 0; i < multiDim.Length; i++)
{
uspjeh[i] = double.TryParse(multiDim[i], out multiDimCentimetara[i]);
if (uspjeh[i] == false)
{
pogreska = true;
goto kraj;
}
}
kraj:
if (pogreska == true)
{
MessageBox.Show("Doslo je do pogreske!");
pogreska = false;
}
else
{
double[] dimenzije = new double[multiDim.Length];
for (int i = 0; i < dimenzije.Length; i++)
{
dimenzije[i] = multiDimCentimetara[i] * 2.54 * mjera;
if (i == dimenzije.Length - 1)
{
dimenzijeIspis += dimenzije[i].ToString() + mjeraKratica;
}
else
{
dimenzijeIspis += dimenzije[i].ToString() + "x";
}
}
textBoxIspisDimenzija.Text = dimenzijeIspis;
dimenzijeIspis = "";
}
}
else
{
double dimCentimetara;
if(double.TryParse(dim, out dimCentimetara))
{
double dimenzija = dimCentimetara * 2.54 * mjera;
dimenzijeIspis = dimenzija.ToString() + mjeraKratica;
textBoxIspisDimenzija.Text = dimenzijeIspis;
dimenzijeIspis = "";
}
else
{
MessageBox.Show("Doslo je do pogreske!");
return;
}
}
}
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
mjera = 0.01;
mjeraKratica = " m";
if (radioButton2.Checked == true)
{
radioButton2.Checked = false;
radioButton1.Checked = true;
}
if (radioButton3.Checked == true)
{
radioButton3.Checked = false;
radioButton1.Checked = true;
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
mjera = 1;
mjeraKratica = " cm";
if (radioButton1.Checked == true)
{
radioButton1.Checked = false;
radioButton2.Checked = true;
}
if (radioButton3.Checked == true)
{
radioButton3.Checked = false;
radioButton2.Checked = true;
}
}
private void radioButton3_CheckedChanged(object sender, EventArgs e)
{
mjera = 10;
mjeraKratica = " mm";
if (radioButton2.Checked == true)
{
radioButton2.Checked = false;
radioButton3.Checked = true;
}
if (radioButton1.Checked == true)
{
radioButton1.Checked = false;
radioButton3.Checked = true;
}
}
}
It should be pretty simple, depending on your requirements. For example, you could just use a basic if block in your method.
void CalculateStuff()
{
// Get input. Do stuff.
if (IsInvalid)
{
MessageBox.Show("You did a bad thing.");
return; // exit the method.
}
// now that we know the input is good, do other stuff.
}
Substitute IsInvalid with whatever check condition you want that will return true if the input is not valid.

How to check if "Count equals 50 then"?

Edited question totally for more understanding.
I have a count function, and I have a label who checks the current count
Here is the label
private void currentCountLabel_TextChanged(object sender, EventArgs e)
{
}
How do I make so once the label reaches as example 50, a function starts. like play sound?
//////////////////////////////
Here is the current one that #btc sources, gave me
private void currentCountLabel_Click(object sender, EventArgs e)
{
if (String.Compare(currentCountLabel.Text, "5") == 0)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"sound.wav");
player.Play();
}
}
But it wont play automaticly, how do I make it to play when it reaches the number?
///////////////////////////////////////////////////////////////////////////////
private void currentCountLabel_TextChanged(object sender, EventArgs e)
{
if (String.Compare(currentCountLabel.Text, "5") == 0)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"meme.wav");
player.Play();
}
}
private void writeToFile()
{
if (Properties.Settings.Default.OBSToggle)
{
if (Properties.Settings.Default.ReverseOrder)
{
File.WriteAllText(#"Count.txt", String.Format("{0} {1}", Count.ToString(), Message));
}
else
{
File.WriteAllText(#"Count.txt", String.Format("{0} {1}", Message, Count.ToString()));
}
}
private void KeyBoardHook_KeyUp(object sender, KeyEventArgs e)
{
if (Properties.Settings.Default.HotKeyEnabled && e.KeyCode == Properties.Settings.Default.HotKeyIn)
{
if (Properties.Settings.Default.SaveCount)
{
Count = Count + 1;
Properties.Settings.Default.Count = Count;
currentCountLabel.Text = Properties.Settings.Default.Count.ToString();
}
else
{
Count = Count + 1;
currentCountLabel.Text = Count.ToString();
}
Message = messageTextBox.Text;
writeToFile();
e.Handled = true;
}
if (Properties.Settings.Default.HotKeyEnabled && e.KeyCode == Properties.Settings.Default.HotKeyDe && Count != 0)
{
if (Properties.Settings.Default.SaveCount)
{
Count = Count - 1;
Properties.Settings.Default.Count = Count;
currentCountLabel.Text = Properties.Settings.Default.Count.ToString();
}
else
{
Count = Count - 1;
currentCountLabel.Text = Count.ToString();
}
Message = messageTextBox.Text;
writeToFile();
e.Handled = true;
}
}
You need a static variable to hold the current count. Initialized to zero. Then increment it each time the function executes.
Then an if statement to evaluate the count and take whatever action.

if(!IsPostback) doesn't exist in the current context

I'm building a web application using a webform and I'm trying to store a counter in a Session, but I'm getting the error that if(!IsPostback) doesn't exist in the current context. Can anyone help me with this issue?
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
Session["AttemptCount"] = 0;
}
}
protected void submitAnswerButton_Click(object sender, EventArgs e)
{
//difficultyList.SelectedIndex = 2;
answerStatus.Visible = true;
int answer = randomNumber1 + randomNumber2;
int counter = (int)Session["AttemptCount"];
if (mathAnswerTextBox.Text == answer.ToString())
{
counter++;
Session["AttemptCount"] = counter;
answerStatus.Text = "Correct!";
// scoreLabel.Text = "Score: " + counter.ToString();
randomNumber1 = random.Next(0, 50);
randomNumber2 = random.Next(0, 50);
num1Label.Text = Convert.ToString(randomNumber1);//add this line
num2Label.Text = Convert.ToString(randomNumber2); //and this line
num1Label.Visible = true;
num2Label.Visible = true;
mathAnswerTextBox.Visible = true;
submitAnswerButton.Visible = true;
}
else if (mathAnswerTextBox.Text != answer.ToString())
{
answerStatus.Text = "Incorrect";
incorrectStrikes.Text = counter.ToString();
num1Label.Visible = true;
num2Label.Visible = true;
mathAnswerTextBox.Visible = true;
submitAnswerButton.Visible = true;
// scoreLabel.Text = counterArray[0].ToString();
}
As I previously mentioned in my comment to your question, your original problem was with the lowercase b in Postback. The reason your "AttemptCount" session variable is not being incremented is because your if statement only increments it:
if (mathAnswerTextBox.Text == answer.ToString())
I think you want to do this in the else clause of your if statement, and not when the answer is correct.

StreamReader file how to ONLY update when high score is reached in listbox?

How do I write my StreamReader file where it will ONLY override the game(s) high score if it is over the current high score? Currently all scores are being updated to the listbox instead of just the scores that exceed the current score/txt file.
Thanks in Advance
public partial class Form1 : Form
{
int Dice;
int RunningTotal;
int MaxRolls;
int RollCount;
Random rand = new Random();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
RollDiebutton.Enabled = true;
StartOverbutton.Enabled = true;
ClickBeginGametoStartlabel.Visible = false;
int beginTotal = 0;
TotalMoneyEarnedlabel.Text = beginTotal.ToString("c");
MaxRolls = rand.Next(3) + 2;
}
private void button4_Click(object sender, EventArgs e)
{
try
{
string highScore;
StreamReader inputFile;
inputFile = File.OpenText("Highscore.txt");
HighscoreBox.Items.Clear();
while (!inputFile.EndOfStream)
{
highScore = inputFile.ReadLine();
HighscoreBox.Items.Add(highScore);
}
inputFile.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
RollDiebutton.Enabled = false;
BeginGamebutton.Enabled = true;
StartOverbutton.Enabled = false;
TotalMoneyEarnedlabel.Text = "";
BeginpictureBox.Image = P2Kbembow.Properties.Resources.Begin;
Pressyourluckandrollagainlabel.Visible = false;
ClickBeginGametoStartlabel.Visible = true;
}
private void button2_Click(object sender, EventArgs e)
{
//Close Form
this.Close();
}
private void RollDiebutton_Click(object sender, EventArgs e)
{
Random rand = new Random();
Dice = rand.Next(6) + 1;
RunningTotal += 0;
int DollarAmount = 100;
int Sum = (Dice * DollarAmount);
BeginGamebutton.Enabled = false;
Pressyourluckandrollagainlabel.Visible = true;
RunningTotal += Sum;
TotalMoneyEarnedlabel.Text = RunningTotal.ToString("c");
RollCount += 1;
if (MaxRolls == 0)
{
Random getMax = new Random();
TotalMoneyEarnedlabel.Text = "";
}
else
if (RollCount >= MaxRolls)
{
MaxRolls = 6;
RollCount = 0;
RunningTotal = 0;
TotalMoneyEarnedlabel.Text = "$0.0";
Show(); MessageBox.Show("Sorry! You lose!");
RollDiebutton.Enabled = false;
BeginGamebutton.Enabled = true;
TotalMoneyEarnedlabel.Text = "";
BeginpictureBox.Image = P2Kbembow.Properties.Resources.Begin;
Pressyourluckandrollagainlabel.Visible = false;
ClickBeginGametoStartlabel.Visible = true;
StartOverbutton.Enabled = false;
return;
}
StreamWriter outputFile;
outputFile = File.CreateText("HighScore.txt");
outputFile.WriteLine(TotalMoneyEarnedlabel.Text);
outputFile.Close();
if (Dice == 1)
{
//shows Image of dice 1
BeginpictureBox.Image = P2Kbembow.Properties.Resources._1Die;
}
if (Dice == 2)
{
//shows Image of dice 2
BeginpictureBox.Image = P2Kbembow.Properties.Resources._2Die;
}
if (Dice == 3)
{
//shows Image of dice 3
BeginpictureBox.Image = P2Kbembow.Properties.Resources._3Die;
}
if (Dice == 4)
{
//shows Image of dice 4
BeginpictureBox.Image = P2Kbembow.Properties.Resources._4Die;
}
if (Dice == 5)
{
//shows Image of dice 5
BeginpictureBox.Image = P2Kbembow.Properties.Resources._5Die;
}
if (Dice == 6)
{
//shows Image of dice 6
BeginpictureBox.Image = P2Kbembow.Properties.Resources._6Die;
}
//Display Message Box of dice rolled
Show(); MessageBox.Show(" You rolled a " + Dice + "!");
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
string highScore;
StreamReader inputFile;
inputFile = File.OpenText("Highscore.txt");
HighscoreBox.Items.Clear();
while (!inputFile.EndOfStream)
{
highScore = inputFile.ReadLine();
HighscoreBox.Items.Add(highScore);
}
inputFile.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
The problematic part of your code is very trivial. To add only the highest score from your file to listbox you could just use:
var highScore = File.ReadAllLines("Highscore.txt").Max(score => decimal.Parse(score));
HighscoreBox.Items.Clear();
HighscoreBox.Items.Add(highScore);
But there are a number of other things you have to take care of:
You have to ensure there is a valid highscore sheet available. So check that in Form load (and may be you dont require to create and overwrite the existing file every time on rolling the die).
DRY your code to load the high score from file to listbox.
string _fileName = "Highscore.txt";
private void Form1_Load(object sender, EventArgs e)
{
if (!File.Exists(_fileName))
{
File.Create(_fileName);
return;
}
LoadHighestScore();
}
private void LoadHighestScore()
{
HighscoreBox.Items.Clear();
var highestScore = GetHighestScore();
HighscoreBox.Items.Add(highestScore);
}
private decimal GetHighestScore()
{
var scores = File.ReadAllLines(_fileName);
if (scores.Length == 0)
return 0;
return scores.Max(score => decimal.Parse(score));
}
You can write the score to your file every time upon rolling the die like this:
private void RollDiebutton_Click(object sender, EventArgs e)
{
//-------------------------
//-------------------------
WriteScore(score);
//-------------------------
//-------------------------
}
private void WriteScore(string score)
{
File.AppendAllLines(sd, new string[]{ score });
}
Mind you this appends the scores to your file every time. If you need to write only if the score beats the existing highest score (which is not very clear from your question) you could do:
private void WriteScore(string score)
{
if (int.Parse(score) > GetHighestScore())
File.AppendAllLines(sd, new string[]{ score });
}
Please break down your large section of code to different methods so that it aids code reuse. Even better if you can move the logics to a different class.
To do this kind of thing, its better to use a small lightweight client database like SQLite. In future what if you need more complex operation like "highest score for every user" ? To get the max score you could do:
SELECT MAX(score) FROM highscores;
As simple as that.
Lastly please post the problematic section of your code rather than whole bunch of irrelevant lines.

Categories

Resources