Why the code goes to else if the statement is true? - c#

I am trying to spawn my obstacles with level improvement, but for some reason when i tested it in game it doesn't work how i want.
Lets say i start game from 26 level.
I play normally until the level 36, even the 35 level spawning correctly but when player reach level exactly on 36 the code goes into else statement not in else if..
This is my code to spawn obstacles by levels..
if (curentLevel > 0 && curentLevel < 10)
{
SpawnSpawner(0);
}
else if (curentLevel > 10 && curentLevel < 35)
{
SpawnSpawner(1);
}
else if (curentLevel > 35 && curentLevel < 50)
{
SpawnSpawner(2);
}
else if (curentLevel > 50 && curentLevel < 60)
{
SpawnSpawner(5);
}
else
{
}
the code on in else statement gets executed which is empty in my example exactly on level 36.
I hope there is solution why because I told the program to check if curentlevel is higher then 35 which is on 36 level and if the level is smaller then 50 which is 36 , so I don't have idea why then its not executed this code:
else if (curentLevel > 35 && curentLevel < 50)
I bet I do something wrong but I hope someone will point me to solution and explain why program doesn't work on my way of thinking, thanks so much...

As per #Ruzihm's explaination in the comment, you're checking if less than 35 and bigger than 35, so when currentLevel is exactly equal to 35, it will not evaluate true in any conditions.
The solution, as per #DavidFreeman's answer in the comments - the solution to your issue is to make the code less complex:
if (curentLevel < 10)
{
SpawnSpawner(0);
}
else if (curentLevel < 35)
{
SpawnSpawner(1);
}
else if (curentLevel < 50)
{
SpawnSpawner(2);
}
else if (curentLevel < 60)
{
SpawnSpawner(5);
}
else
{
}
The if (currentLevel > 10) is redundant, if it doesn't evaluate true in currentLevel < 10 it will definitely be 10 OR MORE in the next else if.
If you must use specific ranges, you must take care to include all levels in the conditionals, like #BACON writes, with your current conditions you're covering the currentLevel 1-9, 11-34, 36-49, and 51-59, since 10 < 10 == false & 10 > 10 == false. You need to include the 10th level in one of the conditionals, like 10 <= 10 == true

Related

BMI & BMR calculator

I'm trying to create a method that takes a user's height, weight, and age, and returns their BMI and BMR.
I think I've done this fine.
However, the last thing I need to do is add some validation to make sure the user has put in some sensible numbers. The constraints being applied to the input are:
50 [cm] ≤ height ≤ 220 [cm]
10 [kg] ≤ weight ≤ 250 [kg]
18 [years] ≤ age ≤ 70 [years]
To do this, I've tried using if statements
if (getHight >= 220 && getHight <= 50)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getAge >= 70 && getAge <= 18)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getWeight >= 250 && getWeight <= 10)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
However, regardless of what I ender, nothing shows up in the console by way of validation errors. It just outputs my BMI and BMR.
What am I missing here?
Your mistake is that you are using AND instead of OR.
You cannot both be taller than 220cm and shorter than 50cm.
Use OR operators instead of AND:
if (getHight > 220 || getHight < 50)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getAge > 70 || getAge < 18)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
else if (getWeight > 250 || getWeight < 10)
{
Console.WriteLine("Unfortunately, your input is incorrect, please try again");
}
Also as #PaulF mentioned, you should not be using <= and >= since the valid range of values is inclusive. Since your logic is the inverse (invalid values), you should drop the = and just use < and >.
As already mentioned, you should be using || instead of && when doing the comparisons and you should be using < and > since the boundary values are acceptable. You might spend some time reading up on the Boolean logical operators - AND, OR, NOT, XOR so they all make sense, because they're very common and used in just about every program you'll write.
I just wanted to add another possible solution in case you're doing a lot of these types of comparisons, which is to write an extension method for them. This way you only have to write it once, which reduces the chance of error.
Below I have an extension method that tests if a number is between a minimum and maximum value (along with an option to specify if those boundary values as valid). Note that I assumed you're testing with an int type, but you can change the type easily by changing the this int value to this double value or this float value, or whatever numeric type you're using:
public static class Extensions
{
public static bool IsBetween(this int value, int min, int max,
bool inclusive = true)
{
return inclusive ?
min <= value && value <= max:
min < value && value < max;
}
}
Now if you include that class in your project, we can use this method to test if the value is not between our accepted values by using the ! not operator. Also note that I changed the else if to separate if statements. This way, if there's more than one error, they all get reported at the same time and the user can correct them all at once. I also changed the error message so the user actually knows what's wrong and how to fix it:
// In your program class, not in the Extensions class above
if (!getHeight.IsBetween(50, 220))
{
Console.WriteLine("ERROR: Height must be an integer between 50 and 220");
}
if (!getAge.IsBetween(18, 70))
{
Console.WriteLine("ERROR: Age must be an integer between 18 and 70");
}
if (!getWeight.IsBetween(10, 250))
{
Console.WriteLine("ERROR: Weight must be an integer between 10 and 250");
}

IF function with && and || at the same time

I want to do IF under serveral condition AND && and OR || on it
i have two range of number
Top1 - Bottom1 and
Top2 - Bottom2
and only executed when Currentnumber is within these two range
am i doing it okay ?
if (OnlyAbove == True
&& (Top1 > Currentnumber || Top2 > Currentnumber)
&& (Bottom1 < Currentnumber || Bottom2 < Currentnumber)
)
{
Statement
}
I'm going to go out on a limb and say: no, you're not doing right on this one - mostly because what your code is currently doing doesn't make sense.
One thing that helps out with stuff like this is to phrase it in common english - so you go from:
if (OnlyAbove == True
&& (Top1 > Currentnumber || Top2 > Currentnumber)
&& (Bottom1 < Currentnumber || Bottom2 < Currentnumber)
)
{
Statement
}
... to ...
if OnlyAbove
AND (CurrentNumber above at least one of the two Tops)
AND (CurrentNumber below at least one of the bottoms)
After all, the stuff between those inner parenthesis is saying "Top1 > current OR Top2 > current" - which really isn't what you're looking for.
Something that'll help out - not only writing code like this, but reading it down the line, is to go a bit overboard with variables. Variables are awesome at helping you document logic, since you can name them very descriptively.
So imagine code that looks like this:
bool betweenRange1 = (Currentnumber > Bottom1) && (Currentnumber < Top1);
bool betweenRange2 = (Currentnumber > Bottom2) && (Currentnumber < Top2);
if (OnlyAbove && betweenRange1 && betweenRange2)
{
Statement
}
... that IF statement starts to look a lot more readable - it's obvious at a glance at what it's getting at. If you're having trouble parsing IF statements, it's not a bad habit to get into. Maybe a bit overkill... but overkill's a lot better than having code you're not sure of what it's doing :-)

Expression brain fade

I'm having brain fade trying to write a single logical expression that suits the question's comment
// **Don't do xyz between 10.00pm and 7:30am**
//
if(hour > 22 || (hour < 7 && minutes < 30)
output("too early or too late");
Without coming up with something god awful like:
if (hour > 20)
"Too late";
if (hour < 7)
"Too early"
else
if (hour == 7 && minute < 30)
"Too early"
Please put me out of my misery.
|| is your friend here. If you have multiple conditions and if any of them are true you want to do something then instead of using
if (condition1)
do_something();
if (condition2)
do_something();
if (condition3)
do_something();
You can use
if (condition1 || condition2 || condition3)
do_something();
So to relate that to what you have your single if statement would be
if(hour > 21 || hour < 7 || (hour == 7 && minute < 30))
output("too early or too late");

Easier way to 'or' operators in if statements (C#)

I'm making a game in unity, and I have this 'if statement' that by every 5 waves my shop menu will become visible. The code does work, but I am certain I'm doing something wrong or could do something better!
if (waveCount == 5 || waveCount == 10 || waveCount == 15 || waveCount == 20 || waveCount == 25 || waveCount == 30 || waveCount == 35 || waveCount == 40 || waveCount == 45 || waveCount == 50)
{
// yield return new WaitForSeconds(shopWait);
shopPanel.SetActive(true);
}
As you can see the 'if statement' not that good, normally it continues all the way to waveCount == 100 but i cut that out. There must be a simpler or cleaner way to do this :/ but i just can't wrap my head around it :(
Edit 1:
Thanks, I didn't know much about modulo, know I know what I have to read about :)
You can use modulo operation:
if (waveCount % 5 == 0)
Yes, there are indeed simpler ways of doing this. If you use a little bit of maths and logic, you can figure this out.
Since you want to check whether the value of waveCount is a multiple of 5, you can use % to get the reminder of waveCount / 5. If that reminder is 0, waveCount is a multiple of 5.
if (waveCount % 5 == 0 && waveCount <= 100)
I added waveCount <= 100 to replicate your code's behaviour when waveCount is larger than 100 i.e. not get into the if statement.
Alternatively, you can put all the values into a list:
var list = new List<int>();
for (int i = 1 ; i <= 20 ; i++) {
list.Add(i * 5);
}
And then check whether the list contains the number:
if (list.Contains(waveNumber))
The advantage of this is that if you decided to change how the game works and say that the shop menu can be opened at waves 9, 52, and 77, you just add the numbers to the list, without modifying the if statement. This provides a lot of flexibility.
if (waveCount % 5 == 0 && waveCount <= 50) {
//...code
}
If your “if” statement's body just contains shopPanel.SetActive(true); you can do that without even using “if” like that.
shopPanel.SetActive(waveCount % 5 == 0 && waveCount <= 50);
Give it a try
if (waveCount % 5 == 0 && waveCount <= 50)
Use the modulo-operator:
if(waveCount % 5 == 0 && waveCount <= 100) ...
The operator calculates the remainder of an integer-divison. In your case the statement should return zero indicating that your number divided by 5 has no remainder.
Just to generalize: in case the data you have doesn't match a pattern, you can put all the things to match against in a set, then test the set for membership:
var thingsToMatch = Set(2, 5, 8, 14, 23, 80, 274...);
if (someNumber in thingsToMatch) {...}
As long as you know the set isn't being recreated everytime the function is called, this has proven to be fairly fast. If your language doesn't automatically cache the set, you can make it a static variable of the function.
You can use the remainder operator for this:
if (waveCount % 5 == 0 && waveCount > 0 && waveCount <= 50)
{
//yield return new WaitForSeconds(shopWait);
shopPanel.SetActive(true);
}
You can test whether the remainder of the division by 5 is 0, which means that the number is divisible by 5.
if (waveCount % 5 == 0 && waveCount >= 5 && waveCount <= 50)
C# performs integer math on integer number types (int, long, uint, ...).
Example:
13 / 5 = 2
I.e. you never get a decimal fraction part. The complementary operation is the modulo operation. It gives you the remainder of this division:
13 % 5 = 3
I.e., 13 / 5 is 2 plus remainder 3. Together, division and modulo operation allow you to perform the reverse operation.
(5 * (13 / 5)) + (13 % 5) =
(5 * 2 ) + ( 3 ) = 13
If you have irregular figures, quite different approaches are to use a switch statement:
switch (waveCount) {
case 5:
case 10:
case 15:
case 20:
case 25:
case 30:
case 35:
case 40:
case 45:
case 50:
shopPanel.SetActive(true);
break;
}
or an array of allowed values:
private static readonly int[] AllowedValues =
new int[] { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
if(Array.IndexOf(AllowedValues, waveCount) >= 0) { ... }

For-Statement, Each 1000th Walkthrough, do something

I'm walking through a Forloop 100'000 times. (that number can be diversified)
Every 1000th time I want do something specially, what I don't do in the other walkthroughs.
Something like that:
for (int i = 0; i < 100000; i++)
{
doTasks(); //Normal
if(i == 1000 || i == 2000 || i == 3000 || i == 4000 ) //and so on...
{
doSomethingElse(); //Special, For every 1000th walkthrough
}
}
What would be the most efficient way to accomplish that task?
Try with a modulo operator. Not sure about the C# syntax, but something like:
if(i % 1000 == 0)
{
//Do something
}
if (i != 0 && i % 1000 == 0)
It means if i mod 1000 is 0 (so on 1000, 2000, 3000, ...) but not on i == 0
if (i != 0 && i % 1000 == 0) {
doSomethingElse();
}
% is the modulus operator, returning the remainder of a division operation. If the remainder is zero then you have a multiple of 1000. However you need to exclude 0 specifically because 0 is evenly divisible by 1000 as well.
Using the modulo operator:
if (i % 1000 == 0) {
// do something...
will do what you want.
It divides by the given argument (in this case, 1000) and gives you the remainder. In this case you're interested in a remainder of 0. See the doc for the modulo operator here
I'm really nitpicking here, and potentially answering a dead horse, but do this:
if(i%1000 == 999) ...
Instead of comparing to 0 and avoiding the first iteration.
use operator % http://msdn.microsoft.com/en-us/library/6a71f45d.aspx

Categories