HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Need help going through a huge array.

02-27-2003, 09:24 PM#1
FyreDaug
Alright my Elseif's werent working, so I decided to try using ifs at the risk of a memory leak, but it completely crashes War3 when it hits the trigger.

Alright using 1 different string, with an array of 1-216 there is 80 options each could be...

Ex: If String[2] = "A" then set string[2] = 440.

For each array from 1-192 it has to do 80 checks. I was using a loop to keep the code shorter but that wont work.

It only has to go to 192, because that's what player 12's last digit in the string is. I'm using
set String[(Player Number of Triggering Player) +12], it adds 12 each time I change a digit, the first digit is P#+12, the second is P#+24, third is P#+36, etc. So no values are overlapping.

Does anyone have a better suggestion on what to do with this, that is quick and will only check YOUR ARRAYS (+base 12 [12,24,36 etc])?

The array numbers that are added onto the player number is 12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,204

Each playernumber + arrayed base 12 is a seperate digit that will be added later, so they all need to remain seperate.

I hope I made myself clear (enough)......
02-27-2003, 09:54 PM#2
Guest
If it crashes could it be the possibility that you cant have over a certain number like 192? or are you allowed to have as many as you want, if so, i believe that it repeatidly checks, do you have a trigger that tells it to stop checking? because when it checks it checks 1000000000000000000000 basicly infinity times a second, and often cause's your game to lock so best have a trigger we're it tells it to stop checking.

Hope this was of any help to you.
02-27-2003, 10:08 PM#3
Aiursrage2k
I often use the edit button so the post below does not make much sense.

function a2I takes string command returns integer
local integer rc
local string array str
local integer i = 0
set str[0] = "a"
set str[1] = "b"
set str[2] = "c"
loop
exitwhen i > 3
if(commmand == str[i])
rc = i
i = 3
endif
set i = i + 1
endloop
return rc
endfunction
02-27-2003, 10:35 PM#4
FyreDaug
Aiursrage2k, I'm fairly new to JASS, but by what I understand, you are telling me that I use 1 string I create a loop and use the loop as the array value. I'm doing that right now, but it doesn't look the way yours is, mine is like this:

Code:
//This is a portion of my code.

//Trigger name=Converting

function Trig_Converting_Func001001 takes nothing returns boolean
    return ( udg_String[GetForLoopIndexA()] == "0" )
endfunction

function Trig_Converting_Func002001 takes nothing returns boolean
    return ( udg_String[GetForLoopIndexA()] == "1" )
endfunction


function Trig_Converting_Func003001 takes nothing returns boolean
    return ( udg_String[GetForLoopIndexA()] == "2" )
endfunction

function Trig_Converting_Func004001 takes nothing returns boolean
    return ( udg_String[GetForLoopIndexA()] == "3" )
endfunction

function Trig_Converting_Actions takes nothing returns nothing
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 216
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
            if ( Trig_Converting_Func001001() ) then
                set udg_String[GetForLoopIndexA()] = "0"
            endif
//If 0 set 0
            if ( Trig_Converting_Func002001() ) then
                set udg_String[GetForLoopIndexA()] = "1"
            endif
//If 1 set 1
            if ( Trig_Converting_Func003001() ) then
                set udg_String[GetForLoopIndexA()] = "2"
            endif
//If 2 set 2
            if ( Trig_Converting_Func004001() ) then
                set udg_String[GetForLoopIndexA()] = "3"
            endif
//If 3 set 3
    set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction

It goes on and had things like A=10, that sorta thing, there is 80 characters, numbers/letter/symbols.

Using IF statements seems to be the worst method right now, but it has to go through 216 arrays, 80 times = 17280 functional changes.

I even tried using a single loop, only happens once (index=1, end=1) and it still closed on me. I know for sure it's this code because of all the IF's and the trigger before works fine.


EDIT: I was thinking of creating 1 string variable with all 80 characters 0123456789ABCDEF..... etc, and refer to the substring in each one, but that's still basically the same thing, but with more work. (Although if someone does crack open my map it would be a little harder to trace.)
02-27-2003, 10:40 PM#5
Aiursrage2k
Revision1
Code:
//Search for character, retuns index, 
//examples: 'a' returns 1,    'z' returns 26

function a2I takes string c returns string
  local string rc
  local string str
  local integer i = 0
  local integer max = 52
  set str = "abcdefghhijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVXYZ"
  loop 
    exitwhen i > max
    if(c ==  SubStringBJ(str, i, i)) then
      set rc = I2S(i)
      set i = max
    endif
    set i = i + 1
  endloop
  return rc
endfunction

//Converts the characters to there numeric equvilaents
function Convert takes integer pnum returns nothing
   local integer i = 0
   loop 
      exitwhen i > 16
      set udg_String[pnum+i*12] = a2I(udg_String[pnum+i*12])       
      set i = i + 1
   endloop  
endfunction

//Changes all player#s' elements of the array to its 
//corresponding number, for example 1 converts elements 
//1,13,25,37 etc, 12 convert elements 12,24,36, etc...
function Conversion takes nothing returns nothing
  Convert(1)
endfunction
02-27-2003, 10:43 PM#6
FyreDaug
I'm still kinda new and I don't know exactly how do that.

Just to make sure it's clear the array goes to a value of 216 String[216] and there is 80 different checks it needs to do, if it's an A do this, but if it's a Z do this instead, but IF's suck for large things. Could you elaborate a little on what to do?

-FyreDaug (In learning process)
02-27-2003, 11:07 PM#7
Guest
to comment on what was said about arrays having limits, no they do not have limits. their only limit is your ram, of course I could be wrong if triggers don't follow the same rules as C does, but they probably do
02-27-2003, 11:08 PM#8
Aiursrage2k
I think the limit an array can hold is 1024 elements.
02-27-2003, 11:58 PM#9
FyreDaug
Quote:
set str[0] = "a"
set str[1] = "b"
set str[2] = "c"
...
set str[80] = "z"
I don't get this part, say you type in 123kghsa354f, and it is supposed to convert that to numbers, obviously the numbers remain, but the letters have to have values.

Quote:
if(c == str[i]) then
set rc = I2S(i)

What if c isn't equal to the string?

Quote:
return rc
What is this?

Quote:
function Convert takes integer pnum returns nothing
local integer i = 0
loop
exitwhen i > 16
set udg_String[pnum+i*12] = a2I(udg_String[pnum+i*12])
set i = i + 1
endloop
endfunction
I have no idea what this is supposed to do (what is the 16 for and what is pnum?)

Quote:
function Conversion takes nothing returns nothing
Convert(1)
endfunction
This does what exactly?
02-28-2003, 01:50 AM#10
Guest
Quote:
I don't get this part, say you type in 123kghsa354f, and it is supposed to convert that to numbers, obviously the numbers remain, but the letters have to have values.

What your doing here is setting up all the possible strings that could be correct. When the loop hits the right one, it's going to return the value "i" in string format as "rc" then it's going to make "i" the same value as the exit condition so that the loop ends. If the loop doesn't hit the right value, it will just add +1 to "i" and continue the loop until the condition is met.

I would explain the rest, but dinner's ready and the wifey wants me off the computer.
02-28-2003, 03:19 AM#11
Aiursrage2k
It seems I have misunderstood what you wanted to happen, from your sample code, I figured the string array was only one character per element (a basic char array).

I thout elements 12,24,36,etc.. belonged to player12, 1,13,25,etc belongs to player1. In which case it should work. Unless you are saying each element of the string contains more then one character, in which case it becomes slightly more difficult. If anyone can help to improve the code I provided it would be apprecitated. See Revision1 :mtk:
02-28-2003, 08:09 AM#12
rwxr-xr-x
If I understand you correctly, you are wanting to associate each letter/number/symbol with a different number. In which case, try the following:

Create 2 variables, one of type string and set it to all of the numbers/letters/symbols (can be done at map initialization, or in your trigger), and the other a string array associating what you want replaced, i.e.

set udg_replaceables = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFG..."
set udg_newStr[0] = "43"
set udg_newStr[1] = "12"
set udg_newStr[2] = "56"
...
set udg_newStr[10] = "442"
...

In the case above, newStr[0] would represent what you want in place of the 0, newStr[1] for 1, newStr[10] for A, etc...

In your trrigger...

Code:
function Convert_Actions takes nothing returns nothing
    local integer x = 0 // position in udg_String array
    local integer y = 1 // substring position in udg_replaceables
                        // and position for udg_newStr array
    local integer p = 0 // associate player number

    loop                // loop for every player
        exitwhen p > 11
        loop            // loop through udg_String
            exitwhen x > 215
            loop        // loop through udg_replaceables
                exitwhen y > 80
                    if ( udg_String[x] == SubStringBJ(udg_replaceables, y, y) ) then
                        set udg_String[x] == udg_newStr[y]
                        exitwhen true  // if we match, exit the loop
                    endif
                set y = y + 1
            endloop
            set x = x + 12
        endloop
        set p = p + 1    
    endloop

endfunction

Hope that helps and is along what you want to do. It takes 3 loops to do everything at once. I assumed you wanted to do this for all players at once which this accounts for. If not, you would remove the outermost loop, and set x intialy to the start of the array for the right player (0 for player 1, 1 for player 2, etc...)

*EDIT* I added another exitwhen condition inside the "if" statement, since I forgot to add it initialy. The idea is, if you find a match, you don't want to keep looping through the udg_replaceables string, and this forces the loop to exit once a match is found.
02-28-2003, 12:55 PM#13
FyreDaug
Sid67, I think I get what you mean, but the return rc is where I'm lost. Does that mean it goes back to where you set rc (like a label) or does it show it's value?
02-28-2003, 03:12 PM#14
rwxr-xr-x
return statements have two effects; 1) they cause the function to end, and 2) if you give it an expression, the value of it is given to whatever called it. In this case return rc is causing the function to return the value of rc.

Quick code example:
Code:
function TellingTheTruth takes nothing returns boolean
    local boolean b = false

    return b
endfunction

function MyFunction takes nothing returns nothing
    if ( TellingTheTruth() ) then
        DisplayText("Good for you")
    else
        DisplayText("Very Bad!")
    endif
endfunction

Note that the type of b is boolean that is being returned in the function TellingTheTruth which matches the return type of the function (defined by returns boolean. Whatever you return must match the type that you specify in your function decleration. So if you wanted to return a string, your function declaration would look like...

function TellingTheTruth takes nothing returns string
02-28-2003, 06:41 PM#15
Guest
That post, rwxr-xr-x, is worth adding a link to in my Custom Text tutorial. Good explanation.