- Home /
Need help with multiple if statements.
So there are 2 variables, int Connections, and float Time, and a classification. Legendary, Epic, Excellent, and Good. I need to check to see which classification should be given. I am currently using if statements. I know there is a better way. If someone can see what my issue is, or a better way please let me know.
//------------Detect What Classification Was Earned---------------
//---References---
GameObject levelIntro = GameObject.Find("Level Introduction");
LevelIntroduction levelIntroScript = levelIntro.GetComponent<LevelIntroduction>();
int curConnections = GameLogic.getTotalConnections();
float curTime = GameLogic.getTotalTime();
if ((curConnections >= levelIntroScript.LegendConnect
&& curTime <= levelIntroScript.LegendTime)
&& !(curTime >= levelIntroScript.EpicTime))
{
classification = "Legendary";
}
if((curConnections >= levelIntroScript.EpicConnect && curTime <= levelIntroScript.EpicTime)
&& !(curTime >= levelIntroScript.ExcellentTime))
{
classification = "Epic";
}
if ((curConnections >= levelIntroScript.ExcellentConnect && curTime <= levelIntroScript.ExcellentTime)
&& !(curTime >= levelIntroScript.GoodTime))
{
classification = "Excellent";
}
if (curConnections >= levelIntroScript.GoodConnect && curTime <= levelIntroScript.GoodConnect)
{
{ classification = "Good"; }
}
//--------------------------------------------------------------------
You could have 3 arrays(times, connections and classifications) all populated in the same order
you could then do a loop and check the first 2 arrays against your curConnections and curTime.
If they meet the conditions then set your classification to the classification of the same index.
Shouldn't this:
if (curConnections >= levelIntroScript.GoodConnect && curTime <= levelIntroScript.GoodConnect)
{
{ classification = "Good"; }
}
be like this ins$$anonymous$$d?
if (curConnections >= levelIntroScript.GoodConnect && curTime <= levelIntroScript.GoodConnect)
{
classification = "Good";
}
also your last if statement is comparing curTime with GoodConnect
Answer by Uldeim · Nov 06, 2014 at 10:22 PM
You have a minor error in the final if statement; you're comparing Time to GoodConnect, which I presume should be GoodTime.
I have a couple of suggestions, though "better" in this case is really just going to be a matter of preference... everything is basically going to boil down to a bunch of ifs.
0) You should use 'else if's instead of the extra '&& !(time >= time)'. Presumably, if someone has a Legendary time, they do not also have an Epic time. Because you're doing your comparisons from high to low, using else ifs will always get you the highest possible qualifying score category.
1) Write a function to compare sets of scores.
bool isBetterScore(int ScoreConnections, float ScoreTime, int ReferenceConnections, float ReferenceTime)
{
if (ScoreConnections >= ReferenceConnections && ScoreTime <= ReferenceTime)
{
return true;
}
return false;
}
This looks better and is faster to write, but it's a little hard to see what's being compared, which leads us to...
2) Combine the scores into a single object, say... CombinedScore:
struct CombinedScore
{
int connections;
float time;
String scoreName;
public CombinedScore(String name, int conns, float t)
{
scoreName = name;
connections = conns;
time = t;
}
}
CombinedScore epicScore = new CombinedScore("Epic",
levelIntroScript.EpicConnections,
levelIntroScript.EpicTime);
With the first change (having a function), you can now change it to:
bool isBetterScore(CombinedScore playerScore, CombinedScore referenceScore)
..
.
This lets you hide most of the implementation details away in case you want to change them later. Don't Repeat Yourself, if possible.
3) Put the reference scores, in order, into a collection, then iterate (loop) over it:
CombinedScore epicScore = ...
...
List<CombinedScore> referenceScoresFromHighToLow = new List<CombinedScore>()
{ legendaryScore, epicScore, excellentScore, goodScore }
foreach (CombinedScore score in referenceScoresFromHighToLow)
{
if (isBetterScore(playerScore, score))
{
classification = score.scoreName;
break;
}
}
Because this goes from High to Low, like your ifs, the loop will break out with the highest possible score that meets the requirements. You could also do this with a LINQ Find, which looks a little bit nicer but is a little bit less explicit.
having issues following this. I see how it works but keep getting errors just trying to write it out
What sort of errors?
Note: I just fixed my constructor declaration for the struct; that might have been causing you problems.
This is what I have now. and I know i am missing parts to fill in but I am really confused
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class LevelExit : $$anonymous$$onoBehaviour {
public float padding;
public GUIStyle myStyle;
public string classification = "";
public int connections = 0;
public float time = 0.0f;
bool isBetterScore(int ScoreConnections, float ScoreTime, int ReferenceConnections, float ReferenceTime)
{
if (ScoreConnections >= ReferenceConnections && ScoreTime <= ReferenceTime)
{
return true;
}
return false;
}
void Awake()
{
GameObject levelIntro = GameObject.Find("Level Introduction");
LevelIntroduction levelIntroScript = levelIntro.GetComponent<LevelIntroduction>();
int curConnections = GameLogic.getTotalConnections();
float curTime = GameLogic.getTotalTime();
CombinedScore epicScore = new CombinedScore("Epic",
levelIntroScript.EpicConnect,
levelIntroScript.EpicTime);
}
struct CombinedScore
{
int connections;
float time;
string scoreName;
public CombinedScore(string name, int conns, float t)
{
scoreName = name;
connections = conns;
time = t;
}
}
List<CombinedScore> referenceScoresFromHighToLow = new List<CombinedScore>()
{ legendaryScore, epicScore, excellentScore, goodScore }
foreach (CombinedScore score in referenceScoresFromHighToLow)
{
if (isBetterScore(playerScore, score))
{
classification = score.scoreName;
break;
}
}
void OnGUI()
{
//Get the number of the current level. Since the range from 0, 1, 2+
//Add 1.
int level = Application.loadedLevel + 1;
GUI.Label(new Rect((Screen.width / 2) - (125 / 2), (Screen.height / 2) - (125 / 2) + padding + 25, 125, 25), "Level " + level.ToString(), myStyle);
GUI.Label(new Rect((Screen.width / 2) - (125 / 2), (Screen.height / 2) - (125 / 2) + padding, 125, 25), "Classification: " + classification, myStyle);
GUI.Label(new Rect((Screen.width / 2) - (125 / 2), (Screen.height / 2) - (125 / 2) + padding - 25, 125, 25), "Connections: " + GameLogic.getTotalConnections(), myStyle);
GUI.Label(new Rect((Screen.width / 2) - (125 / 2), (Screen.height / 2) - (125 / 2) + padding - 50, 125, 25), "Time: " + (int)GameLogic.getTotalTime(), myStyle);
}
}
Aha, I see. I didn't fill in all the blanks, the rest was left as "an exercise for the reader". ;)
Take a look here (http://pastebin.com/7Wj$$anonymous$$WJnw), I've put it in mostly final form, though I haven't tested it at all.
Yeah, sorry. I am still new to program$$anonymous$$g and trying to learn.. and i clicked that link but i t says it s been removed?
Answer by FairGamesProductions · Nov 06, 2014 at 10:21 PM
Using else if statements after the first if, may improve your scripts performance. That way if one of the conditions is met, then the script will not check the rest of the else if statements after the one that was found to be true.
Yeah this is probably what you're after.
Your classification will always be overwritten with "Good" otherwise.
The other option is to reorder your statements so Good is at the top and Legendary is at the bottom. So only greater classification will overwrite. else if is much cleaner.
Answer by NoseKills · Nov 06, 2014 at 10:47 PM
First you would need to decide and explain to us how you want it to work. If "connections" is Legendary but "time" is Excellent, do we take the highest value (Legendary based on connections), the lowest (Excellent based on time) or perhaps Epic because that falls between your connection ranking and time ranking.
Without knowing the answer, something like this might simplify the problem for you (not the neatest solution but since you don't want to use arrays etc...)
int timeRank = 0;
int connectionRank = 0;
if (curConnections >= levelIntroScript.LegendConnect)
{
connectionRank = 4;
} // use "else if" because if connections was Legendary, we don't even need to check if it was Epic
else if (curConnections >= levelIntroScript.EpicConnect)
{
connectionRank = 3;
}
else if (curConnections >= levelIntroScript.ExcellentConnect)
{
connectionRank = 2;
} // if you're supposed to always get at least "Good" rank, there's no need to compare the score
else // if (curConnections >= levelIntroScript.GoodConnect)
{
// everything less than the 3 top ranks gives a "good" rank
connectionRank = 1;
}
if (curTime <= levelIntroScript.LegendTime)
{
timeRank = 4;
} // use "else if" because if curTime was Legendary, we don't even need to check if it was Epic
else if (curTime <= levelIntroScript.EpicTime)
{
timeRank = 3;
}
else if (curTime <= levelIntroScript.ExcellentTime)
{
timeRank = 2;
} // if you're supposed to always get at least "Good" time, there's no need to compare the time
else // if (curTime <= levelIntroScript.GoodTime)
{
timeRank = 1;
}
// now you can check what ranks you got by evaluating the 2 numbers
int maxRank = Mathf.Max(timeRank, connectionRank);
int minRank = Mathf.Min(timeRank, connectionRank);
int avgRank = (timeRank + connectionRank) / 2f;
How its supposed to work is forexample, for Legendary you need to get 10 Connections within eed 12 seconds. For Epic, you need to get 8 connections in 14 seconds, But, if you get 10 connections in 13 seconds.. then that isnt qualified for legendary anymore so it would go as Epic. and it does this from Legendary down to good.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
C# if Statement Checking for Null Causing Null? 1 Answer
Distribute terrain in zones 3 Answers
C# Creating a List of If Statements 3 Answers
How to get around adding loads of "if" commands in my script 2 Answers