!= && != amazing behaviour

4i4in

Member
I was trying to skip checking legality of movement for characters that are not moving (they have previous and curent x/y).
I put such exclusion:
if xxx1 != xxx0 && yyy1 != yyy0 {do stuff} //exclude checking not moving characters

it didnt work.
So i add some clarity in case compiler have odd interpretation:
if (xxx1 != xxx0) && (yyy1 != yyy0) {do stuff} //exclude checking not moving characters

but it didnt work either.

I ended with that:
if xxx1 = xxx0 && yyy1 = yyy0 {no code} //exclude checking not moving characters
else{do stuff}

and it works.

What is wrong? Need more brackets?
Just wonder. In case I will get in such riddle again.
 

Neptune

Member
There is nothing wrong with
GML:
if xxx1 != xxx0 && yyy1 != yyy0 {do stuff}
You don't need brackets (in this case). Using = instead of == is just bad practice, but GM will allow it.

= is used for assignment
== is used for comparison, same for !=

Perhaps you were looking for
GML:
if xxx1 != xxx0 || yyy1 != yyy0 {do stuff}
In which case, if either case is true, your code will run. You've essentially done that with your last line (by flipping the logic using && and else)
 
Using = instead of == is just bad practice, but GM will allow it.
The VM compiler tolerates it, sadly, but YYC will not like your code at all.
As you said, he's just looking for or, not and. It's a fair guess he can move horizontally or vertically! ๐Ÿ˜‚
 

FrostyCat

Redemption Seeker
The problem would have been obvious had you drawn a truth table, and its solution just as obvious had you used De Morgan's Laws.

If this is your intended behaviour:
GML:
if xxx1 = xxx0 && yyy1 = yyy0 { } //exclude checking not moving characters
else { ... }
Then this is what you should have done:
GML:
if (xxx1 != xxx0 || yyy1 != yyy0) { ... }
It is fashionable these days to start making games without basic Boolean logic, but the results end up not being very fashionable.
 

curato

Member
I don't remember any such error in the Boolean operations. It would have broken everyone's project. The really key is plan everything out before you start coding. There is a joke that says weeks of coding can prevent hours of planning.
 
Last edited:

FrostyCat

Redemption Seeker
There was a change in the behaviour of && and || in the GMS 1.2 timeframe (added support for short-circuiting), but that would not have made any difference in the code from the first post. The botched application of De Morgan's Laws is just as wrong now as it was in legacy GM and pre-1.2 GMS.
 

4i4in

Member
I don't remember any such error in the Boolean operations. It would have broken everyone's project.
It did.
FrostyCat call exactly that event:
There was a change in the behaviour of && and || in the GMS 1.2 timeframe (added support for short-circuiting)
me stupid :)
me so sorry :)

//I'm even more stupid when forgeting that ds_list_read is not ds_list_find_value and geting NaN.
 

Evanski

Raccoon Lord
Forum Staff
Moderator
Also keep in mind GML has lazy logic checks

so using frostcats example

GML:
if (xxx1 != xxx0 || yyy1 != yyy0) { ... }
If xxx1 = xxx0 it wont bother checking yyy1 != yyy0

Edit: Im smooth raccoon brain ignore me
 
Last edited:
Also keep in mind GML has lazy logic checks
GML:
if (xxx1 != xxx0 || yyy1 != yyy0) { ... }
If xxx1 = xxx0 it wont bother checking yyy1 != yyy0
Why would it continue the check, and why is this crazy logic? I do a lot of C# these days, and this is the exact same thing.
Quite useful, you can check if something exists and do a check on it in one line.
GML equivalent example:
GML:
if( (instance_exists(obj_object)) && (obj_object.x > 50) ){
    //This will never ever crash
}
 

Evanski

Raccoon Lord
Forum Staff
Moderator
Why would it continue the check, and why is this crazy logic? I do a lot of C# these days, and this is the exact same thing.
Quite useful, you can check if something exists and do a check on it in one line.
GML equivalent example:
GML:
if( (instance_exists(obj_object)) && (obj_object.x > 50) ){
    //This will never ever crash
}
Oh no I messed up and thought we where talking about && not ||

in an OR check it checks all logic

in an AND check it will only check those that are true (ie if x=a && c = 0)
This is faster as it wont need to check the rest anyway as the first part is false and the AND check requires both to be true to the logic check (== != < >)
 
Last edited:

4i4in

Member
Why would it continue the check, and why is this crazy logic?
I'm not using objects. Cant have 4k objects in game with reasonable fps_real. I'm using ds_list and scroling throu this.


GML:
#region//check collisions with objects
if game_state = 1
{
    kkk = ds_list_find_value(char_list,0); //this one store the number of entry for each "object"
    for(iii = 1; iii < ds_list_size(char_list); iii = iii +    kkk)
        {
            xxx0 = ds_list_find_value(char_list,iii+0);
            yyy0 = ds_list_find_value(char_list,iii+1);
            xxx1 = ds_list_find_value(char_list,iii+2);
            yyy1 = ds_list_find_value(char_list,iii+3);
            rrr = ds_list_find_value(char_list,iii+6);//type of character - need it later for diferent checks
           
            ppp = ds_list_find_value(obj_list,0);
            if (xxx1 != xxx0 || yyy1 != yyy0)
            {

                for(jjj = 1; jjj < ds_list_size(obj_list); jjj = jjj +    ppp)
                    {
                        xxx2 = ds_list_find_value(obj_list,jjj+0);
                        yyy2 = ds_list_find_value(obj_list,jjj+1);
                        qqq = ds_list_find_value(obj_list,jjj+2);//type of object
                        if xxx1 = xxx2 && yyy1 = yyy2
                        {
                        switch qqq//interaction with
                            {
                                case 1://wall
                                {
                                ds_list_set(char_list,iii+2,xxx0);
                                ds_list_set(char_list,iii+3,yyy0);
                                break;}
                           
                            }
                        }
                    }
            }
        }
}
#endregion
This is grid rigid WASD "game" to explain to son basic he get on arduino 2x16display in more intresting form. So I do not even bother wih p+=q to make it readable for him. No directions, no trigonometry as far^^
Only simple interactions on grid later extrapolated to screen by *64 factor of sprites.
 
Last edited:
in an OR check it checks all logic
Nope. In an OR check, if whatever condition returns true, the ones after it won't be evaluated. My example was just to show that there is NO useless evaluation if the entire condition is to return true anyway.
In an "AND" check, if one returns false, the ones after it also wont be evaluated.

I'm not using objects. Cant have 4k objects in game with reasonable fps_real. I'm using ds_list and scroling throu this.
Objects or structs, or anything, you can definitely have 4k of them. It all boils down to the efficiency of your code. If all your code is Big O(N) or worse is another matter altogether.
I can hit 30k instances no problem in VM debug mode, 4k is nothing. Your computer performs billions of calculations per seconds.
In a nutshell, it's not just the amount of instances, but also how they do stuff, that'll drop or increase performance.
 
Last edited:

Evanski

Raccoon Lord
Forum Staff
Moderator
Does it? If the first condition is true, then the entire OR will be true, so there would be no need to execute the second part. That's how short-circuiting works.
Nope you're right, Im wrong again :p I understand the basics of the logic checks and how to use them I guess my explaining needs more work, oh well I'll shut up now lmao
 
By the way, all this stuff is really easy to get a grasp of, even of the most complicated cases. Frostycat linked you to some stuff about De Morgan, you should read into this.
It's basically 2 "laws" that define boolean algebra.
 

Yal

๐Ÿง *penguin noises*
GMC Elder
If you're already struggling with boolean logic, you're gonna have a blast once you get to interpolation/easing and trigonometric functions.
 

Roldy

Member
As @
It did.
FrostyCat call exactly that event:

me stupid :)
me so sorry :)

//I'm even more stupid when forgeting that ds_list_read is not ds_list_find_value and geting NaN.
Like everything, you get better with practice and every mistake is an opportunity to learn. Congrats... you just learned stuff! :p
Keep doing it and you'll keep getting better.

Everyone in this thread knows less than they don't know. It is the normal operating state.
 

4i4in

Member
If you're already struggling with boolean logic, you're gonna have a blast once you get to interpolation/easing and trigonometric functions.
Those I do as a job. Only boolean dosent bother me in real world.

Like everything, you get better with practice and every mistake is an opportunity to learn. Congrats... you just learned stuff!
No way - I make same mistake over and over again every time I seat back to GMS. Exactly same mistakes.
 

Neptune

Member
The fact this thread went beyond my reply... Is why I rarely offer help anymore ๐Ÿคฃ

To the noob struggling with basic boolean logic "Had you sat in a university classroom and took philosophy & logic, you'd have known to draw a truth table and remember De Morgan" ๐Ÿ‘๐Ÿ‘๐Ÿ‘
 
The fact this thread went beyond my reply... Is why I rarely offer help anymore ๐Ÿคฃ
The reason the topic went beyond your reply is because you did not answer the question posed by OP.
What is wrong? Need more brackets?
Just wonder. In case I will get in such riddle again.
You simply gave him the solution without explanation. That wouldn't be of help since OP specifically asked for the reason he was having the problem; not a solution, since he already had an alternate.
 

Yal

๐Ÿง *penguin noises*
GMC Elder
The simple version of De Morgan is "if you invert AND / OR, you also need to invert every true and false, and vice versa"

So the opposite of A && B would be !A || !B
 

Neptune

Member
!(A && B) {} ----> (!A || !B) {}

!(A && B) {} is what OP desired, and their solution was (A && B) {} else {} they could have done de morgans, or just !(A && B) {}

Really there is no point to do a conversion using || though... But perhaps it's easier than being comfortable with ( ) and ! operator at first.
 
Last edited:
Top