
-----------------------------------
Slaivis
Wed Jun 28, 2006 9:57 pm

Help With Array Subscripts
-----------------------------------
Now, I'm not really new to arrays, but this one's got me stumped. 

I'm writing a game, and this is supposed to be the background. 

The goal is to draw lines of a length of 100 pixels, that start at the centre of the screen, grow to their full length, then radiate outwards. The effect is supposed to give the impression that the player is flying through space at warp speeds. 

However, what happens is that I get an array subscript is out of range order. I've tried following what the program does, but I don't understand how it could possibly be out of range because all of my arrays have maximum values either defined by variables, or values that aren't reached by the program at the time of the error. 

I don't know... Perhaps if you run this, you will have either the experience to know what the problem is, or an eye keen enough to spot it. 

Here's the code: 


setscreen ("graphics:800;600,offscreenonly") 
/* 
lc - Light Create? 
lmax - Light Max 
le - Light Exists 
lang - Light Angle 
ldc - Light Distance from Centre 
ldci - Light Distance from Centre Initiated 
lx - X value of Light Distance from Centre 
ly - Y value of Light Distance from Centre 

*/ 

var lc : int 
var lmax : int := 10 
var le : array 1 .. lmax of boolean 
var lang, ldc, ldci : array 1 .. lmax of int 
for i : 1 .. lmax 
le (i) := false 
ldci (i) := 0 
ldc (i) := 0 
end for 

%Initialize the values coresponding to lcdi, so that the program doesn't have to make repetetive calculations while drawing. 
var sina, cosa : array 1 .. 360, 1 .. 100 of int 
for i : 1 .. 360 
for j : 1 .. 100 
sina (i, j) := round (sind (i) * j) 
cosa (i, j) := round (cosd (i) * j) 
end for 
end for 

%Initialize the X and Y values while the light is acutally moving, coresponding to ldc 
var lx, ly : array 1 .. 360, 1 .. (maxx * 2) of int 
for i : 1 .. 360 
for j : 1 .. (maxx * 2) 
lx (i, j) := round (sind (i) * j) 
ly (i, j) := round (cosd (i) * j) 
end for 
end for 


%Declare the procedures so that the order of their actual declaration does not matter 
forward proc createlight (n : int) 
forward proc createlightQ 
forward proc light (n : int) 


%Set all the values of a new 'particle' of light to their starting position. 
body proc createlight (n : int) 
le (n) := true 
randint (lang (n), 1, 360) 
ldc (n) := 0 
ldci (n) := 0 
lx (lang (n), 1) := 0 
ly (lang (n), 1) := 0 
end createlight 

%Generate a random number to decide whether or not another 'particle' of light should be created. 
body proc createlightQ 
randint (lc, 1, 100) 
%If it is decided that another 'particle' of light should be created... 
if lc > 95 then 
for i : 1 .. lmax 
%Find a 'slot' that is not taken. 
if le (i) = false then 
%Create the 'particle' in an untaken 'slot'. 
createlight (i) 
exit 
end if 
end for 
end if 
end createlightQ 

%Draw any 'particle'. 
body proc light (n : int) 
%If the length of the 'particle' is not full. 
if ldci (n) = 99 then 
%Free up the slot. 
%le (n) := false 
end if 
end light 



drawfillbox (0, 0, maxx, maxy, 7) 
loop 
%drawfillbox (0, 0, maxx, maxy, 7) 
createlightQ 
for i : 1 .. lmax 
%Move each particle accordingly. 
if ldci (i) < 97 then 
ldci (i) += 3 
elsif ldci (i) > 97 then 
ldc (i) += 3 
end if 
if le (i) = true then 
light (i) 
end if 
end for 

View.Update 
end loop 


If you've made it this far, I salute you. 

- Thanks

-----------------------------------
Mazer
Wed Jun 28, 2006 10:04 pm


-----------------------------------
I haven't got Turing with me, but a couple of things you may want to consider in order for us to help you:
1) Tell us where you get the error (ie, line number), this makes it easier on people who (like myself) don't have Turing available
2) Indent! For the same reason as above and more.

-----------------------------------
Slaivis
Wed Jun 28, 2006 10:45 pm


-----------------------------------
Alright, I was mostly counting on people running the program in Turing and hitting F2 to find both of those things, but I'll paste the information into the forum. 

This code should be indented, and the error first occurs at the variable that I've bolded. I haven't included the line number because the lines tend to get shifted over in the post. 

This is really irritating. I can't bold anything with the 'code' option, and the 'quote' option removes all indentation. I also seem to be unable to edit my post here.

To make the problem code the most visible, I've surrounded it by three blank lines and commented on it.


setscreen ("graphics:800;600,offscreenonly") 
/* 
lc - Light Create? 
lmax - Light Max 
le - Light Exists 
lang - Light Angle 
ldc - Light Distance from Centre 
ldci - Light Distance from Centre Initiated 
lx - X value of Light Distance from Centre 
ly - Y value of Light Distance from Centre 

*/ 

var lc : int 
var lmax : int := 10 
var le : array 1 .. lmax of boolean 
var lang, ldc, ldci : array 1 .. lmax of int 
for i : 1 .. lmax 
    le (i) := false 
    ldci (i) := 0 
    ldc (i) := 0 
end for 

%Initialize the values coresponding to lcdi, so that the program doesn't have to make repetetive calculations while drawing. 
var sina, cosa : array 1 .. 360, 1 .. 100 of int 
for i : 1 .. 360 
    for j : 1 .. 100 
        sina (i, j) := round (sind (i) * j) 
        cosa (i, j) := round (cosd (i) * j) 
    end for 
end for 

%Initialize the X and Y values while the light is acutally moving, coresponding to ldc 
var lx, ly : array 1 .. 360, 1 .. (maxx * 2) of int 
for i : 1 .. 360 
    for j : 1 .. (maxx * 2) 
        lx (i, j) := round (sind (i) * j) 
        ly (i, j) := round (cosd (i) * j) 
    end for 
end for 


%Declare the procedures so that the order of their actual declaration does not matter 
forward proc createlight (n : int) 
forward proc createlightQ 
forward proc light (n : int) 


%Set all the values of a new 'particle' of light to their starting position. 
body proc createlight (n : int) 
    le (n) := true 
    randint (lang (n), 1, 360) 
    ldc (n) := 0 
    ldci (n) := 0 
    lx (lang (n), 1) := 0 
    ly (lang (n), 1) := 0 
end createlight 

%Generate a random number to decide whether or not another 'particle' of light should be created. 
body proc createlightQ 
    randint (lc, 1, 100) 
    %If it is decided that another 'particle' of light should be created... 
    if lc > 95 then 
        for i : 1 .. lmax 
        %Find a 'slot' that is not taken. 
            if le (i) = false then 
            %Create the 'particle' in an untaken 'slot'. 
                createlight (i) 
                exit 
            end if 
        end for 
    end if 
end createlightQ 

%Draw any 'particle'. 
body proc light (n : int) 
%If the length of the 'particle' is not full. 
    if ldci (n) = 99 then 
    %Free up the slot. 
        %le (n) := false 
    end if 
end light 



drawfillbox (0, 0, maxx, maxy, 7) 
loop 
    %drawfillbox (0, 0, maxx, maxy, 7) 
    createlightQ 
    for i : 1 .. lmax 
    %Move each particle accordingly. 
        if ldci (i) < 97 then 
            ldci (i) += 3 
        elsif ldci (i) > 97 then 
            ldc (i) += 3 
        end if 
        if le (i) = true then 
            light (i) 
        end if 
    end for 

    View.Update 
end loop 
 

-----------------------------------
Mazer
Thu Jun 29, 2006 7:56 am


-----------------------------------
The problem isn't that n is out of the range of ldc, but that ldc(n) is out of the range of lx. Is ldc(n) ever greater than zero?

-----------------------------------
Slaivis
Thu Jun 29, 2006 12:09 pm


-----------------------------------
The problem isn't that n is out of the range of ldc, but that ldc(n) is out of the range of lx. Is ldc(n) ever greater than zero?

ldc(n) is never less than zero.

I think you've led me to the solution.

The thing is that ldc(n) is set to zero to initialize it, but the subscripts for lx are set from a minium value of one.

Thus, my subscript is actually below the range, which is what completely threw me off because I'd never encountered something like that.

This means that I should initialize my value of ldc as 1.


- Thanks, Mazer!
