New account registration is temporarily disabled.

USING A VARIABLE AS MULTIPLE SWITCHES.

Posts

Pages: 1
I just wrote this up for my blog. I thought it might be useful for others to read it; and it would certainly be useful for me to see any comments or corrections. Give it a read if you have the time. (By the way, I'm a completely untrained programmer. I assume this stuff is pretty basic, but it's completely new to me.)

---

I am working within a branching conversation. You are talking with a character, and their responses change depending on what you say or do. Certain responses from the character lead toward a particular conclusion to the conversation. Once you have received these certain responses, the conversation ends.

I'll make this example more concrete:

Say you are a detective, and you are interrogating a suspect. You want to discover three holes in the suspect's alibi. Once you discover three holes, you know you will be able to convict the suspect.

So, when you are programming this hypothetical interrogation in RPG Maker 2003, you need to indicate to the program a) when a hole in the alibi is discovered and b) when three holes have been discovered.

You might simply create a counter (a variable) that increases whenever a hole is discovered. When the counter hits three, the conversation ends, and you've got your suspect. However, unless you ensure that the player doesn't ask the same question twice (and rediscover the same hole in the alibi), the counter will increase whenever any given hole is discovered or rediscovered. So the player could simply ask the same question three times, the game will assume he's found all the holes, and the conversation will end.

You can solve this problem by turning each hole into a switch. Then, instead of counting up to three and ending the conversation, the program turns on three different switches. When all three have turned on, make the conversation end.

I've programmed certain parts of "Aniktophlox" like this, and I find myself with lots and lots of switches! Today I discovered a better, more code-efficient way to do this.

I started thinking about the problem like this: instead of using a variable as a counter, maybe it could be used as a collection of switches. The easiest way to imagine this was to imagine a variable in which each digit is a switch: 001 (or 1) would mean the third switch is on; 010 would mean the second switch is on; 110 would mean the first two switches are on; and so on. But this didn't work, because I couldn't get RPG Maker 2003 to check those digits in the way I imagined. I tried using division and modulus operations, but nothing worked out.

Somehow, I hit on the idea of using prime numbers. I didn't know how I would use prime numbers, but I realized I could think of the problem like this: 2 contains 1 and 2; 3 contains 1 and 3, but not 2; 5 contains 1 and 5, but not three; and so on. I felt as though I was on the right track. I tried throwing a few non-prime numbers into the mix, but that idea didn't pan out. Eventually I decided that I needed to work with bigger numbers, so I took 3, 5, and 7 -- three primes -- and started multiplying them together:

3x3=9,
3x5=15,
3x7=21,
5x5=25,
5x7=35,
and so on...

I wrote down all these multiplication products and started dividing each one by 3, by 5, and by 7; then I looked at which multiples left remainders. {In RPG Maker 2003, you can manipulate a variable in this way: divide it by a given number and then change the original variable into what remains after the division. In my fantasy, I could somehow do this operation and then check if the variable had become a zero (0 = a switch turned off, in my original idea) or not (1 = a switch turned on, in my original idea).} So I started getting these numbers:

35
divided by 3 leaves a remainder of 2 ("3" is "on");
divided by 5 leaves no remainder ("5" is "off");
divided by 7 leaves no remainder ("7" is "off").

As I went through all my multiplication products, I eventually found all the various combinations of my three imagined switches being either off or on. I was amazed! But I had gone so far from my original conception of each digit as an imaginary switch (001, 010, 100, and so on) that I didn't know how to implement what I'd found. I thought a while, feeling very confused but very sure that I was figuring something out. Ultimately, I set up my version of the interrogation program like this:

I first set the variable to 1. This is my imaginary, multi-switch variable. At 1, every switch is off. Each imaginary switch is a prime number; and to turn a switch on, you simply multiply the variable by that prime number: e.g., 1x3=3. Now, if you check the variable (set to 3) by dividing by any given switch (i.e., prime number), here's what you get:

3
divided by 3 leaves no remainder ("3" is "off");
divided by 5 leaves a remainder ("5" is "on");
divided by 7 leaves a remainder ("7" is "on").

This is the opposite of how I want it! The imaginary 3 switch was suppsed to be on, not off! But this is easily remedied: instead of programming a remainder as an "on," program it as an "off!" Thus:

3
divided by 3 leaves no remainder ("3" is "on");
divided by 5 leaves a remainder ("5" is "off");
divided by 7 leaves a remainder ("7" is "off").

Let's bring this idea back to our interrogation program. The player is interrogating a suspect and wants to find three holes in the suspect's alibi. We will label each hole as a prime number. Whenever the player discovers a hole, we multiply our "multi-switch" variable (first set to 1) by that hole's prime number. But also, before that, to be certain the hole hasn't already been discovered, we first check to see if division by that hole's prime number returns a remainder or not. If a remainder isn't found, the imaginary switch has already been turned on and we don't need to turn it on again.

So, instead of having three separate switches for these three holes in the alibi, we can now check them all with one variable.

E/S
Yes, it is something like that. If I figure out just what he's doing there, I might be able to compare the methods better. (I suspect his method is more elegant and powerful.)

E/S
If I understand correctly, Kazesui's method is better for mass encoding and decoding of switches. Mine seems to be better for encoding fewer switches and checking their status with less lines of code.

Kazesui's method takes more steps to encode and decode. Switch #1, basically, is turned on or off by adding or subtracting 1 from the variable. That's simple; but switch #5 is turned on or off by adding or subtracting 16! As you can see in his code examples, he needs many lines of code to communicate the encoded value of any given switch number. By my math, you'd have to rename Switch #1 to Switch #0, then do something like this to find the encoded value:

Switch # encoded value = 2^(Switch #)

By that math, Switch #4 (previously known as Switch #5) can be turned on or off by adding or subtracting 16. I guess that could work, but because RM2k3 can't easily change variables by powers of n, the encoding and decoding uses several lines of code, including some limited looping or repeating conditional branches (which, again, you see in Kazesui's examples). As I'm saying, this is probably better for mass encoding and decoding. You can code five switches into a number as low as 31. (By my method, only three switches can be encoded in 105.)

But what my method can do is this:

Switch 3 is turned off or on by multiplying or dividing by 3; no need to convert. And, unless my math is faulty, you can check the status of an encoded switch simply by checking for a remainder after division by the switch number.

Make sense?

E/S
This is a brilliant idea to use prime numbers.

I also ran up against this problem. My game has about 160 weapons which can be selectively upgraded across 4 characters. I created a simple program which breaks down a variable into each digit and stores the value in each digit into several temporary variables that are used to do whatever checks I need to do at the time. (A number like 243743 becomes six seperate variables.) It's cumbersome, though. But it really saves a lot of variables.

On that note, I've heard that you can use over 5000 variables in RPG Maker 2003 by using a referential variable to set and acquire their data.

(For example,
Var 0001:VariableReference Set to 5001
Var [[0001:VariableReference]] Set to 1
Variable 5001 is now equal to 1.)

In this way, you could use as many variables as you like and never run out so long as the player's computer has the memory to store them. I haven't tested this personally, but I've heard that it does work, because RPG Maker uses a king of dynamic memory structure.
Saying it's better for certain kind of numbers is bit of a stretch. To encode your switches into one variable, you'd need just as many lines of event commands as the one in the tutorial, minus the ones you cannot fit because using prime numbers is not as compact as binary. Unless using some patch of plugin to point to switches, you simply need those branches.

for decoding into switches, you'd might need two or three lines less code, a code which is pretty short and not really computationally heavy to begin with, so it doesn't really make that big a difference.

Your biggest argument for it being better seems to be that you can access the "switches" on the fly. But that would assume you would actually be using the variable itself as a set of switches, rather than just a place to store irrelevant switches for the time being (which is what the tutorial does).
Practically, you'd want to use switches rather than variables (where switches are handy) since these are easier to work with. You could have 1 set of of 20 switches which you use for one area, and when you leave this area, you just encode the switches into a variable, and can reuse the same switches again. This makes usage easy, since you don't want to make a division every time you want to figure if a switch is on. Event pages can't even be triggered that way, so it's impractical. Meaning encoding and decoding in batches make more sense than being able to single out single switches in a variable.
Apart from that, it's also possible to get a switch directly by dividing by the appropriate number (2^switch#), and then doing modulus 2, so two lines instead of one, but still just as impractical for reasons mentioned above.
It might also bear mentioning that the "refer to a variable id outside of the defined range" trick I mentioned above might also carry over to switches as well, so the developer could have more than 5,000 switches.

The only thing is, the developer would have to keep track of what each switch or variable above 5000 is, since there would be no way to name them.
Kazesui,

I'm not saying my code is better or more powerful or even more elegant. I could never have imagined your code, because I didn't know how to convert from base-10 to binary before reading your tutorial! I learned a lot from your tutorial and from comparing it to the method I devised. Thanks.

E/S
Pages: 1