Posted: 18th Jun 2007 5:49
I have a situation where I need to compare the values from 3 variables to 3 other variables. I only want to do something if all three variables are the same. will something like this work?

If a1 = a2 AND b1 = b2 AND c1 = c2 then Do_My_Thing()

assuming, of course, Do_My_Thing() is a valid function.

or, can you only do one comparison?

Edit:

ok, tested this, it does work.
Posted: 18th Jun 2007 6:00
That is the coolest question all weekend! My experience with this has been that you first need to cease the if/then and rely on the if/endif. The next thing is to do it the hard way first to eliminate errors in your thinking about the inputs, which are the first things that usually go wrong in these things.

You can start collecting them up, but you need to be careful; that is pretty lame but, it is my experience.

Start with the one you just posted, and experiment with it. I find that after having done that, I write nice logic blocks that are complex evaluations, but I know about using the return of function calls in that, and implicit and explicit casts that can mess things up.

It never pays to try to get too complicated in these things, because that usually means you have programmed yourself into some sort of corner, you know? Plus, it just looks so pained, and confusing.
Posted: 18th Jun 2007 6:04
Jinzai
here was my test case.
I did do it with if, endif, I hardly ever use if, then.
+ Code Snippet
function test_and()
a1 = 1
a2 = 1
b1 = 2
b2 = 2
c1 = 3
c2 = 3

If a1 = a2 AND b1 = b2 and c1 = c2
   make object box 5,10,10,10
endif

endfunction


that code works TRUE


+ Code Snippet
function test_and()
a1 = 1
a2 = 2
b1 = 2
b2 = 2
c1 = 3
c2 = 3

If a1 = a2 AND b1 = b2 and c1 = c2
   make object box 5,10,10,10
endif

endfunction


that code works FALSE

you'll soon see where I'm going with this, its gonna be a good one, I promise
Posted: 18th Jun 2007 6:41
and to expand on this, I think it could be explained like this.

If a1 equals a2, the result would be 1
If b1 equals b2, the result would be 1
If c1 equals c2, the result would be 1

so, for the entire AND operation to be true, we would need a result of 111

If a1 does not equal a2, the result would be 0
really, no need to go any further, but just incase it does and compares at the end, the result would not be 111, no matter what the other two results were.

so, to really test it, a1 has to equal a2, and b1 has to equal b2. And in my test case, they don't. So I did it again, making sure the third variable was different.

+ Code Snippet
function test_and()
a1 = 1
a2 = 1
b1 = 2
b2 = 2
c1 = 3
c2 = 4

If a1 = a2 AND b1 = b2 and c1 = c2
   make object box 5,10,10,10
endif

endfunction


As I hoped, this returned FALSE, so, this to me is a true test matrix of my question. I would assume it would work for four or five or six, who knows how many.
Posted: 18th Jun 2007 7:40
Just to add my 2 cents...

If you have a lot of nested if statements that are checking several things... put the "most common to fail" check in the beginning. This is a way of short-circuiting the check so it doesn't do everything.

+ Code Snippet
rem All these checks need to be true to call function yoyo()
if <this rarely happens>
   if <this can happen sometimes>
       if <this happens often>
           yoyo()
       endif
   endif
endif
Posted: 18th Jun 2007 7:43
Yes, it does. One thing that is likely to have already occurred to you, or perhaps is about to occur to you is that you can pack this down into smaller sized chunks and that is a pretty good shortcut/optimization to apply. State machines are usually on/off, or sometimes I have taken more than 1 bit and made multi-state variables. (For example you can do 16 states using 4 bits.) Then you are able to use select/case, for example. It uses less memory, and is much faster. You can even put it in existing code, you just start collecting ones which are two state (they get one bit), four state (they get 2 bits), etc. Its a chore if your app is big already, but it is worth the trouble, I think. Then, you can use bitmasking to test for multiple states at once. It helps you to shortcut logic trees, and it reduces the memory footprint. It also allows a finer granularity of per frame control of game objects. The basic if/endif presents a sort of barrier if you are having to go too far to the right of the screen when you are writing it.


At some point, you will outstrip either the compiler's ability to build the logic, or you will otherwise run out of steam with memory, or perhaps the stack.

Here is something that demonstrates what I mean, a little anyway.

+ Code Snippet
REM Project: bitfields
REM Created: 6/18/2007 12:03:26 AM
REM
REM ***** Main Source File *****
REM
remstart
    These might look stupid at first glance, but they are really arbirary names
    here. I use hex because each of the places to the right of the 'x' represents
    4 bits.
remend

#constant ONE_OF_SIXTEEN = 0x00000000
#constant TWO_OF_SIXTEEN = 0x00000001
#constant THREE_OF_SIXTEEN = 0x00000002
#constant FOUR_OF_SIXTEEN = 0x00000003
#constant FIVE_OF_SIXTEEN = 0x00000004
#constant SIX_OF_SIXTEEN = 0x00000005
#constant SEVEN_OF_SIXTEEN = 0x00000006
#constant EIGHT_OF_SIXTEEN = 0x00000007
#constant NINE_OF_SIXTEEN = 0x00000008
#constant TEN_OF_SIXTEEN = 0x00000009
#constant ELEVEN_OF_SIXTEEN = 0x0000000a
#constant TWELVE_OF_SIXTEEN = 0x0000000b
#constant THIRTEEN_OF_SIXTEEN = 0x0000000c
#constant FOURTEEN_OF_SIXTEEN = 0x0000000d
#constant FIFTEEN_OF_SIXTEEN = 0x0000000e
#constant SIXTEEN_OF_SIXTEEN = 0x0000000f

rem Use CHANNEL_MASK to strip the channel ID bits.

#constant CHANNEL_MASK = 0x000000f

rem Use DATA_MASK to strip out the 28 bit data value. This is packed to the LEFT.

#constant DATA_MASK = 0xfffffff0

dim channel(16) as dword

global i as integer

rem Fill the 16 channel 28-bit data array with some easily verified data.

for i = 0 to 15
    channel(i) = ((16 - i) << 4) || i
next i

for i = 0 to 15
    print "Channel " + str$(channel(i) && CHANNEL_MASK) + " DATA: " + ...
    str$((channel(i) && DATA_MASK) >> 4)
next i
wait key
end
Posted: 18th Jun 2007 9:41
jinzai:
I have to say, your code is WAY over my head, at the moment.
using hex doesn't make it any easier to understand, even though I understand hex, I don't like to look at it.
Is it really necessary in anything we do in DBPro?

Your use of bitwise operators << and ||
here is where it gets tricky for the layman programmer.(like me!)

Your code:
for i = 0 to 15
channel(i) = ((16 - i) << 4) || i
next i

so I understand this, << is a symbol that shifts all bits a number of spaces to the left. So, in your code the result of (16 - i), which is 16 in the first loop thru, will get bit shifted 4 spaces to the left. In Binary, 16 is represented as 10000. So, this bitwise operation will shift 10000 four spaces to the left, resulting in 10000000. In Decimal, this is 256, btw. Now, this code performs an OR operation. So, we have 1000000 OR'd to i, which in the first loop is 0 or, 0000 binary. So, in the first loop thru i = 0, 16 - 0 = 16, shift 4 to the left, so now 256 and OR it with i, which is 0, so the result in this case, is 256. Here is mt question. How or why would I use something like this? I know alot of programmers use it for states, but, in this language, wouldn't it be more readable, and easier to figure, inc and dec variables?
Like I said, your programming is way over my head, but someday I hope to go beyond just reading and writing variables. I know I'm going to have to grasp this to get serious.
Posted: 18th Jun 2007 10:20
The landlord of the Dog and Duck has a sign made outside his pub. But when it arrives it reads DogandDuck. So, he says to the sign writer:

"There is no space between Dog and and and and and Duck".
Posted: 18th Jun 2007 12:55
The worst thing about that example is that I put the channels in order to make it easy to fill it. What if these were from say, network packets. The channel then would represent 16 players with 28 bits for, say things like firing, crouching, an animation number, anything.

When you use 32-bits to convey 32 pieces of information that you are currently using to carry one, or two, you gain alot. For one thing, you can test 32 states in any combination in one statement. That would take 32 'if a = b's', or one selected mask operation. Let's say you have 8 conditions you want to test for in your hypothetical logic. Now, there are different ways to do this, and you will end up using most of them, because your game is going to be all over the place as far as the logic of the individual subsystems. At some point, you will get deep into the logic, and it will cost you a frame, or you will arrive there to find that you needed to run some code prior to arriving at this condition. This method can test for those unique conditions earlier in the code without using 8 boolean style logic operations; it uses 1.

As far as the snippet, here is what is going on there:

Hex is actually clearer in the end, but I understand your confusion. Decimal is not a good way to look at it, it will confuse you more. It helps to use binary at first sometimes, but that takes up alot of room if you bother to show the entire dword:
+ Code Snippet
#constant ONE_OF_SIXTEEN = 0x00000000        [00000000b]
#constant TWO_OF_SIXTEEN = 0x00000001        [00000001b]
#constant THREE_OF_SIXTEEN = 0x00000002      [00000010b]
#constant FOUR_OF_SIXTEEN = 0x00000003       [00000011b]
#constant FIVE_OF_SIXTEEN = 0x00000004       [00000100b]
#constant SIX_OF_SIXTEEN = 0x00000005        [00000101b]
#constant SEVEN_OF_SIXTEEN = 0x00000006      [00000110b]
#constant EIGHT_OF_SIXTEEN = 0x00000007      [00000111b]
#constant NINE_OF_SIXTEEN = 0x00000008       [00001000b]
#constant TEN_OF_SIXTEEN = 0x00000009        [00001001b]
#constant ELEVEN_OF_SIXTEEN = 0x0000000a     [00001010b]
#constant TWELVE_OF_SIXTEEN = 0x0000000b     [00001011b]
#constant THIRTEEN_OF_SIXTEEN = 0x0000000c   [00001100b]
#constant FOURTEEN_OF_SIXTEEN = 0x0000000d   [00001101b]
#constant FIFTEEN_OF_SIXTEEN = 0x0000000e    [00001110b]
#constant SIXTEEN_OF_SIXTEEN = 0x0000000f    [00001111b]


Notice here two things. First, like I said, one hex place = 4 bits
See how the binary bits count? It helps enormously to be able to visualize to some extent what is happening in code. If it looks foreign, it is, just try to get accustomed to it. That is not my code, however. It is not obfuscated, and it flows well to my eyes, but why wouldn't it?

CHANNEL_MASK is any easy way to retrieve only the channel ID. By setting only channel bits in the mask, the && (bitwise AND) will only pick off channel ID bits. The same goes for the data, except that if you are using it as a single 28-bit value, it is shifted left 4 bit positions to make room for the ID in the 4 least significant bits. So, it is effectively multiplied by 16, as you pointed out, but do not use any maths at all on these packed values. First, you need to do the voodoo and get it into its actual type.

Next, the hand magic to fill the array, I should have simply filled it with random values to show that the channels do not need to be in order when evaluated, and in fact, you can force it to sort itself in place if that is what you want. This is actually how multi-channel data acquisition systems stream say 16 channels of 16 bit data with 12 digital bits (16 + 12 + 4 = 32). It keeps the channels' ID with its data, and all is accessible from a single 32-bit value. The same 4 bits could indicate 16 different kinds of anything.

I deliberately chose this example because it is pretty simple, but all that did was underplay its flexibility and still not manage to convey its utility. Sorry.
Posted: 18th Jun 2007 16:18
i dont think theres a limit to how many ands u can use.ive used something like this with no problems if a and b and c and d and e then whatever