I’m feeling a movement part 2 – Pretzel logic

12-28-2017
Warning: If you have a headache brewing, then don’t read this article, as it may cause confusion.

Now, let’s get down to the logical meat of the enemy movement. At a quick glance, can anyone tell me the logic by looking and the below code?

if( sprites[i].f&1 )
	if( sprites[i].y>0 )
	{
		sprites[i].y--;
	}
else
         sprites[i].f ^= 1;
else
	if( sprites[i].y  0 )
		sprites[i].x--;
else
	sprites[i].f^= 2;
else
	if( sprites[i].x < scrw * 16 )
		sprites[i].x++;
else
	sprites[i].f ^= 2;

Time’s up! How did you do? I’ve got a bit of smoke coming out the ears by thinking of it.

We know from the last article that the .i from the command sprites[i] refers to a LOOP that goes through all the enemy sprites.

We also should know that the period after the sprite[i[ as in the command sprite[i].n indicates an additional command to do something with the sprite. N would be the sprite number. X would be the X coordinate. Y would be the Y coordinate. F would be the direction of movement.

Again, I’m going to rehash Antonio’s statement.

Each line is one sprite. The .n is the number of the sprite (will draw a different sprite if changed), the .x and .y are the coordinates (will change of position if modified), and the .f has no effect on the engine, but it’s used by the demo to store the direction of movement (it’s diagonal movement so only 4 directions).

So, if we look at the command

sprites[i].f

And the loop happens to be at 1, we know that we are dealing with sprite[1] and looking at the stored variable f. The variable “f” has no effect on the engine and is used to store the direction of movement.

Further, we can see this definition if we look at fase.h, where we find.

typedef struct {
  unsigned char n;
  unsigned char x;
  unsigned char y;
  unsigned char f;
} SPRITE;

This builds our structure for the SPRITE command. We are not going to mess with that at all, keep yer damn dirty hands off it!

Well, the first bit of code has an awful lot of evaluations to consider, which is why I’m calling it pretzel logic. It literally makes the enemy sprites move in diagonals across the screen bouncing on edges and hurdling off in the opposite direction after it hits a wall. Kinda looks like a pretzel. Perhaps a bit of imagination would help.

So, our first evaluation has some bit-wise Boolean logic in it, in fact, there is a lot of Boolean logic riddled throughout.

Let’s visit bitwise Boolean logic first.

AND

A   B   AND result
0   0   0
0   1   0
1   0   0
1   1   1

Thus, the result only equals true if both A and B are true.

This is represented by the & character.

OR

A   B   OR result
0   0   0
0   1   1
1   0   1
1   1   1

The results are all true unless A and B are false
This is represented by the | character.

XOR (Exclusive OR)

A   B   XOR result

0   0   0
0   1   1
1   0   1
1   1   0

The results are true only if either A or B is true and the other is false. If both A and B are true then the result is false. If A and B are false the result is false.
This is represented by the ^ character

That last one should scramble your brains a bit. It’s not commonly used when speaking, meaning in conversation, you will often hear. “Would you like an Apple and a Pear” or perhaps you might hear “Would you like an Apple or a Pear”. A natural conversation would never have “Would you like an Apple xor a Pear”.

Back to our first evaluation.

if( sprites[i].f&1 )

Is saying that if our SPRITE’s direction and 1 are true then we will do our next evaluation. If the SPRITE’s direction and 1 are not true then we will use the else command.

The second evaluation (which is only considered if sprite direction and 1 are true) is

if( sprites[i].y>0 )

Which asks if the SPRITE’s Y coordinate is larger that 0.

If it is, then the next command comes in play

sprites[i].y--;

This will decrease our SPRITE’s Y coordinate.

Next, we see

else

This is saying that if the prior evaluation is false, then we will perform another action and that action is

sprites[i].f ^= 1;

Another Boolean! YAH!

This one performs a flip-flop and reverses whatever is stored in f. This shoots the sprite off in another direction.

Got it? I hope you do because we repeat the exact same thing with our next sequence.

if ( sprites[i].y < scrh*16 )

Works the same way but checks to make sure that we haven’t gone past the bottom of the the screen. If it does, we push the sprite in the opposite direction.

The program then checks the X coordinates and does the same thing.

It’s like the worst grammar lesson ever. Furthermore, the layout of the commands doesn’t help with looking at this bit of Pretzel Logic.

Keep this in mind, C doesn’t care if it confuses you, but don’t you dare confuse it.

I think a simple reformatting and adding brackets will help understand the logic better.

//evaluation for Y coordinates
if( sprites[i].f&1 )
{
	if( sprites[i].y>0 )
	{
		sprites[i].y--;
	}
		else
		{
			sprites[i].f ^= 1;
		}
	else if ( sprites[i].y  0 )
	{
		sprites[i].x--;
	}
		else
		{
			sprites[i].f^= 2;
		}
	else if( sprites[i].x < scrw * 16 )
	{
		sprites[i].x++;
	}
		else
		{
			sprites[i].f ^= 2;
		}
}

See why I am a bit of a nut about using brackets. I always think code flows to your eyes better when spaced and bracketed. You may disagree with me, and that’s OK, it just what works for me.

I sincerely hope that makes sense to everyone.

Now, that I’ve explained the logic, I’ve decided in my game, not to use any of it! I’m going with a different type of logic.

That logic is to be determined, but before I write it up in an article, I have to figure it out. That might take a while. So, for now, I’m going to try to retackle another bit of code that has been pending for a while.

Advertisements

Author: andydansby

I'm a hobbyist coder working with the ZX Spectrum. Living in New York state near the Syracuse area. I grew up in Virgina. The first computer my parents bought for me was a Timex Sinclair 2068.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s