PDA

View Full Version : Using bits of an integer as independent variables



C-Dawg
11-17-2006, 07:43 PM
Alright, so, I'd like to set up a few global variables to mirror Link's inventory. That is, at certain points, Link sets off a script that checks each item in Link's inventory, then sets bits of a global variable accordingly. So I'm wondering how ZScript would handle the following tasks:

1. Is there a way to run a loop of function that checks each item and returns whether or not Link possesses that item?

2. How do I get specific bits of an integer and write to those bits? How many bits make up an integer? I don't need digits, just binary bits.

Saffith
11-17-2006, 09:39 PM
1. Is there a way to run a loop of function that checks each item and returns whether or not Link possesses that item?Well, yeah, but it'll be tricky (if not impossible - haven't tried working such a thing out myself) to get it to work with the global variable representation. Link->Item[i] will tell you whether Link has the item with the given ID. In b15, there'll be constants in std.zh relating the numbers to the items, but for now, numbers are all you'll get.


2. How do I get specific bits of an integer and write to those bits? How many bits make up an integer? I don't need digits, just binary bits.This part's a bit tricky. There are sixteen bits in an integer, but you can only use the first thirteen reliably in constants. Any number greater than 9999 (that's 0010011100001111) will be truncated, even though the program can handle them just fine. Hopefully, that'll be changed, but that's how it is for now. You can use the fourteenth bit with 0010000000000000; you just can't put it in whatever constant you like.

So, what you'll probably want to do is something like this:

const int BOOMERANG = 1b;
const int BLUE_CANDLE = 10b;
const int BAIT = 100b;
const int WAND = 1000b;

ffc script Items
{
int itemSet;

void run()
{
itemSet=0; // Initialize to no items

itemSet |= BOOMERANG; // OR with boomerang constant to add it to the set

itemSet &= ~BOOMERANG; // AND with inverted boomerang to remove it

if(itemSet & WAND != 0)
{
// If ANDing with the item constant gives a nonzero result,
// the item is in the set
}
}
}Except, of course, since there are around a hundred items, you'll need eight, maybe nine global variables, each keeping track of a different set of items.


Edit: I might've been wrong. It seems numbers can go as far as eighteen bits. Not sure what the deal with that is.
In any case, it's probably not a good idea to go past sixteen, but I realized there's a fairly easy way you can use all of them, and do it in loops.

itemCounter=0; // Which item you're currently checking
itemSet1=0; // First set of items
bit=1; // Bit corresponding to the current item; you don't have to know which bit goes to which item

for(int i=0; i<16; i++)
{
if(Link->Item[itemCounter])
itemSet1 |= bit;
itemCounter++; // Increment counter to check next item
bit <<= 1; // Shift bit to store next item
}

// Don't reset itemCounter
itemSet2=0;
bit=1;

for(int i=0; i<16; i++)
{
if(Link->Item[itemCounter])
itemSet2 |= bit;
itemCounter++;
bit <<= 1;
}

// Etc...
Another place arrays would be handy.

jman2050
11-18-2006, 01:36 PM
Actually, a number can be 32 bits. That's the size of a long int after all...

Saffith
11-18-2006, 04:20 PM
Gah, of course. I see. It's 18 bits for the integer part, and 14 bits for the decimal part.

Okay, so it's 32 bits in all. Only the integral part of the number is used for bitwise operations, so you can essentially get 18 bools out of one int.

C-Dawg
11-18-2006, 04:33 PM
Not too shabby.