[SOLVED] OR binary question

Discussion in 'Programming' started by Bentley, Sep 9, 2019.

  1. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    Just a quick question:

    I have AI (in a platformer) that sets its face variable like this:

    Edit: targ_obj is the player and there's only 1 player.

    Code:
    face = sign(targ_obj.x - x) | face; 
    face is set in the create event to 1. The idea is that "face" will be 1 or -1, right or left, and if their x's are equal, (the OR should work right?) the enemy faces where he was facing.

    It's just a replacement for this
    Code:
    if (x != targ_obj.x)
    {
        face = sign(targ_obj.x - x);
    }
    Curious where I'm misunderstanding. Thanks for reading.
     
  2. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,780
    Well depending on how your version of GM handles it, -1 or anyting would still be -1, since that translates to every bit being set. That's the same reason you can use -1 in place of c_white. So if the player is to the left, then face will always be -1. If face is already -1, then it will remain so.
     
    Bentley likes this.
  3. Binsk

    Binsk Member

    Joined:
    Jun 22, 2016
    Posts:
    582
    Let's take a look at the math. For the sake of demonstration, I'm shortening the size of an int to 4 bits.

    You will have a 1 which is represented as 0001 and you have a -1 which is represented as 1001.

    If you have targ_obj.x = 3 and x = 1 you'd have targ_obj.x - x = 0001 (after sign) giving 0001 | 0001 = 0001 (1, face = 1) or 0001 | 1001 = 1001 (-1, face = -1)
    If you have targ_obj.x = 1 and x = 3 you'd have targ_obj.x - x = 1001 (after sign) giving 1001 | 0001 = 1001 (-1, face = 1) or 1001 | 1001 = 1001 (-1, face = -1)

    You tell me if that math looks like what you are aiming for. Pretty sure it isn't. Remember that bitwise operates at the BIT level.
     
    Last edited: Sep 9, 2019
    Bentley likes this.
  4. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,780
    Personally i use

    sign(target.x-x | 1)

    As you should be able to discern, this favors of value of 1. The difference is it can still change at any time. So if you want the enemy to face left more than right, you would change your code so that a positive value of face equals a negative leftward direction.
     
    Last edited: Sep 10, 2019
    Bentley likes this.
  5. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    Thanks @TheouAegis for the explanation, and thanks @Binsk for the explanation as well. I was misunderstanding the bit math. I'd thought that 0 would get ORed with "face" (1 or -1) which would leave you with face (1 or -1). Just seeing you write "-1 is represented as 1001" made me realize how wrong I am thinking about this.

    Appreciate all the help,
    thanks all.
     
  6. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    Yes, that sounds like a great idea. I'd use that in all situations except this particular one. The reason being the owl grabs the target when their x's align. But I don't want the owl to face right if he was facing left, I want him to face where he was facing.

    But again, in all other situations what you coded is perfect and I will use that (thanks for the help my friend).
     
  7. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,780
    If you were using a state machine suitable for this, you could ahve it so that the owl's swooping state would use sign(target.x-x|1). When sign(target.x-x)!=face, switch to the grabbing state. Just ensure that the owl will not run the face=sign(target.x-x|1) code after switching states.

    Note I didn't say x=target.x. Remember, a hard == will usually fail. Even if you have pixel-perfect motion, if the player is 1px away from the owl and the player and owl both move 1px each, that's a differences of 2 pixels, so your owl would overshoot.
     
    Bentley likes this.
  8. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    @TheouAegis Thanks for the replies:

    Edit: I see what you mean. Store the value of sign(tx - x) and check if it doesn't equal face. Also, good point about =='s on position. I ran into a problem with that. I set targ_x to the player'x, and targ_y to the player's bbox_top + 1. Both the owl and the player have an origin at the bottom center, so the idea was to get the owl to be just above the player with a tiny overlap, and then the collision event runs which checks 1. is the owl swooping 2. hard comparision of position matching targ_x/targ_y.

    As you predicted, the hard comparision was never true. I ended up snapping the owl to the player in the chase state if the owl was close, which would cause the collision event to run later that game step, (the owl's state ran in the normal step and all collision events run after the normal step right?).

    But I still see a flaw in the way I was doing it. Ex: owl snaps in step event which would cause collision event's hard comparison to be true, BUT, if the player moves after the owl, the hard comparison is not true (assuming the player's step event runs after the owl's step event). So yes... bad idea on my part (I wrote that code in like 10 minutes and I'm realizing how flawed it is).

    But all that is to say: I'm going to change what I have to what you suggested.
     
    Last edited: Sep 10, 2019
  9. chamaeleon

    chamaeleon Member

    Joined:
    Jun 21, 2016
    Posts:
    946
    @Bentley
    Given your opening post, I would just like to know if you understand that | does not stop processing the rest of the expression just because the left hand side is "true". It will continue processing everything on the right and perform the bitwise operation on the values on eiher side of it. It is not at all the same as the short-circuit ability of || in a conditional expression which does stop the evaluation of the rest of the expression if the left hand side is true, because nothing on the right hand side can change the value of the expression.
     
    Bentley likes this.
  10. Bentley

    Bentley Member

    Joined:
    Jun 18, 2017
    Posts:
    786
    Yes, thanks for checking in @chamaeleon.

    Correct, I did not expect short-circuit evaluation.

    My thinking was: "I will get the result of sign(player.x - x) and OR that with face. I was thinking that if the result of sign was 0, 0 ORed with face (1 or -1) would just equal face. I was misunderstanding bitmath.

    Edit: I did work with binary on bitboards a long time ago. I think I just have a bad memory lol. But that's not to say I had a grasp of binary in the first place.

    Edit2: @chamaeleon Now I see why you'd think that. If the first condition was 0 (false) than the second condition would run going by short-circuit if I mistook | for ||. Thanks for double checking.
     
    Last edited: Sep 10, 2019
    chamaeleon likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice