Staredit Network > Forums > SC1 UMS Mapmaking Assistance > Topic: Binary Calculator Bugs/Speed Issues
Binary Calculator Bugs/Speed Issues
Nov 6 2013, 5:26 pm
By: Sylph-Of-Space  

Nov 6 2013, 5:26 pm Sylph-Of-Space Post #1



Hi! I'm running into some serious issues with the Binary calculator that Tuxedo Templar made since I'm trying to use it for in-game calculation on a reasonable time frame...

The first issue is with how it handles division with a large number (x>1000) being divided by a small number (y<100). I understand why this is slow since it only subtracts y once each time it goes through this cycle (and therefore has a ton of subtractions to do before x=0 and division is complete) but I don't know if there is a sensible way to do it faster with only addition and subtraction.

The other issue is actually a pretty serious bug in that the calculator also runs one too many times when dividing odd numbers by even numbers (at least when they are small ones) such as 7/2 since it gives an answer of 4 (though to be fair minor errors like this won't seriously effect what I'm doing) but it seems to be related to an issue with how the calculator handles 0/0 since it gives an output of 1 (i.e. the calculator seems to always run one extra time when not dealing with two even numbers) yet fixing this issue by detecting if minerals=0 and gas=1 just glitches up the whole thing. I'll need to take a better look at it.

Has anyone improved on the calculator, can it be improved?



None.

Nov 6 2013, 6:02 pm MetalGear Post #2



Well I haven't seen Tuxedo's calculator, but I've made a lot of maps with in-built calculators where I've had to multiply values, so the opposite of what you're doing. It is possibly to multiply or divide large figures in just one trigger cycle.

Basically, what you'd do is copy and paste the triggers, but double all the values. Repeat this procedure until your map can do calculations instantly. Do you understand or do you need me to further clarify?



None.

Nov 6 2013, 6:47 pm jjf28 Post #3

Cartography Artisan

High level starcraft algorithm to store A1 / D1 in B

What you have to do is take 2^n*divisor and check if it fits in the dividend (or current remainder), if it does, you add 2^n to B; for n = (BMax - 1)/2 to 0

To check if 2^n*divisor is greater than your dividend you have to subtract equal amounts from both until one of them reaches 0. If it was your 2^n*divisor that reached 0 first (or at the same time), then it fits, and you can add 2^n to B.

Now because you need to subtract from your divisor to get 2^n*divisor, you'll also have to preserve it in another variable to use it at each step, and because your remainder will be zero'd if 2^n*divisor was greater than it, you also have to preserve that, and only subtract from the preserved value if 2^n*divisor was less than the remainder.

A1 = remainder (initially dividend)
A2 = remainder (initially dividend)
Ac = remainder check
D1 = divisor
D2 = divisor
Dc = divisor*2^n
B = quotient

Start:

Copy D1 to D2, and D1*256 to D and Dc
Copy A1 to A2 and Ac

While Ac and Dc are greater than 0, subtract equal amounts from Ac and Dc (henceforth referred to as Ac -=- Dc)
If Dc == 0, do A2 -=- D and add 256 to B

Next...

Copy D2 to D1, and D2*128 to D and Dc
Copy A2 to A1 and Ac

Do Ac -=- Dc
If Dc == 0, do A1 -=- D and add 128 to B

Next...

Copy D1 to D2, and D1*64 to D and Dc
Copy A1 to A2 and Ac

Do Ac -=- Dc
If Dc == 0, do A2 -=- D and add 64 to B

... Repeat till you get to 'add 1 to B'

----------------------------------------------------------

To copy D1 to D2 and D1*256 to D and Dc, do something like this

If ( D1 >= 256 )
{
D1 -= 256
D2 += 256
Dc += 65536
}
if ( D1 >= 128 )
{
D1 += 128
D2 += 128
Dc += 32768
}

... repeat

-------------------------------------------

to do Ac -=- Dc do something like this

If ( Ac >= 256 and Dc >= 256 )
{
Ac -= 256
Dc -= 256
}
If ( Ac >= 128 and Dc >= 128 )
{
Ac -= 128
Dc -= 128
}

... repeat

Optimizations you can do include reusing variables not currently in use and using quartic-countoffs insted of binary countoffs

Post has been edited 2 time(s), last time on Nov 6 2013, 6:54 pm by jjf28.



TheNitesWhoSay - Clan Aura - github

Reached the top of StarCraft theory crafting 2:12 AM CST, August 2nd, 2014.

Nov 6 2013, 6:49 pm MetalGear Post #4



So I'm guessing your triggers look something like this at the moment:

Trigger set 1

Trigger set 2

Trigger set 3




None.

Nov 6 2013, 8:45 pm NudeRaider Post #5

We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

The easiest way to speed up things is to copy triggers so they run multiple times per trigger loop. Actual calculation time will stay the same but at least you don't have to wait 84ms between each step.




Nov 7 2013, 2:39 am Sylph-Of-Space Post #6



I understand the copying triggers aspect but that doesn't really help the issue here. It subtracts y fast enough. The issue is when x is really large and y is say 2, since each cycle going through only subtracts two from x. If x=1000 and y=2 then x/y takes around a full minute! Even halving that is unacceptably slow.

MetalGear, I understand what you're saying in principle but not in practice... I could see how it would speed up the subtraction and then restoring phases but how fast? Also the triggers don't look like that but putting requirements for x would probably fix the issue with it running an extra time...

As for jj28's answer: I'm way too dumb in computing language stuff to understand what you're doing there. I get how triggers work, because it's all spelled out. That answer just makes me derp (but if you can explain it in regular arithmetic or triggers?). I figured there was a different algorithmic way to do this... ugh. I sort of understand what you're saying but I don't get how it works or what -=- means. I'm sorry, I mostly do terrain stuff, I'm not a programmer. I couldn't figure out how Javascript worked...



None.

Nov 7 2013, 2:40 am Sylph-Of-Space Post #7



Here's Tuxedo Templar's map that I was working off of:

Attachments:
Binary_Calculator_v1.0.scx
Hits: 2 Size: 42.69kb



None.

Nov 7 2013, 5:17 am Azrael Post #8



Quote from Sylph-Of-Space
I understand the copying triggers aspect but that doesn't really help the issue here. It subtracts y fast enough. The issue is when x is really large and y is say 2, since each cycle going through only subtracts two from x. If x=1000 and y=2 then x/y takes around a full minute! Even halving that is unacceptably slow.

Each cycle only subtracts y from x once because the triggers haven't been copied. Copying them once would halve the time. Copying them 120 times would turn "a full minute" into "half a second".

And you'd only need to copy them at most 40 times for that effect anyways, because even with one player you can make a trigger for "Player 1, Force 1, All Players".




Nov 7 2013, 11:09 am MetalGear Post #9



I made my own calculator map, and if you test it, you'll see that multiplication sums happen instantly. Also, you are not limited to any x or y value. However, I'm still working on the division, I haven't triggered that yet, so give me a bit more time. If you open up the file, you'll see that I've stacked binary sets for the multiplication triggers. This is what you'll need to do for your division problem.

Attachments:
IC1.1.scx
Hits: 2 Size: 73.04kb



None.

Nov 7 2013, 4:13 pm jjf28 Post #10

Cartography Artisan

@Metal

--

As for my A-=-B operation... Here we're just trying to figure out if A>=B (A greater than or equal to B), and unfortunately starcraft doesn't give us a mechanism to compare two deathcounters, the closest we get is the ability to check if something is equal to 0 or greater than 0 (exactly 0, at least 1).

Lets say that A and B have a maximum value of 3, we could check if A >= B by doing something like this:

If A is at least 1 and B is at least 1
    Subtract 1 from A
    Subtract 1 from B


If A is at least 1 and B is at least 1
    Subtract 1 from A
    Subtract 1 from B

If A is at least 1 and B is at least 1
    Subtract 1 from A
    Subtract 1 from B

If B equals 0
    We know A contained the value of B or more (A >= B)

If B > 0
    We know A contained less than the value of B (A < B)


But of course we don't have to subtract 1 each time, using the powers of 2 (sometimes called binary count-offs) and bumping up the max of A and B to 31 we get:


If A is at least 16 and B is at least 16
    Subtract 16 from A
    Subtract 16 from B

If A is at least 8 and B is at least 8
    Subtract 8 from A
    Subtract 8 from B

If A is at least 4 and B is at least 4
    Subtract 4 from A
    Subtract 4 from B

If A is at least 2 and B is at least 2
    Subtract 2 from A
    Subtract 2 from B

If A is at least 1 and B is at least 1
    Subtract 1 from A
    Subtract 1 from B


If B equals 0
    We know A contained the value of B or more (A >= B)

If B > 0
    We know A contained less than the value of B (A < B)

Highlighted in red is how you do A -=- B.

How the statement highlighted in orange is triggered:


The attached map contains a finished division algorithm, look for triggers whose comments begin with "Division:" under player 1.

Attachments:
Navi Targeting.scx
Hits: 8 Size: 402.79kb

Post has been edited 1 time(s), last time on Nov 7 2013, 5:15 pm by jjf28.



TheNitesWhoSay - Clan Aura - github

Reached the top of StarCraft theory crafting 2:12 AM CST, August 2nd, 2014.

Nov 8 2013, 12:19 am Kaias Post #11



Oreo triggers has math functions (including trigonometric) that can generate all these triggers for you. Some examples:



Oreo triggers uses the max value to generate the math with as few triggers as it can. All of these operations are "instant" (calculations are done all within a single trigger cycle).

If learning and setting up Oreo is too much for you, I'm willing to generate the triggers for you. All I'd need to know is the operations you need performed and which Player/Unit combinations the deathcounters are.



None.

Nov 26 2013, 12:26 am Sylph-Of-Space Post #12



I've been really sick over the past two weeks... can anyone still help me with this issue? I understand the multiplication map but not the division one, and I can't run Oreo triggers since I currently only have access to a Macbook (I'm running SCMDraft in Wine). The only operation I need help with now is division, I could send you my just started map, it's using two death counters for player 7 who will be largely the calculator player (since I only need one operation done at a time for the steps of a damage formula).



None.

Nov 26 2013, 3:20 am Kaias Post #13



Quote from Sylph-Of-Space
I've been really sick over the past two weeks... can anyone still help me with this issue? I understand the multiplication map but not the division one, and I can't run Oreo triggers since I currently only have access to a Macbook (I'm running SCMDraft in Wine). The only operation I need help with now is division, I could send you my just started map, it's using two death counters for player 7 who will be largely the calculator player (since I only need one operation done at a time for the steps of a damage formula).
What are the maximum values that the two deathcounters can be? What unit/player combinations are they? Do you want the division to round or round down (floor)?



None.

Nov 26 2013, 6:50 pm Sylph-Of-Space Post #14



The biggest number it should end up dividing would be around 800,000 and the divisor won't be bigger than 3000. X is the Independent Command Center, Y is the Independent Starport, and the result number is Cave-In, all for Player 7. Ruins is the back-up for calculator memory. Any of the unused units can be used since I haven't used them yet, just started planning it out.

Post has been edited 2 time(s), last time on Nov 26 2013, 6:57 pm by Sylph-Of-Space.



None.

Nov 26 2013, 6:57 pm Sylph-Of-Space Post #15



Let me post the map once I get the multiplication set-up.



None.

Nov 27 2013, 1:18 am Kaias Post #16



Oreo uses disposable Switches to nest its logic and disposable Deathcounters to manipulate the values. I tested it against your specs. In your case it needs 15 disposable switches, 2 disposable deathcounters and generates 517 triggers to perform the operation.



None.

Nov 27 2013, 6:40 pm Sylph-Of-Space Post #17



Thank you!!!!! Of course, I didn't get the multiplication set up since I spent a lot of time working out an idea for division that is really fast and uses only two death counters but unfortunately doesn't work right (and I can think of a couple of reasons why, ;P). I might post the map if I can figure out the issues, but before that I need to just take what already works perfectly! Which of course means copying what Metal Gear sent me. ;D At any rate, here's the map I need division set up on, sorry to be such a pain.

Edit: Oh, and I'm pretty sure it wouldn't matter too much how the numbers are rounded. If it's the same amount of triggers then rounding rather than always rounding down would of course be better. Oh yeah, and there are two switches in use for the calculator, I believe 1 & 2, for starting calculating and for the restore function.

Attachments:
battlesystemfin.scx
Hits: 1 Size: 48.62kb

Post has been edited 1 time(s), last time on Nov 27 2013, 6:46 pm by Sylph-Of-Space.



None.

Nov 28 2013, 10:54 am Kaias Post #18



I took a look at your Player 7 triggers. I know you're not familiar with Oreo Triggers code, but perhaps its intuitive enough for you to get the gist of whats going on:



If so, is this what you're looking for?



None.

Nov 28 2013, 5:04 pm Sylph-Of-Space Post #19



Absolutely!



None.

Nov 28 2013, 8:26 pm Kaias Post #20



I made Terran Marker a disposable deathcounter and named it "Temporary". The calculations use switches 100 through 115. For multiplication I used maximum values of 32767 for LeftHandBit and 127 for RightHandBit.

I've only glanced at the generated triggers, and haven't done any testing. If something needs fixing I can easily regenerate it. Calculation takes 742 triggers in total.

Attachments:
battlesystemfin v2.scx
Hits: 1 Size: 78.97kb



None.

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[11:50 pm]
O)FaRTy1billion[MM] -- nice, now i have more than enough
[11:49 pm]
O)FaRTy1billion[MM] -- if i don't gamble them away first
[11:49 pm]
O)FaRTy1billion[MM] -- o, due to a donation i now have enough minerals to send you minerals
[03:26 am]
O)FaRTy1billion[MM] -- i have to ask for minerals first tho cuz i don't have enough to send
[2024-4-17. : 1:53 am]
Vrael -- bet u'll ask for my minerals first and then just send me some lousy vespene gas instead
[2024-4-17. : 1:52 am]
Vrael -- hah do you think I was born yesterday?
[2024-4-17. : 1:08 am]
O)FaRTy1billion[MM] -- i'll trade you mineral counts
[2024-4-16. : 5:05 pm]
Vrael -- Its simple, just send all minerals to Vrael until you have 0 minerals then your account is gone
[2024-4-16. : 4:31 pm]
Zoan -- where's the option to delete my account
[2024-4-16. : 4:30 pm]
Zoan -- goodbye forever
Please log in to shout.


Members Online: RIVE