Best coding method?
by amaranthia · in Torque Game Builder · 03/11/2008 (5:28 pm) · 9 replies
Right now I'm using a giant IF statement to determine whether to return a value as true or false. It seems like a lot of work for what I'm trying to do, so I decided to paste the IF statement and see if anyone has a better way of setting this code up. I have 35 of these IF statements that check for the proper combination of objects.
Your thoughts?
if (%name.sky == 1 &&
%name.sun == 0 &&
%name.water == 0 &&
%name.dirt== 0 &&
%name.air == 0 &&
%name.frost == 1 &&
%name.fire == 0 &&
%name.mud == 0
)
{
return true;
}Your thoughts?
#2
Gary (-;
03/11/2008 (5:46 pm)
Or you might want to reconsider how your use values. If a lot of those things are mutually exclusive then you might try enumerations or similar instead. Pseudocode:enum sky ( sunny, clear, cloudy, nuclearwinter ); enum ground (icy, dirty, muddy, wet, steaming, glowing ); if(sky == sunny && ground == glowing) return true;
Gary (-;
#3
On top of that, the patterns have to be exact. For example, in pattern 1, "sky" must be 0 and "sun" must be 1. Every single value is counted... I can't break after I get true, true, true, etc.
This is the answer I came up with:
I still don't think this is the best answer. A friend of mine said I should use a mask. I'm hunting the forums right now in an attempt to figure out how masks work.
03/11/2008 (10:12 pm)
All of these values are integers. Many of them can only be 1 or 0, but a few of them can be 1-x. I actually have 35 of these values and none of them can be categorized (I've already done this with the ones I could).On top of that, the patterns have to be exact. For example, in pattern 1, "sky" must be 0 and "sun" must be 1. Every single value is counted... I can't break after I get true, true, true, etc.
This is the answer I came up with:
%value = %name.sky @
%name.sun @
%name.water @
%name.dirt @
%name.air @
%name.frost @
%name.fire @
%name.mud;
%pattern = "010000010";
if (%value == %pattern)
return true;I still don't think this is the best answer. A friend of mine said I should use a mask. I'm hunting the forums right now in an attempt to figure out how masks work.
#4
also for simplicity you could use
!%name.something instead of %name.something ==0
and also
%name.something instead of %name.something == 1
03/11/2008 (10:15 pm)
You maybe able to find patters where you can group false statements and nest true statements inside like this://false conditions
if ( ! %name.mud && ! %name.fire && ! %name.air && ! %name.dirt && ! %name.water && ! %name.sun)
{
//true conditions that only occur if all above are false go here
if ( %name.frost && %name.sky)
{
//do something
}
}also for simplicity you could use
!%name.something instead of %name.something ==0
and also
%name.something instead of %name.something == 1
#5
not sure if that makes any sense or not....
basically you could check if your elements are true or false, if they are true, assign a constant value to a temp value to each one such as (2,4,16,32,64,128,256, etc...) and if the element evaluates to false, set the temp value to 0. When you add all of these temp values together, you should get a unique number that only works if specific elements are true.
03/11/2008 (10:47 pm)
You may also want to try something like this now that I think more about it:switch( getTotalValue() )
{
case 6:
// %sun + %water , everything else doesn't work
case 2562:
// %sun + %cloud + %moon, this is same as %sun==1 %cloud==1 %moon==1 and everything else == 0
default
//etc etc etc
}
function getTotalValue( %name )
{
%sun = 2;
%water = 4;
%earth = 16;
%air = 32;
%fire = 64;
%dirt = 128;
%sky = 256;
%cloud = 512;
%rain = 1024;
%moon = 2048;
if( ! %name.sun) //if %name.sun == 0
%sun = 0;
if( ! %name.water) //if %name.water == 0
%water = 0;
if( ! %name.earth) //if %name.earth == 0
%earth = 0;
// etc etc
return %sun + %water + %earth;
}not sure if that makes any sense or not....
basically you could check if your elements are true or false, if they are true, assign a constant value to a temp value to each one such as (2,4,16,32,64,128,256, etc...) and if the element evaluates to false, set the temp value to 0. When you add all of these temp values together, you should get a unique number that only works if specific elements are true.
#6
03/12/2008 (10:44 am)
Very good idea! I'll test it. :)
#7
Gellyware has the idea, but Torque can take some of the grunt work out. Check out the bit functions in the 1.7.2 TGB Reference -> t2dUtility and also TGB Reference -> TorqueScriptReference.
03/12/2008 (1:58 pm)
A mask is a series of bits -- 1's or 0's.Gellyware has the idea, but Torque can take some of the grunt work out. Check out the bit functions in the 1.7.2 TGB Reference -> t2dUtility and also TGB Reference -> TorqueScriptReference.
#8
// Assign each element in your test a unique bit...
$skyMask = bit(0);
$sunMask = bit(1);
$waterMask = bit(2);
etc...
// How to tell if an element is enabled...
$skyEnabled = false;
$sunEnabled = false;
etc...
// Can assign a combination of masks its own by ORing them together (if you want)
$comboMask1 = $skyMask | $sunMask | $waterMask;
// The current "state" could be represented as 1 or 0 for each of these masks...
%currentMask = 0;
if ( $skyEnabled )
%currentMask |= $skyMask;
if ( $sunEnabled )
%currentMask |= $sunMask;
etc...
// So if a mask is enabled, that BIT will be 1 in %currentMask, if not it will be 0 ( off ).
// and you can test %currentmask like so...
// AND (&) will return the value of that BIT...eg... the skyBit.
if ( %currentMask & $skyMask )
{do something}
Maybe this will give you some idea for how to use bitwise operations in your game.
03/13/2008 (11:17 am)
Instead of:if (%name.sky == 1 &&
%name.sun == 0 &&
%name.water == 0 &&
%name.dirt== 0 &&
%name.air == 0 &&
%name.frost == 1 &&
%name.fire == 0 &&
%name.mud == 0 )// Assign each element in your test a unique bit...
$skyMask = bit(0);
$sunMask = bit(1);
$waterMask = bit(2);
etc...
// How to tell if an element is enabled...
$skyEnabled = false;
$sunEnabled = false;
etc...
// Can assign a combination of masks its own by ORing them together (if you want)
$comboMask1 = $skyMask | $sunMask | $waterMask;
// The current "state" could be represented as 1 or 0 for each of these masks...
%currentMask = 0;
if ( $skyEnabled )
%currentMask |= $skyMask;
if ( $sunEnabled )
%currentMask |= $sunMask;
etc...
// So if a mask is enabled, that BIT will be 1 in %currentMask, if not it will be 0 ( off ).
// and you can test %currentmask like so...
// AND (&) will return the value of that BIT...eg... the skyBit.
if ( %currentMask & $skyMask )
{do something}
Maybe this will give you some idea for how to use bitwise operations in your game.
#9
03/13/2008 (7:00 pm)
Thank you James, this is exactly what I was looking for. Thanks for the lesson, too. :D
Torque Owner Gary "ChunkyKs" Briggs
Well, my immediate thought is "ew"
Past that, if what you've really got is a huge number of boolean variables [which you don't really make clear if that is the case or not], then try some logic reduction mechanisms reappropriated from your favorite circuit design course:
Karnaugh Maps
Quine-McCluskey
and one that I hadn't heard of before until I read your post and forgot what a Karnaugh map was called so had to google:
Expresso
Honestly, though, it's more likely you need to redesign your code further up the toolchain and branch the behaviour a little earlier.
Gary (-;