• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[function] CodeConverter

Level 16
Joined
Oct 12, 2008
Messages
1,570

CodeConverter


What is CodeConverter?
CodeConverter is a function which can convert any x-base code into an y-base code. Confusing? I shall explain.
Our normal number system is a 10-base code, meaning it has 10 different characters (0,1,2,3,4,5,6,7,8,9,0). When you think about numbers, you think them in a 10-base number normally, but when a computer thinks, he thinks in a 2-base number, binary code.
This function can convert an x-base number into an y-base number, with for x and y any number higher than 1.

The code
JASS:
library CodeConverter
    function ConvertCode takes integer amount, integer oldbase, integer newbase returns integer
        local integer i = 0
        local integer i2 = 0
        local integer current = 0
        local string amounts = I2S(amount)
        local integer length = StringLength(amounts)
        local string c
        local integer plus = StringLength(I2S(oldbase))
        
        // no x-base or y-base number can be made when x or y are below 2
        if oldbase < 2 or newbase < 2 then
            return -1
        endif
        
        // Why would you want to convert to the same base?
        if oldbase == newbase then
            return amount
        endif
        
        // First we convert to 10-base. But if the old base is already 10, there is no need.
        if oldbase != 10 then
            loop
                set c = SubString(amounts,length-plus-(i*plus),length-(i*plus))
                exitwhen c == "" or length-i == 0
                set current = current + (S2I(c)*R2I(Pow(oldbase,i)))
                set i = i + 1
            endloop
            set i = 0
        endif
        
        // Now we convert to y-base, but if y is 10, we dont need to, because we already did that above.
        if newbase != 10 then
            set c = ""
            loop
                exitwhen Pow(newbase,i) > current
                set i = i + 1
            endloop
            set i = i - 1
            loop
                exitwhen i < 0
                if current >= Pow(newbase,i) then
                    loop
                        exitwhen current < Pow(newbase,i)
                        set i2 = i2 + 1
                        set current = current - R2I(Pow(newbase,i))
                    endloop
                endif
                set c = c + I2S(i2)
                set i2 = 0
                set i = i - 1
            endloop
            return S2I(c)
        else
            return current
        endif
        return -1
    endfunction
endlibrary

A question to you:
What will actually happen when I insert a negative number? Currently it will return the converted number, only positive. should it return negative or positive?

Confession
This can probably be done alot easier without converting to 10-base first, but I do not have the knowledge how to.

-Yixx,,-
 
Last edited:
Level 16
Joined
Oct 12, 2008
Messages
1,570
How is making it take a string logical?
And i think the current oldbase/newbase thing (where they are max+1) is good, it is an understandable form this way, and quite logic i think..
JASS:
call ConvertCode(10110101,2,10)
converts 10110101 from binary code into our numerical system..

Also, how do you think that it doesnt necessarily convert from any base to any base?
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
This function on it's own is not meant for your own codes, but with a wrapper function you can create your own, which I did actually..
Using StringTable..

JASS:
globals
    private StringTable ST
    private integer MaxAmount = 24
    private integer IntPerChar = StringLength(I2S(MaxAmount))
endglobals
function ConvertYOURCODEto10 takes string code returns integer
    local integer l = StringLength(code)
    local integer i = 0
    local string c
    local string input
    loop
        set c = SubString(code,length-IntPerChar-(IntPerChar*i),length-plus)
        exitwhen c == "" or length-plus <=0
        set input = I2S(ST[c]) + input
        set i = i + 1
    endloop
    return ConvertCode(S2I(input),MaxAmount,10)
endfunction
That is how it will look, where you input what value each character of your code has in the StringTable like this:
JASS:
function Init takes nothing returns nothing
    set ST["A"]=0
    set ST["B"]=1
    // etc..
endfunction


Should I add this in a textmacro or such with the system?
 
Level 11
Joined
Apr 29, 2007
Messages
826
Like this? :)
JASS:
library_once Convert
{
    public constant string DEC = "0123456789"
    public constant string HEX = "0123456789ABCDEF"
    public constant string BIN = "01"
    public constant string OCT = "01234567"
    
    #define
    {
        <Convert_DECIMAL>      = Convert_DEC
        <Convert_HEXADECIMAL>  = Convert_HEX
        <Convert_BINARY>       = Convert_BIN
        <Convert_OCTAL>        = Convert_OCT
    }

    #include "cj_types_private.j"

    //Returns the position where a string is inside another string.
    private int IndexOf(string base, string find)
    {
        int result = 0;
        int length = StringLength(base);
        int flength = StringLength(find);
        
        if length > flength
        {
            do
            {
                if SubString(base, result, result+flength) == find {return result}
            } whilenot(++result > length)
        }
        
        return -1;
    }
    
    string Convert(string num, string from, string to)
    {
        string result = "";
        
        int fl = StringLength(from); //From length
        int tl = StringLength(to); //To length
        
        string nf = SubString(from, 0, 1) //First character from
        string div = "";
        
        int resultmod = 0;
        int resultdiv = 0;
        int i = 0
        
        do
        {
            i = 0;
            resultmod = IndexOf(from, SubString(num, 0, 1));
            div = "";
            
            do
            {
                if resultmod >= tl
                {
                    resultdiv = resultmod/tl;
                    div = div+SubString(from, resultdiv, resultdiv+1);
                    resultmod -= resultdiv*tl;
                }
                else
                {
                    div = div+nf;
                }
                
                exitwhen(++i >= StringLength(num))
                resultmod = (resultmod*fl)+IndexOf(from, SubString(num, i, i+1));
            }
            
            i = 0;
            do
            {
                exitwhen(SubString(div, i, i+1) != nf)
            } whilenot(++i >= StringLength(div))
            
            div = SubString(div, i, StringLength(div));
            result = SubString(to, resultmod, resultmod+1)+result;
            num = div;
            
            exitwhen num == ""
        }
        
        return result;
    }
}
 
Last edited:
Top