My else if's don't work - if-statement

I have no idea why my else if's aren't working!!!
var workSurvival:Number = 0;
var work:int = parseInt(work_txt.text);
if(work < 60 > 0){
workSurvival = work*12;
trace("work 1-" + workSurvival);
}else if(work < 120 > 60){
workSurvival = work*25;
trace("work 2-" + workSurvival);
trace(work);
}else if(work == 120){
bestScore -= 1;
trace("Good Score!");
}else if(work < 200 > 120){
workSurvival = work*8;
trace("work 3-" + workSurvival);
}else if(work < 401 > 200){
workSurvival = work*4;
trace("work 4-" + workSurvival);
}

if(work < 60 > 0) is not a valid IF statement. You need to rewrite it to be
if(work > 0 && work < 60)
The same goes for every other statement here.

Expanding on what howrad said: work < x > y is equivalent to (work < x) > y, so during evaluation it will end up as true > y or false < y (after work < x is evaluated) and not exhibit the desired range behavior ..
Now, how I would write it:
if(work < 60){
}else if(work < 120){
}else if(work == 120){
}else if(work < 200){
}else if(work < 401){
}else{
}
That is, "inch along": this works because the conditionals go from specific to general across the range and the first matching conditional will terminate the sequence of checks.

your conditions inside the if statements are incorrect
change them to
if(work>0&&work<60) instead of if(work < 60 > 0)
else if(work>60&&work<120) instead of else if(work < 120 > 60)
else if(work>120&&work<200) instead of else if(work < 200 > 120)
if(work>200&&work<401) instead of else if(work < 401 > 200)
and your code should work fine

Related

Mouse events not working as they should in functions

I am displaying a card stack and need to know the exact pinpoints of the pixels so I mapped out a function that should return whatever LMB location was at pressed time. The issue with this is that for some reason I can no longer see the cards.
I tried making the function a class member of Game, but then the mouse logic doesn't work at all. I still had MyMouse M; declared but its like the code was just ignored completely. I know how to overload functions and yet this just seems to defy logic.
Function for MouseLogic();
void MouseLogic() {
Game G;
Coordinates C;
MyMouse M;
G.PrintLL(10, 25, G.start_user);
G.PrintLL(10, 10, G.start_cpu);
while (1) {
M.ReadMouseInput();
switch (M.InputRecord.EventType)
{
case MOUSE_EVENT: // mouse input
if (M.InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
int x = M.InputRecord.Event.MouseEvent.dwMousePosition.X;
int y = M.InputRecord.Event.MouseEvent.dwMousePosition.Y;
cout << GetCardNumber(x, y);
}
}
}
}
Function for GetCardNumber
int GetCardNumber(int x, int y)
{
if ((x >= 10 && x <= 23) && (y >= 10 && y <= 25))
return 1;
else if ((x >= 41 && x <= 54) && (y >= 10 && y <= 25))
return 2;
else if ((x >= 72 && x <= 85) && (y >= 10 && y <= 25))
return 3;
else if ((x >= 45 && x <= 60) && (y >= 10 && y <= 25))
return 4;
else if ((x >= 78 && x <= 91) && (y >= 10 && y <= 25))
return 5;
else if ((x >= 10 && x <= 23) && (y >= 25 && y <= 40))
return 6;
else if ((x >= 41 && x <= 54) && (y >= 25 && y <= 40))
return 7;
else if ((x >= 72 && x <= 85) && (y >= 25 && y <= 40))
return 8;
else if ((x >= 45 && x <= 60) && (y >= 25 && y <= 40))
return 9;
else if ((x >= 78 && x <= 91) && (y >= 25 && y <= 40))
return 10;
else
return 0;
}
This seemed to work for anyone wondering! I just had to pass the class as an argument for some reason. Would still love an explanation for the logic behind this.
void MouseLogic(Game G) {
Coordinates C;
MyMouse M;
G.PrintLL(10, 25, G.start_user);
G.PrintLL(10, 10, G.start_cpu);
while (1) {
M.ReadMouseInput();
switch (M.InputRecord.EventType)
{
case MOUSE_EVENT: // mouse input
if (M.InputRecord.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
{
int x = M.InputRecord.Event.MouseEvent.dwMousePosition.X;
int y = M.InputRecord.Event.MouseEvent.dwMousePosition.Y;
cout << GetCardNumber(x, y);
}
}
}
}

How to make a loop to determine if 2 numbers belong in a given range

I am having problems making a loop which stops when both x and y are in the range/interval [0,1] in c++.
double x;
double y;
while(condition)
{
if(x < 0)
{
x = -x;
}
else
{
x = 2 - x;
}
if(y < 0)
{
y = -y;
}
else
{
y = 2 - y;
}
}
This method with 2 loops works:
while((x < 0) || (x > 1)) {do sth}
while((y < 0) || (y > 1)) {do sth}
This doesn't work:
while(!((x >= 0) && (x <= 1)) && !((y >= 0) && (y <= 1))) {do sth}
And this doesn't work either:
while(((x < 0) || (x > 1)) && ((y < 0) || (y > 1))) {do sth}
This makes an infinite loop (in my case):
while(((x < 0) || (x > 1)) || ((y < 0) || (y > 1))) {do sth}
Note: {do sth} changes x and y if needed so they will eventually go in that interval (same as in the first block of code).
Note 2: By doesn't work I mean it never goes in the loop when x is in the interval and y < 0 (and some other cases).
while ( !( (x>=0 && x<=1) && (y>=0 && y<=1) ) ) should be the combined conditional check.
I'd go for a dedicated function with a speaking name: so you can still understand your code in a couple of weeks :-), e.g.
auto check_outside_interval_0_1 = [] (double const a) {
return a < 0.0 or 1.0 < a;
};
while( check_outside_interval_0_1(x) or
check_outside_interval_0_1(y) ) {
// ... do your things here
}

How to return false from a for loop if any of the conditions are false

I'm working on a function which should return false if any of the point positions are outside of the defined rectangle boundaries.
My current c++ code is as follows:
bool trackingPointsVisible(){
//I've got 4 points here
if(!points.empty()){
// loop through each of the points
for(int i=0; i<points.size(); i++){
//check if points' x and y positions are out of the boundaries
if(points[i].x < -60 || points[i].x > 300 ||
points[i].y < -60 || points[i].y > 300){
// if any of them are out return false
return false;
}else{
//if they're within the boundaries, return true
return true;
}
}
}
}
For some reason, it returns true even if one of the points if out of the specified boundaries. I don't think this should be the case. Should I rewrite this function and check each point individually or is there another approach?
Could anyone please point what am I doing wrong here? Thanks.
You return based on the check of the first point, without proceeding to check any of the others. You should return false if you find a point outside the region, otherwise continue to check the remaining points, only returning true outside the loop.
For whatever it's worth, you can simplify the code a bit:
bool trackingPointsVisible()
{
for (const auto& point : points)
//check if points' x and y positions are out of the boundaries
if (point.x < -60 || point.x > 300 ||
point.y < -60 || point.y > 300)
return false;
return true;
}
...or, more declaratively...
bool trackingPointsVisible()
{
// check none of the points are out of bounds...
return std::none_of(std::begin(points), std::end(points),
[](const Point& point) {
return point.x < -60 || point.x > 300 ||
point.y < -60 || point.y > 300;
});
}
You can return true only in the end of the function:
bool trackingPointsVisible(){
//I've got 4 points here
if(!points.empty()){
// loop through each of the points
for(int i=0; i<points.size(); i++) {
//check if points' x and y positions are out of the boundaries
if(points[i].x < -60 || points[i].x > 300 ||
points[i].y < -60 || points[i].y > 300) {
// if any of them are out return false
return false;
}
}
}
return true;
}
First of all the function has undefined behavior because it returns nothing in case when the container points is empty.
Secondly you have to return true only if all points were checked. That is the return statement for true must be outside the loop.
The function can be defined the following way.
bool trackingPointsVisible()
{
//I've got 4 points here
size_t i = 0;
while ( i < points.size() and not
( points[i].x < -60 || points[i].x > 300 ||
points[i].y < -60 || points[i].y > 300 ) ) i++;
return i == points.size();
}
The declaration
size_t i = 0;
can be substituted for
decltype( points )::size_type i = 0;
For example
bool trackingPointsVisible()
{
//I've got 4 points here
decltype( points )::size_type i = 0;
while ( i < points.size() and not
( points[i].x < -60 || points[i].x > 300 ||
points[i].y < -60 || points[i].y > 300 ) ) i++;
return i == points.size();
}

How to reduce logic expressions?

{
ans += (a[i] > a[j]) != (b[i] > b[j]);
//ans += ((a[i] > a[j]) && (b[j] > b[i])) || ((a[j] > a[i]) && (b[i] > b[j]));
}
What you see above is a snippet I took from some where. There are two logic expressions. Supposedly, the one commented out is the same as the one not commented out.
How do you get from:
((a[i] > a[j]) && (b[j] > b[i])) || ((a[j] > a[i]) && (b[i] > b[j]))
to something like this
(a[i] > a[j]) != (b[i] > b[j])
Are there any guides or books for these kind of logic expression simplifications?
This is actually very simple.
With (a[i] > a[j]) != (b[i] > b[j]), what we're saying is that this will only be true when the relationship to a[i] and a[j] is the opposite of the relationship from b[i] to b[j]. For this to hold then, if a[i]>a[j] is true, then b[i]>b[j] is false, which means that b[j]>b[i] is true. This means that when a[i]>a[j] is true, b[j]>b[i] is true, and it also means the inverse - when a[j]>a[i] is true, then b[i]>a[j] as well.
Another way of saying all of that is ( (a[i]>a[j]) && (b[j]>a[i]) ) || ( (a[j]>a[i]) && (b[i]>b[j]) . That boolean logic will be true only in the same cases where ( (a[i] > a[j]) ) != (b[i] > b[j]) is true.
As another example, consider when both a[i] > a[j] and b[i] > a[j] . You'll see that the first you posted is false in this condition, because the two terms on either side of the != evaluate to true, meaning the != evaluates to false. This case also causes the second statement to resolve to false because you don't have either of the two terms around the || evaluating to true, they both evaluate to false.
Lastly, this question looks like homework to me - if it is you should use the appropriate tag.
However, this all ignores the possibilities of a[i] == a[j] or b[i] == b[j], which another answer to this question demonstrates can cause the two statements to not evaluate to the same thing. But if you assume that the two cannot be equal, then the two statements from your question will be the same, following the logic demonstrated above.
The code you posted is right if you assume that
!(p > q) == (p < q)
Meaning that for some reason, you're ignoring equality.
With this in mind, let's say that:
a1 = a[i]
a2 = a[j]
b1 = b[i]
b2 = b[j]
Then you have:
ans += ((a1 > a2) && (b2 > b1)) || ((a2 > a1) && (b1 > b2));
Which, since we're ignoring equality, is the same as:
ans += ((a1 > a2) && !(b1 > b2)) || (!(a1 > a2) && (b1 > b2));
If you take a closer look, you'll see that the expressions are repeated, so they can be simplified:
A = a1 > a2
B = b1 > b2
Then:
ans += (A && !B) || (!A && B);
Which means either A or B, but no both
This is a known boolean operation called XOR, which in your case is the same as different (!=)
Therefore:
ans += A != B;
And expanding:
ans += (a1 > a2) != (b1 > b2)
So:
ans += (a[i] > a[j]) != (b[i] > b[j])
Hope it's clear now.
These expressions are not equivalent.
For example, when a[i] == a[j] and b[i] > b[j], the first expression gives...
(a[i] > a[j]) != (b[i] > b[j]);
false != true
true
...while the second one gives:
((a[i] > a[j]) && (b[j] > b[i])) || ((a[j] > a[i]) && (b[i] > b[j]));
(false && false) || (false && true)
false || false
false
Let's take this:
((a[i] > a[j]) && (b[j] > b[i])) || ((a[j] > a[i]) && (b[i] > b[j]))
and call it this, for simplicity:
(w > x) && (y > z) || (x > w) && (z > y)
which is NOT logically equivalent to:
(w > x) && (y > z) || !(w > x) && !(y > z)
because they could be equal, but it is to:
(w > x) && (y > z) || !(w >= x) && !(y >= z)
So you could simplify it to (w > x) == (y > z) or, alternatively, to (w > x) != (z >= y).

Will else-is resolve if the if statement above it is chosen?

In this set of statements:
if(robot1Count < 12) {
robot1Count++;
}
else if(robot1Count < 24) {
robot1Count++;
}
else if(robot1Count < 36) {
robot1Count++;
}
else if(robot1Count < 48) {
robot1Count++;
}
else {
robot1Count = 0;
}
Imagine this is in an infinite loop, would this loop traverse from 0 to 48, change to 0. The thing I'm wondering is if the first block is executed, would all the following blocks be ignored? Or should I change the second to else if(robot1Count < 24 && robot1Count >= 12) ? Or does that not matter?
The thing I'm wondering is if the first block is executed, would all the following blocks be ignored?
Yes, they will all be ignored. The conditions won't even be evaluated. But you know, you could have tested this yourself!
if(robot1Count < 12) {
printf("< 12");
robot1Count++;
}
else if(robot1Count < 24) {
printf(">= 12 && < 24");
robot1Count++;
}
else if(robot1Count < 36) {
printf(">= 24 && < 36");
robot1Count++;
}
else if(robot1Count < 48) {
printf(">= 36 && < 48");
robot1Count++;
}
else {
printf(">= 48");
robot1Count = 0;
}
And then you can see which messages are printed to the console and then you'd know and feel what is going on!
This:
if (cond1)
stuff1;
else if (cond2)
stuff2;
else if (cond3)
stuff3;
else
stuff4;
is identical to this:
if (cond1) {
stuff1;
}
else {
if (cond2) {
stuff2;
}
else {
if (cond3) {
stuff3;
}
else {
stuff4;
}
}
}
Yes -- the if leg and the else leg of an if statement are mututally exclusive -- if the if leg executes the else does not (and vice versa).
Of course they will be ignored, unless you switch the "else if" to "if"
if the code above is in a infinite loop
example
int robot1Count = 0;
while (1 != 2) {
if(robot1Count < 12) {
robot1Count++;
}
else if(robot1Count < 24) {
robot1Count++;
}
else if(robot1Count < 36) {
robot1Count++;
}
else if(robot1Count < 48) {
robot1Count++;
}
else {
robot1Count = 0;
}
}
in a loop this will increment to 48 and go back to 0
it will only hit robot1Count++ per single execution of the loop