I have to programming a triangle-calculator, that can calculate from three given values all the other missing information's. I do know how I can calculate the values - that isn't the problem.
But I don't know, how I can programming that in a good way.
The interface looks like this:
With this 12 input-fields there are many possible combinations. My first idea was to use if/else statements for every combination. But that is not very efficient.
I'am sure, that there is a better solution, but I don't know how.
Can anybody help me?
EDIT
My code looks at the moment so:
protected void FlaecheBerechnen_Click(object sender, EventArgs e)
{
WerteAuslesen();
Berechnen();
}
protected void WerteAuslesen()
{
//Sides
string strSeite_a = this.txt_a.Text; if (strSeite_a == string.Empty) { i++; } else { if ((double.TryParse(strSeite_a, out seite_a) == false)) { GenerateErrorReport("Seite a"); } }
string strSeite_b = this.txt_b.Text; if (strSeite_b == string.Empty) { i++; } else { if ((double.TryParse(strSeite_b, out seite_b) == false)) { GenerateErrorReport("Seite b"); } }
string strSeite_c = this.txt_c.Text; if (strSeite_c == string.Empty) { i++; } else { if ((double.TryParse(strSeite_c, out seite_c) == false)) { GenerateErrorReport("Seite c"); } }
//Angles
string strWinkel_a = this.txtAlpha.Text; if (strWinkel_a == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_a, out winkel_a) == false)) { GenerateErrorReport("Winkel Alpha"); } }
string strWinkel_b = this.txtBeta.Text; if (strWinkel_b == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_b, out winkel_b) == false)) { GenerateErrorReport("Winkel Beta"); } }
string strWinkel_y = this.txtGamma.Text; if (strWinkel_y == string.Empty) { i++; } else { if ((double.TryParse(strWinkel_y, out winkel_y) == false)) { GenerateErrorReport("Winkel Gamma"); } }
//Height
string strHoehe_a = this.txt_ha.Text; if (strHoehe_a == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_a, out hoehe_a) == false)) { GenerateErrorReport("Höhe a"); } }
string strHoehe_b = this.txt_hb.Text; if (strHoehe_b == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_b, out hoehe_b) == false)) { GenerateErrorReport("Höhe b"); } }
string strHoehe_c = this.txt_hc.Text; if (strHoehe_c == string.Empty) { i++; } else { if ((double.TryParse(strHoehe_c, out hoehe_c) == false)) { GenerateErrorReport("Höhe c"); } }
//ErrorReport:
if (ErrorMessage != null)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('Folgende Angaben sind fehlerhaft: " + ErrorMessage + "');", true);
return;
}
//Logic
//If more than 3 values....
string AlertText;
if (i < 6)
{
AlertText = "Es dürfen nur 3 Angaben gemacht werden!";
Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + AlertText + "');", true);
return;
}
if (i > 6)
{
AlertText = "Es müssen mindestens 3 Angaben gemacht werden!";
Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + AlertText + "');", true);
return;
}
}
protected void Berechnen()
{
//Höhensatz
if (seite_a != 0 && seite_b != 0 && seite_c != 0)
{
//Calculate missing angles
//Winkel Gamma
cos_y = (seite_a * seite_a) + (seite_b * seite_b) - (seite_c * seite_c); //Zähler berechnen
cos_y = cos_y / (2 * seite_a * seite_b); //Durch Nenner teilen
winkel_y = Math.Acos(cos_y); //Bogenradius berechnen
winkel_y = winkel_y * 180 / Math.PI; //In Winkel umrechnen
//Winkel Beta
cos_b = (seite_c * seite_c) + (seite_a * seite_a) - (seite_b * seite_b); //Zähler berechnen
cos_b = cos_b / (2 * seite_c * seite_a); //Durch Nenn teilen
winkel_b = Math.Acos(cos_b); //Bogenradius berechnen
winkel_b = winkel_b * 180 / Math.PI; //In Winkel umrechnen
//Winkel Alpha
double winkel_a = 180 - winkel_b - winkel_y;
//Werte eintragen
txtAlpha.Text = Convert.ToString(winkel_a);
txtBeta.Text = Convert.ToString(winkel_b);
txtGamma.Text = Convert.ToString(winkel_y);
//Flächen berechnen
//Mit Satz des Heron
Heron heron = new Heron(seite_a, seite_b, seite_c);
double FlaecheHeron = heron.Area;
Page.ClientScript.RegisterStartupScript(this.GetType(), "ErrorAlert", "alert('" + FlaecheHeron + "');", true);
}
}
The problem is, that there are so much possible combinations.
if (seite_a != 0 && seite_b != 0 && seite_c != 0), etc, etc....
You could write down all the rules you could possibly use to perform your computations. I guess you'd use angle sum, law of sines, law of cosines, and so on. Write each of these rules as a class, and create an instance for each possible labeling for each of these (i.e. whether you're using the law of cosines to compute γ or β). You should end up with a list of objects, all sharing a common interface, which you can use to compute some values from some others. You could then iterate over this list to see which rules apply, and use them to compute additional values. Once the count of missing values reaches zero, you are done.
If you iterate over all your rules without finding a rule to apply, then your set of possible rules isn't complete enough. I believe that it would be a very good idea to write a unit test which tries out all 220 possible ways to fill in three out of twelve inputs, to make sure that you have a sufficient set of rules to handle all of them. Simply start with a complete set of 12 values, compute all three-element subsets, feed them into your application code and compare the results against the expected values, taking numerical errors into account.
The above approach is neither optimized for performance nor for numeric stability. If either of these is an issue for you, a different approach might be better suited.
Related
I am creating an XML from a backend that is supposed to be fed into a GDSN datapool. The company has a very old backend which only has their own PLU number and barcode attached to every item. What I know is that (at least here in Iceland) most GTIN are the EAN-13 barcode with a padded 0 at the front although this is not always the case. Do you know of a library that could check if a GTIN is correct i.e. would calculate the check digit?
I am using a windows form and am using C#.
First to validate what you want to do:
https://www.gs1.org/services/check-digit-calculator
Then you have 2 possibilities for GTIN since it must be 14 digits long.
The case you described, then you pad a 0 on the left
A GTIN with right length is provided directly (which is possible and left digit will not be 0)
Here is a quick example on how you can check this, based on the fact you know the gtin string only contains digits:
public Boolean ValidateGTIN(string gtin)
{
string tmpGTIN = gtin;
if (tmpGTIN.Length < 13)
{
Console.Write("GTIN code is invalid (should be at least 13 digits long)");
return false;
}
else if (tmpGTIN.Length == 13)
{
tmpGTIN = "0" + gtin;
}
// Now that you have a GTIN with 14 digits, you can check the checksum
Boolean IsValid = false;
int Sum = 0;
int EvenSum = 0;
int CurrentDigit = 0;
for (int pos = 0; pos <= 12; ++pos)
{
Int32.TryParse(tmpGTIN[pos].ToString(), out CurrentDigit);
if (pos % 2 == 0)
{
EvenSum += CurrentDigit;
}
else
{
Sum += CurrentDigit;
}
}
Sum += 3 * EvenSum;
Int32.TryParse(tmpGTIN[13].ToString(), out CurrentDigit);
IsValid = ((10 - (Sum % 10)) % 10) == CurrentDigit;
if (!IsValid)
{
Console.Write("GTIN code is invalid (wrong checksum)");
}
return IsValid;
}
Thanks for that. This is almost there. I would like to take it a step further - I am going to copy your code and add a little:
//First create a function only for validating
//This is your code to almost all - variable names change
public Boolean validateGTIN(string gtin)
{
Boolean IsValid = false;
int Sum = 0;
int EvenSum = 0;
int CurrentDigit = 0;
for (int pos = 0; pos <= 12; ++pos)
{
Int32.TryParse(gtin[pos].ToString(), out CurrentDigit);
if (pos % 2 == 0)
{
EvenSum += CurrentDigit;
}
else
{
Sum += CurrentDigit;
}
}
Sum += 3 * EvenSum;
Int32.TryParse(GTIN[13].ToString(), out CurrentDigit);
IsValid = ((10 - (Sum % 10)) % 10) == CurrentDigit;
if (!IsValid)
{
Console.Write("GTIN code is invalid (wrong checksum)");
}
return IsValid;
}
//Here we change quite a bit to accommodate for edge cases:
//We return a string which is the GTIN fully formed or we throw and exception.
public String createGTIN(string bcFromBackend)
{
string barcodeStr = bcFromBackend;
//Here we check if the barcode supplied has fewer than 13 digits
if (barcodeStr.Length < 13)
{
throw new System.ArgumentException("Barcode not an EAN-13
barcode");
}
//If the barcode is of length 13 we start feeding the value with a padded 0
//into our validate fuction if it returns false then we pad with 1 and so on
//until we get to 9. It then throws an error if not valid
else if (barcodeStr.Length == 13)
{
if(validateGTIN("0"+ barcodeStr))
{
return "0" + barcodeStr;
}
else if(validateGTIN("1" + barcodeStr))
{
return "1" + barcodeStr;
}
else if(validateGTIN("2" + barcodeStr))
{
return "2" + barcodeStr;
}
else if(validateGTIN("3" + barcodeStr))
{
return "3" + barcodeStr;
}
else if(validateGTIN("4" + barcodeStr))
{
return "4" + barcodeStr;
}
else if(validateGTIN("4" + barcodeStr))
{
return "4" + barcodeStr;
}
else if(validateGTIN("5" + barcodeStr))
{
return "5" + barcodeStr;
}
else if(validateGTIN("6" + barcodeStr))
{
return "6" + barcodeStr;
}
else if(validateGTIN("7" + barcodeStr))
{
return "7" + barcodeStr;
}
else if(validateGTIN("8" + barcodeStr))
{
return "8" + barcodeStr;
}
else if(validateGTIN("9" + barcodeStr))
{
return "9" + barcodeStr;
} else {
throw new System.InvalidOperationException("Unable to create valid
GTIN from given barcode")
}
}
//Lastly if the barcode is of length 14 we try with this value. Else throw
//error
else if(barcodeStr.Length == 14)
{
if(validateGTIN(barcodeStr)
{
return barcodeStr;
}
else
{
throw new System.InvalidOperationException("Unable to create valid
GTIN from given barcode");
}
}
Hopefully this makes sense. I have not sent the code through testing as I don't have my IDE on my current computer installed. Is
Just a quick one guys - y'know when your brain hurts just looking at something. Just seeing if there is a "better" way to do this in terms of boolean logic.
private RegenerationType AccquireRegenerationState (int floor, int playerFloor)
{
bool entranceExists = (floorBlocks[floor].doorBlocks.Count != 0) ? true : false;
if (floor + 1 == playerFloor || !floorBlocks[floor + 1].isVisited)
{
if (entranceExists)
{
return RegenerationType.Still;
}
else
{
return RegenerationType.Limit;
}
}
else
{
if (entranceExists)
{
return RegenerationType.Prime;
}
else
{
return RegenerationType.Full;
}
}
}
I guess that's the best you can achieve. Of course, assuming that you maintain code readability and clearness:
private RegenerationType AccquireRegenerationState (int floor, int playerFloor)
{
var entranceExists = floorBlocks[floor].doorBlocks.Count != 0;
var whatever = floor + 1 == playerFloor || !floorBlocks[floor + 1].isVisited;
if (whatever)
{
return entranceExists ? RegenerationType.Still : RegenerationType.Limit;
}
else
{
return entranceExists ? RegenerationType.Prime : RegenerationType.Full;
}
}
bool entranceExists = (floorBlocks[floor].doorBlocks.Count != 0);
return
(floor + 1 == playerFloor || !floorBlocks[floor + 1].isVisited)?
(entranceExists? RegenerationType.Still: RegenerationType.Limit):
(entranceExists? RegenerationType.Prime: RegenerationType.Full);
i have a form with more than one NumericUpDown as controls to input answer. i want every input is true for an operation (multiplication, sum etc), NumericUpDown for that operation will be disable. i have used the code below (just for sum operation), but i think its not efficient because i have to make a method to check every operation.
private void IsSumTrue() {
if (add1 + add2 == sum.Value)
{
sum.Enabled = false;
}
}
private void IsDifferenceTrue()
{
if (add1 - add2 == difference.Value)
{
difference.Enabled = false;
}
}
private void IsProductTrue()
{
if (add1 * add2 == product.Value)
{
product.Enabled = false;
}
}
private void IsQuotientTrue()
{
if (add1 / add2 == quotient.Value)
{
quotient.Enabled = false;
}
}
anyone have idea how to make it more efficient with just a method for all operation?
below is my idea, but to check the value is true for every NumericUpDown i don't know how.
private void DisableIfValueIsTrue()
{
foreach(Control control in this.Controls)
{
NumericUpDown value = control as NumericUpDown;
// if(value [NEED HELP]
}
}
Considering your situtaion, you can set a tag for each NumericUpDown in design mode like this:
sum.Tag=1;
square.Tag=2;
etc
Then define some int variables:
int iSum=add1+add2;
int iSquare= //Whatever you want
etc
And finally loop through your controls this way:
foreach (NumericUpDown control in this.Controls.OfType<NumericUpDown>())
{
int intCondition = Convert.ToInt32(control.Tag) == 1
? iSum
: Convert.ToInt32(control.Tag) == 2
? iSquare
: Convert.ToInt32(control.Tag) == 3
? i3
: i4; //You should extend this for your 8 controls
control.Enabled = intCondition == control.Value;
}
OK! Second way I offer
Since you will have to always check 8 different conditions, you could simply forget about looping through the controls and just change your method like this:
private void DisableIfValueIsTrue()
{
sum.Enabled = add1 + add2 != sum.Value;
difference.Enabled= add1 - add2 != difference.Value;
product.Enabled= add1 * add2 != product.Value;
quotient.Enabled= (add2 !=0) && (add1 / add2 != quotient.Value);
//etc
}
I came across this while doing some research and would like to give my solution I used for my situation and hope it helps people. I needed minimum and maximum numbers for a calculation, so mine are named appropriately and I correlated these with some CheckBoxes. I used null in beginning of minimum and end of maximum to account for empty. I also had to create an event handler SubscribeToEvents() shown below.
In my load event for my form:
SubscribeToEvents();
_checkBoxs = new[] { cbXLight, cbLight, cbMedium, cbHeavy, cbXHeavy, cbXXHeavy, cbXXXHeavy };
_minimumsNumericUpDowns = new[] { null, nLightMin, nMediumMin, nHeavyMin, nXHeavyMin, nXXHeavyMin, nXXXHeavyMin };
_maximumsNumericUpDowns = new[] { nXLightMax, nLightMax, nMediumMax, nHeavyMax, nXHeavyMax, nXXHeavyMax, null };
then I created a method:
private void DisableNumericUpDowns()
{
// disable everything:
foreach (var n in _minimumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
foreach (var n in _maximumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
}
The event handler:
private bool _eventsSubscribed;
private void SubscribeToEvents()
{
if (_eventsSubscribed)
return;
_eventsSubscribed = true;
cbXXHeavy.CheckedChanged += CheckBox_NumericState;
cbXHeavy.CheckedChanged += CheckBox_NumericState;
cbXLight.CheckedChanged += CheckBox_NumericState;
cbHeavy.CheckedChanged += CheckBox_NumericState;
cbLight.CheckedChanged += CheckBox_NumericState;
cbMedium.CheckedChanged += CheckBox_NumericState;
cbXXXHeavy.CheckedChanged += CheckBox_NumericState;
}
Now I can used this to check when they are enabled and if they are greater than or less than 0 if needed in the method CheckBox:
private void CheckBox_NumericState(object sender, EventArgs e)
{
// disable everything
DisableNumericUpDowns();
// see if more than one checkbox is checked:
var numChecked = _checkBoxs.Count((cb) => cb.Checked);
// enable things if more than one item is checked:
if (numChecked <= 1) return;
// find the smallest and enable its max:
var smallest = -1;
for (var i = 0; i < _checkBoxs.Length; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
smallest = i;
break;
}
// find the largest and enable its min:
var largest = -1;
for (var i = _checkBoxs.Length - 1; i >= 0; i--)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
largest = i;
break;
}
// enable both for everything between smallest and largest:
var tempVar = largest - 1;
for (var i = (smallest + 1); i <= tempVar; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
}
}
So I can check each state as required:
I want to check if Extra Light is check:
// Extra Light
if (!cbXLight.Checked) return;
if (nXLightMax.Enabled == false)
{
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
if (nXLightMax.Value > 0)
{
_dMax = nXLightMax.Value;
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Extra Light Max cannot be zero (0)");
}
}
and next light checks both:
// Light
if (cbLight.Checked)
{
if (nLightMin.Enabled == false && nLightMax.Enabled == false)
{
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMin.Enabled && nLightMin.Value > 0)
{
if (nXLightMax.Enabled && nLightMin.Enabled && nLightMax.Enabled == false)
{
_dMin = nLightMin.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMax.Value > 0)
{
_dMin = nLightMin.Value;
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
return;
}
}
}
else if (nLightMin.Enabled == false && nLightMax.Enabled)
{
if (nLightMax.Value > 0)
{
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
}
}
else
{
MessageBox.Show(#"Light Min cannot be zero (0)");
return;
}
}
}
Hope this helps someone.
Tim
thanks for #AlexJoliq and #BrettCaswell. just want to inform that before Alex edited his answer from using "==" to "!=", i (thought) already solved the problem. but i don't know where is the more effective and efficient way, alex's or mine.
below is my code for DisableIfValueIsTrue():
if (add1 + add2 == sum.Value) sum.Enabled = false;
if (add1 - add2 == difference.Value) difference.Enabled = false;
if (add1 * add2 == product.Value) product.Enabled = false;
if (add1 / add2 == quotient.Value) quotient.Enabled = false;
I am trying to use mod division to determine whether a year in a loop is a census or election year, and I have two issues:
1. I cannot get the wording in line with the year for ex:
It is like:
2000
this is an election year
this is a census year
2001
but I need it to say:
2000, this is an election year, this is a census year
2001 etc
2 : My math is some sort of wrong but I am having trouble identifying why or where, the division needs to apply to a user entered year range, and it needs to divide each year by 10, or 4, and the years that have no remainder are election or census years, but it is not doing that properly, it is not dividing all of the years, just some. My code is this:
private void buttonGo_Click(object sender, EventArgs e)
{
//Variables
int startYr = 0;
int endYr = 0;
int yearDisp = 0;
//Input Validation
startYr = int.Parse(textBoxStartYr.Text);
endYr = int.Parse(textBoxEndYr.Text);
if (int.TryParse(textBoxStartYr.Text, out startYr))
{
//correct
}
else
{
MessageBox.Show("Please enter a four digit year");
return;
}
if (int.TryParse(textBoxEndYr.Text, out endYr))
{
//correct
}
else
{
MessageBox.Show("Please enter a four digit year");
return;
}
//Loop
for (yearDisp = startYr; yearDisp <= endYr; yearDisp++)
{
listBoxDisp.Items.Add("Year:" + yearDisp.ToString());
if (checkBoxCensus.Checked == true )
{
if ((yearDisp % 10) == 0)
{
listBoxDisp.Items.Add("This is a census year");
}
else { }
}
else
{
//nothing needed
}
if (checkBoxElection.Checked == true)
{
if ((yearDisp % 4) == 0)
{
listBoxDisp.Items.Add("This is an election year");
}
else { }
}
else
{
//nothing
}
}
}
Try this:
private void buttonGo_Click(object sender, EventArgs e)
{
// Variables
int startYr = 0;
int endYr = 0;
bool checkForCensus = checkBoxCensus.Checked;
bool checkForElection = checkBoxElection.Checked;
// Input Validation
string errorMsg = "";
if (!int.TryParse(textBoxStartYr.Text, out startYr))
errorMsg += "Please enter a four digit year";
if (!int.TryParse(textBoxEndYr.Text, out endYr))\
errorMsg += String.Format("{0}Please enter a four digit year",
errorMsg == "" ? "" : " ");
if (errorMsg != "")
{
MessageBox.Show(errorMsg);
return;
}
// Loop
for (int yearDisp = startYr; yearDisp <= endYr; yearDisp++)
{
bool isCensusYear, isElectionYear;
if (checkForCensus && (yearDisp % 10) == 0)
isCensusYear = true;
if (checkForElection && (yearDisp % 4) == 0)
isElectionYear = true;
listBoxDisp.Items.Add(String.Format("{0}: {1}{2}{3}",
yearDisp.ToString(),
isCensusYear ? "this is a census year" : "",
(isCensusYear && isElectionYear) ? "," : "",
isElectionYear ? "this is an election year" : ""
));
}
}
Notes:
The empty if and else statements are unnecessary. I have removed the to make them more concise.
On the topic of conditionals in if statements: the ! means "not" or "the opposite of". Examples: !false == true and !true == false.
You do not need the initial int.Parse() statements because TryParse()'s second parameter is an out parameter (it outputs the parsed integer).
I created two variables which get the value of the check box. That way you don't have to check the value every time the loop is executed.
I used a ternary operator and String.Format() to determine what text to display.
Although you didn't mention it, I did change the input validation so that only one message box is displayed.
Try this for your listbox issue.
for (yearDisp = startYr; yearDisp <= endYr; yearDisp++)
{
int index = listBoxDisp.Items.Add("Year:" + yearDisp.ToString());
if (checkBoxCensus.Checked == true)
{
if ((yearDisp % 10) == 0)
{
listBoxDisp.Items[index] += ",This is a census year";
}
else { }
}
else
{
//nothing needed
}
if (checkBoxElection.Checked == true)
{
if ((yearDisp % 4) == 0)
{
listBoxDisp.Items[index] += ",This is an election year";
}
else { }
}
else
{
//nothing
}
}
Try something like this:
private void buttonGo_Click(object sender, EventArgs e)
{
//Variables
int startYr = 0;
int endYr = 0;
int yearDisp = 0;
//Input Validation
if (!int.TryParse(textBoxStartYr.Text, out startYr))
{
MessageBox.Show("Please enter a four digit year");
return;
}
if (!int.TryParse(textBoxEndYr.Text, out endYr))
{
MessageBox.Show("Please enter a four digit year");
return;
}
//Loop
for (yearDisp = startYr; yearDisp <= endYr; yearDisp++)
{
bool isElection = 0 == (yearDisp % 4);
bool isCensus = 0 == (yearDisp % 10);
if (isCensus && checkBoxCensus.Checked && isElection && checkBoxElection.Checked)
{
listBoxDisp.Items.Add(String.Format("{0} This is a both a census year and an election year", yearDisp));
}
else if (isCensus && checkBoxCensus.Checked)
{
listBoxDisp.Items.Add(String.Format("{0} This is a census year", yearDisp));
}
else if (isElection && checkBoxElection.Checked)
{
listBoxDisp.Items.Add(String.Format("{0} This is an election year", yearDisp));
}
else {
listBoxDisp.Items.Add(yearDisp.ToString());
}
}
}
Here's a more concise version of the for loop:
for (yearDisp = startYr; yearDisp <= endYr; yearDisp++)
{
bool isElection = (0 == (yearDisp % 4)) && checkBoxCensus.Checked;
bool isCensus = 0 == (yearDisp % 10) && checkBoxElection.Checked;
string text = yearDisp.ToString();
if (isCensus && isElection)
{
text += " This is a both a census year and an election year";
}
else if (isCensus)
{
text += " This is a census year", yearDisp;
}
else if (isElection)
{
text += " This is an election year";
}
listBoxDisp.Items.Add(text);
}
I am writing a Rock(Sten), Paper(Påse), Scissor(Sax) game, that plays against the computer. It works and all but I want to break the game when one off the two wins three times. But it keeps looping...
Im really new to programming so excuse if the code is messy... :(
And im Swedish so the code is in Swedish to... Hope you understand, if not ask me..
This is the Main:
static void Main(string[] args)
{
Game ssp = new Game();
Interaction.MsgBox("Welcome!");
string Choice = Interaction.InputBox("Chose Rock, Scissor eller Paper:");
ssp.Start();
ssp.Seewicharethevinner(Choice);
}
This is the class with the methods that handels the game:
string CompusterChoice;
//Starts the game
public void Start()
{
//Computers hand
Random rnd = new Random();
int x = rnd.Next(0, 3);
if (x == 0)
{ DatornsVal = "Rock"; }
else if (x == 1)
{ DatornsVal = "Paper"; }
else if (x == 2)
{ DatornsVal = "Scissor"; }
}
//Look who will win
public void Seewicharethewinner(string _Choice)
{
string PlayerChoice = _Choice;
string _PlayerChoice = _Choice.ToUpper();
string _ComputerChoice = ComputerChoice.ToUpper();
if (_PlayerChoice == _ComputerChoice)
{
Interaction.MsgBox("Tie!\nYour choice was: " + _Choice + "\n" + "Computer choice was: " + _ComputerChoice);
string Choice = Interaction.InputBox("Chose Rock, Scissor eller Paper:");
ssp.Start();
ssp.Seewicharethevinner(Choice);
}
else if (_ComputerChoice == "ROCK" && _PlayerChoice == "SCISSOR" || _ComputerChoice == "SICSSOR" && _PlayerChoice == "PAPER" || _ComputerChoice == "PAPER"
&& _PlayerChoice == "ROCK")
{
Interaction.MsgBox("You Lose!\nYour choice was: " + _Choice + "\n" + "Computer choice was: " + _ComputerChoice);
int player = 0;
int computer = 1;
Points(computer, player);
string Choice = Interaction.InputBox("Chose Rock, Scissor eller Paper:");
ssp.Start();
ssp.Seewicharethevinner(Choice);
}
else if (_ComputerChoice == "ROCK" && _PlayerChoice == "PAPER" || _ComputerChoice == "SICSSOR" && _PlayerChoice == "ROCK" || _ComputerChoice == "PAPER"
&& _PlayerChoice == "SICSSOR")
{
Interaction.MsgBox("You won!\nYour choice was: " + _Choice + "\n" + "Computer choice was: " + _ComputerChoice);
int player = 1;
int computer = 0;
Points(computer, player);
string Choice = Interaction.InputBox("Chose Rock, Scissor eller Paper:");
ssp.Start();
ssp.Seewicharethevinner(Choice);
}
}
public void Points(int _computer, int _player)
{
int computerpoints = 0;
int playerpoints = 0;
if (_computer > _player)
{
computerpoints++;
}
else
{
playerpoints++;
}
if (computerpoints == 3)
{
Interaction.MsgBox("Computer won three times!");
}
if (playerpoints == 3)
{
Interaction.MsgBox("You won three times!");
}
}
So it looks like the problem is that in your Poang method you check to see if someone has won 3 times and if so display a message, but after you check that you don't terminate the program. It just keeps going on as if nothing happened. Also, your win count variables are locally scoped, so they lose their value every time the function ends.
There are a lot of things that could be done to make this program better, however I am just going to provide the simplest fix here:
public void UtseVinnare(string _Val)
{
string SpelareVal = _Val;
string _SpelarVal = _Val.ToUpper();
string _DatornsVal = DatornsVal.ToUpper();
if (_DatornsVal == _SpelarVal)
{
Interaction.MsgBox("Oavgjort!\nDitt val var: " + SpelareVal + "\n" + "Datorns val var: " + DatornsVal);
string Val = Interaction.InputBox("Välj Sten, Sax eller Påse:");
Starta();
UtseVinnare(Val);
}
else if (_DatornsVal == "STEN" && _SpelarVal == "SAX" || _DatornsVal == "SAX" && _SpelarVal == "PÅSE" || _DatornsVal == "PÅSE"
&& _SpelarVal == "STEN")
{
Interaction.MsgBox("Du förlorade!\nDitt val var: " + SpelareVal + "\n" + "Datorns val var: " + DatornsVal);
int spelare = 0;
int dator = 1;
if (Poang(dator, spelare))
{
return;
}
string Val = Interaction.InputBox("Välj Sten, Sax eller Påse:");
Starta();
UtseVinnare(Val);
}
else if (_DatornsVal == "STEN" && _SpelarVal == "PÅSE" || _DatornsVal == "SAX" && _SpelarVal == "STEN" || _DatornsVal == "PÅSE"
&& _SpelarVal == "SAX")
{
Interaction.MsgBox("Du vann!\nDitt val var: " + SpelareVal + "\n" + "Datorns val var: " + DatornsVal);
int spelare = 1;
int dator = 0;
if (Poang(dator, spelare))
{
return;
}
string Val = Interaction.InputBox("Välj Sten, Sax eller Påse:");
Starta();
UtseVinnare(Val);
}
}
int datorpoangraknare = 0;
int spelarpoangraknare = 0;
public bool Poang(int _dator, int _spelare)
{
if (_dator > _spelare)
{
datorpoangraknare++;
}
else
{
spelarpoangraknare++;
}
if (datorpoangraknare == 3)
{
Interaction.MsgBox("Datorn vann tre gånger!");
return true;
}
if (spelarpoangraknare == 3)
{
Interaction.MsgBox("Du vann tre gåger!");
return true;
}
return false;
}
Instead of trying to fix your code with the current methods I would suggest adding the following to make your code easier to follow:
1: Use enums to give a clear meaning to numbers.
public enum Choice
{
Rock,
Paper,
Scissor
}
public enum WinResult
{
Won,
Tie,
Lost
}
2: Add a method to ask input from user and return the result.
private Choice GiveChoice()
{
// This is a label where we can jump to if the input was invalid.
start:
// Ask the question.
Console.Clear();
Console.WriteLine("Choose (0:Rock, 1:Paper, 2:Scissor):");
string answer = Console.ReadLine();
int result = -1;
// Validate and re-ask if invalid.
if (!int.TryParse(answer, out result) || (result < 0 && result > 2))
goto start;
return (Choice) result;
}
3: Add a method to compare 2 results from eachother.
// Returns if v1 has won, tied or lost from v2. (Left to right)
private WinResult CompareForWinner(Choice v1, Choice v2)
{
if (v1 == Choice.Paper)
{
if (v2 == Choice.Paper)
return WinResult.Tie;
if (v2 == Choice.Rock)
return WinResult.Lost;
return WinResult.Won;
}
if (v1 == Choice.Rock)
{
if (v2 == Choice.Paper)
return WinResult.Lost;
if (v2 == Choice.Rock)
return WinResult.Tie;
return WinResult.Won;
}
// v1 = Scissor.
if (v2 == Choice.Paper)
return WinResult.Won;
if (v2 == Choice.Rock)
return WinResult.Lost;
return WinResult.Tie;
}
It's not a direct answer to your question. But I think it will help you solve it yourself.
Surely the answer to this question should be go and read a book on programming c#?
I noticed that this is marked as a Duplicate above. When you go to that Duplicate that too is marked as a duplicate and only 11 hours ago.
I really don't think people should be just posting up their homework....