April 28, 2024, 05:20:00 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Dynamic 2D Array

Started by Blue Steel, April 05, 2007, 04:10:52 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Blue Steel

April 05, 2007, 04:10:52 PM Last Edit: April 07, 2007, 06:04:54 PM by Blue Steel
I'm trying to

BlocksAccrossScreen=40
BlocksDownScreen=30
dim ScreenArray[BlocksAccrossScreen,BlocksDownScreen] as int

duplicate definition of variable or label - int
duplicate definition of variable or label - int

it seems that EBasic can't do it :(
it seems that EBASIC needs a REAL number in the Dim's

I really need this functionality

Am i doing it correctly or is there another way around it..
real values aren't going to work in other projects .. where I ask the user what values they need in a Dim..

  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic

Ionic Wind Support Team

Arrays are defined with constants. 

const BlocksAccrossScreen=40
const BlocksDownScreen=30
dim ScreenArray[BlocksAccrossScreen,BlocksDownScreen] as int

Ionic Wind Support Team

Blue Steel

thanks Paul .. i thought i had tried something similar(using const)  but it didn't work .. this time it worked fine..

next question is how would i assingn a users input to a const LOL
(trying as i type this ...)
  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic

Ionic Wind Support Team

You can't.  Arrays are compile time entities, they are not 'allocated'.  Their size must be known by the compiler long before an executable is created and ran.   Array's either exist on the stack or in a global memory segment that is created when Windows loads your executable.

If you need a dynamic array you have to use memory allocation, NEW, DELETE, etc.

Paul.
Ionic Wind Support Team

Bruce Peaslee

Bruce Peaslee
"Born too loose."
iTired (There's a nap for that.)
Well, I headed for Las Vegas
Only made it out to Needles

Blue Steel

actually i was serous.. :(

I don't care how i have to do it.. I need a way to assign a storage area depending on what values the end user states..

egample one:  UniFile (A user definable Sequential database)
Psudo code
input how many fields do you want in this Database
input max number of records
for x=0 to input amount
input field name:
input max data size for this field
next x

dim fields[number user typed in, max records]

save this data to the header of a file
numfields
maxrecords
field1 name
data1 max length
...
... same for all the fields
...
actual data for each field for record
...
... actual data for next record
...
EOF

Example2: a game where user sets size of playing field and number of eliments and speed etc

Psedo code
input how many colums
input how many rows
input how many different objects

build an array of size colums,rows to store position of ellements and be able to compare contents


Both of these examples are programs i'm trying to convert from my original programs on the Commodore C64.

one of them (the DB one) will have to re-use the old data files

once the user has typed in the Values or they are read in from the file they are then known real figures which don't change for the current run of that program .. next time they run it .. (to start up a new database or new game) they can change these values .. but only on a fresh run of the program

its sad to know that the Old Commodore C64 used to be able to do this using its ancient basic and the moderrn day programming languages can't
it used dim z(x,y)
and if the values of x or y were empty  numbers then they reverted to 0,0

and stayed as they were set till the end of that run of the program .. they arn't dynamic as such because x and y don't change once input

Can someone please show me how I can do something similar (using New etc.. or what ever) in Ebasic

My old next door neighbour has been using this program i wrote for him now for close to 20 years .. lol and wants to update to a PC without loosing all his data so he's asked me to port my original program accross to the PC

I understand now fully that Dim z[x,y] will no longer work with user input values .. but how do i do it with the modern languages
  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic

REDEBOLT

I would like to help you out, Cameron, when
I finish the database problem with splakidas.
Regards,
Bob

Blue Steel

Below is the code from a test program i wrote using the NEW.. pointer method

I'm having problems with junk appearing in the cells and it not working at all with large numbers (larger than say 42 for Colums and or rows greater than say 25)

' My attempt a a roll your own 2d array type of thing from a users inpout for the size of the array
' compile as Console


' Notice .. if Colums goes above 42 then nothing gets displayed
' i'm also getting garbage in some Cells if i say go above 40,24
' if i keep the numbewrs small it doesn't seem to happen.. maybe i've been lucky
'
' What am i doing Wrong .. Shouldn't i be able to type in any REAL number in the inputs and have this thing work

string  temp$
int Row,Colum,BlocksAccrossScreen,BlocksDownScreen
pointer pScreen

INPUT "How many blocks do you want accross the screen ", BlocksAccrossScreen
INPUT "How many blocks do you want down the screen ", BlocksDownScreen

' set up area for our array pScreen[Colum + Row] just like
' dim ScreenArray[BlocksAccrossScreen,BlocksDownScreen]
pScreen = NEW(INT,BlocksAccrossScreen*BlocksDownScreen)

' loop to set original contents of pScreen[Colum + Row] just like
' ScreenArray[Colum,Row]
for Row = 0 to BlocksAccrossScreen
for Colum=0 to BlocksDownScreen
pScreen[Colum + (Row*BlocksAccrossScreen)] = 0
next Colum
next Row

' Setup a dummy row,colum reference point
Row = rnd(BlocksDownScreen-1)+1
Colum = rnd(BlocksAccrossScreen-1)+1

' Display Where we've placed it so that we can compare it to the final output
print
print "Value Stored in Row:",Row," Colum:",Colum
print
' Store something inside pScreen[Colum + Row]
' just like we would an array ScreenArray[Colum,Row]
pScreen[Colum + (Row*BlocksAccrossScreen)] = 1

'Display full contents of our array pScreen[Colum + Row] just like we would an array ScreenArray[Colum,Row]
' for Row = 1 to BlocksDownScreen
' for Colum=1 to BlocksAccrossScreen
' print pScreen[Colum + (Row*BlocksAccrossScreen)],
' next Colum
' print
' next Row

' Display Cells that don't contain 0
' should only be our one cell that we placed something into

for Row = 1 to BlocksDownScreen
for Colum=1 to BlocksAccrossScreen
if pScreen[Colum + (Row*BlocksAccrossScreen)]<>0
print "Row:",Row," Colum:",Colum," Contents:",pScreen[Colum + (Row*BlocksAccrossScreen)]
endif
next Colum
next Row

' Wait for input after display then exit
print
input temp$
DELETE pScreen
  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic

LarryMc

After this line in your code:pScreen = NEW(INT,BlocksAccrossScreen*BlocksDownScreen)

make the following change to every occurance of pScreen from:pScreen to #<INT>pScreen

After that I did a 550x 550 grid and set 2 points to non zero and they both showed up as expected.

I tried 600x600 and I got a GPF(I thinks due to product being more than 32784, but not sure)

Also, for some reason it doesn't like large non square grids
320x320 works but 320x50 doesn't

I don't see why.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

LarryMc

It was crashing with no-square arrays because in your loop where you were setting everything to zero you had your across and down wrong.
' loop to set original contents of pScreen[Colum + Row] just like
' ScreenArray[Colum,Row]
for Row = 0 to BlocksAccrossScreen
for Colum=0 to BlocksDownScreen
pScreen[Colum + (Row*BlocksAccrossScreen)] = 0
next Colum
next Row
should be' loop to set original contents of pScreen[Colum + Row] just like
' ScreenArray[Colum,Row]
for Row = 0 to BlocksDownScreen
for Colum=0 to BlocksAccrossScreen
pScreen[Colum + (Row*BlocksAccrossScreen)] = 0
next Colum
next Row


So the only thing that is left is that it doesn't like a grid whose product is greater than 327000.
Can't answer that one.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Blue Steel

thanks Larry

below is my modified code with more comments and some slightly reworking

but its still got problems .. read the comments to see


' My attempt a a roll your own 2d array type of thing from a users inpout for the size of the array
' compile as Console

' still not quite working right
' Larry McCaughn pointed out 327680 seemed to be the cut off point
' but to test try values of 1,99999999 (works) and 789,1 (doesn't work) 788,1 (does work)
' so it doesn't look like a magic number thing
' no difference if i use # or #<int> .. yes i tried both

string  temp$
int Row,Colum, BlocksAccrossScreen,BlocksDownScreen
pointer pScreen

INPUT "How many blocks do you want accross the screen ", BlocksAccrossScreen
INPUT "How many blocks do you want down the screen ", BlocksDownScreen

' set up area for our array pScreen[Colum + Row] just like
' dim ScreenArray[BlocksAccrossScreen,BlocksDownScreen]
' added +1 to input values cause arrays sert from 0 and not 1
' so needed to add 1 to reference contents from 1 to input value
' as opposed to 0 to input value-1
pScreen = NEW(int,(BlocksAccrossScreen+1)*(BlocksDownScreen+1))

' loop to set original contents of pScreen[Colum + Row] just like
' ScreenArray[Colum,Row]

' (Thanks goes to Larry McCaughn for tracking down what i'd done wrong)
' #<int> tells it that its an int ???
' I thought it was for TypeCasting
' IE: for forcing input/output to a particular type
' Tried it and it worked then
' I then tried it with just the # and it worked as well
' didn't think <int> was necessary as all values set to it were of type int anyway
' as it was told to expect its comming into it as it was initialized to be
' So a tip for new programmers if your not sure what type of data is being fed to it
' use #<int> and not just #

for Row = 0 to BlocksDownScreen+1
for Colum = 0 to BlocksAccrossScreen+1
#pScreen[Colum + (Row*(BlocksAccrossScreen+1))] = 0
next Colum
next Row

' Setup a dummy row,colum reference point
' the -1 is to take into account that arrays start from 0 not 1
' and the +1 added on the end is to make it from 1 to input value
' so Arrays 0,x and y,0 arn't being used and can effectivly be used to store other values in your program
Row = rnd(BlocksDownScreen-1)+1
Colum = rnd(BlocksAccrossScreen-1)+1

' Display Where we've placed it so that we can compare it to the final output
print
print "Value Stored in Row:", Row, " Colum:", Colum
print
' Store something inside pScreen[Colum + Row]
' just like we would an array ScreenArray[Colum,Row]
#pScreen[Colum + (Row*BlocksAccrossScreen)] = 1

' Display Cells that don't contain 0
' should only be our one cell that we placed something into
for Row = 1 to BlocksDownScreen
for Colum = 1 to BlocksAccrossScreen
if #pScreen[Colum + (Row*BlocksAccrossScreen)] <> 0
print "Row:", Row, " Colum:", Colum, " Contents:", #pScreen[Colum + (Row*BlocksAccrossScreen)]
endif
next Colum
next Row

' Wait for input after display then exit
print
DELETE pScreen
input temp$
'sometimes crashes when program ends too :( i duno why



below is the same code without all the comments (for those of you who find it hard to follow with all my comments)

' compile as Console

string  temp$
int Row,Colum, BlocksAccrossScreen,BlocksDownScreen
pointer pScreen

INPUT "How many blocks do you want accross the screen ", BlocksAccrossScreen
INPUT "How many blocks do you want down the screen ", BlocksDownScreen

pScreen = NEW(int,(BlocksAccrossScreen+1)*(BlocksDownScreen+1))

for Row = 0 to BlocksDownScreen+1
for Colum = 0 to BlocksAccrossScreen+1
#pScreen[Colum + (Row*(BlocksAccrossScreen+1))] = 0
next Colum
next Row

Row = rnd(BlocksDownScreen-1)+1
Colum = rnd(BlocksAccrossScreen-1)+1
print
print "Value Stored in Row:", Row, " Colum:", Colum
print
#pScreen[Colum + (Row*BlocksAccrossScreen)] = 1

for Row = 1 to BlocksDownScreen
for Colum = 1 to BlocksAccrossScreen
if #pScreen[Colum + (Row*BlocksAccrossScreen)] <> 0
print "Row:", Row, " Colum:", Colum, " Contents:", #pScreen[Colum + (Row*BlocksAccrossScreen)]
endif
next Colum
next Row

print
DELETE pScreen
input temp$
  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic

Ionic Wind Support Team

Yer FOR loops are still a little bit off. 

FOR x = 0 to 10
PRINT x," "
NEXT x
...
0 1 2 3 4 5 6 7 8 9 10


It includes the last value.  So your loops are wrong as they are accessing memory beyond your allocated limit.

Paul.
Ionic Wind Support Team

Blue Steel

Thanks Paul .. modified yet again.. Still  crashes on exit sometimes.. the other problems remain :(


' My attempt a a roll your own 2d array type of thing from a users inpout for the size of the array
' compile as Console

' still not quite working right
' Larry McCaughn pointed out 327680 seemed to be the cut off point
' but to test try values of 1,99999999 (works) and 789,1 (doesn't work) 788,1 (does work)
' so it doesn't look like a magic number thing
' no difference if i use # or #<int> .. yes i tried both

string  temp$
int Row,Colum, BlocksAccrossScreen,BlocksDownScreen
pointer pScreen

INPUT "How many blocks do you want accross the screen ", BlocksAccrossScreen
INPUT "How many blocks do you want down the screen ", BlocksDownScreen

' set up area for our array pScreen[Colum + Row] just like
' dim ScreenArray[BlocksAccrossScreen,BlocksDownScreen]
pScreen = NEW(int,BlocksAccrossScreen*BlocksDownScreen)

' loop to set original contents of pScreen[Colum + Row] just like
' ScreenArray[Colum,Row]

' (Thanks goes to Larry McCaughn for tracking down what i'd done wrong)
' #<int> tells it that its an int ???
' I thought it was for TypeCasting
' IE: for forcing input/output to a particular type
' Tried it and it worked then
' I then tried it with just the # and it worked as well
' didn't think <int> was necessary as all values set to it were of type int anyway
' as it was told to expect its comming into it as it was initialized to be
' So a tip for new programmers if your not sure what type of data is being fed to it
' use #<int> and not just #

for Row = 0 to BlocksDownScreen
for Colum = 0 to BlocksAccrossScreen
#pScreen[Colum + Row*BlocksAccrossScreen] = 0
next Colum
next Row

' Setup a dummy row,colum reference point
' the -1 is to take into account that arrays start from 0 not 1
' and the +1 added on the end is to make it from 1 to input value
' so Arrays 0,x and y,0 arn't being used and can effectivly be used to store other values in your program
Row = rnd(BlocksDownScreen-1)+1
Colum = rnd(BlocksAccrossScreen-1)+1

' Display Where we've placed it so that we can compare it to the final output
print
print "Value Stored in Row:", Row, " Colum:", Colum
print
' Store something inside pScreen[Colum + Row]
' just like we would an array ScreenArray[Colum,Row]
#pScreen[Colum + Row*BlocksAccrossScreen] = 1

' Display Cells that don't contain 0
' should only be our one cell that we placed something into
for Row = 1 to BlocksDownScreen
for Colum = 1 to BlocksAccrossScreen
if #pScreen[Colum + Row*BlocksAccrossScreen] <> 0
print "Row:", Row, " Colum:", Colum, " Contents:", #pScreen[Colum + Row*BlocksAccrossScreen]
endif
next Colum
next Row

' Wait for input after display then exit
print
DELETE pScreen
input temp$


  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic

LarryMc

This works with 90,000,000 elements (3,000 x 30,000)
added the delete pScreen before closing to clear memory
fixed loop indexing to use 1 to max
added 1 to x.y at NEW command to have enough space for 1 to the user input max
string  BlocksAccrossScreen$,BlocksDownScreen$,temp$
int Row,Colum,x,y
pointer pScreen

INPUT "How many blocks do you want accross the screen ", BlocksAccrossScreen$
INPUT "How many blocks do you want down the screen ", BlocksDownScreen$

x = val(BlocksAccrossScreen$)
y =val(BlocksDownScreen$)

pScreen = NEW(INT,(x+1)*(y+1))

for Row = 1 to y
      for Colum=1 to x
            #<INT>pScreen[Colum + (Row*x)] = 0
      next Colum
next Row

' Setup a dummy row,colum reference point
Row = rnd(1,y)+1
Colum = rnd(1,x)+1
print
print "Value Stored in Row:",Row," Colum:",Colum
print
#<INT>pScreen[Colum + (Row*x)] = 1

for Row = 1 to y
      for Colum=1 to x
            if #<INT>pScreen[Colum + (Row*x)]<>0
                print "Row:",Row," Colum:",Colum," Contents:",#<INT>pScreen[Colum + (Row*x)]
            endif
      next Colum
next Row

delete pScreen
' Wait for input after display then exit
print x*y
input temp$

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Blue Steel

Thanks Larry ;)

I too have Just got mine working ..

Code modified into subs now for reading and writing to the Array ;)

i've had my 2g mem up to 452,225,000*1 and 21,200*21,200

Code modified again .. still had a problem reading pScreen[0]

ALL Fixed now and Working properly (I hope)


'' My attempt a a roll your own 2d array type of thing from a users inpout for the size of the array
' SubRoutines ClearArray():StoreInArray(Colum,Row,Content):GetArrayContents(Colum,Row) returns Content as int
' compile as Windows .exe
' trace values 0=normal : 1=debug : 2=Display Table (only realy good on arrays less than 40 Colums)
openconsole

string  temp$
int Row,Colum,BlocksAccrossScreen,BlocksDownScreen,Content,trace
pointer pScreen

trace=1

INPUT "How many blocks do you want accross the screen ", BlocksAccrossScreen
INPUT "How many blocks do you want down the screen ", BlocksDownScreen

pScreen = NEW(int,BlocksAccrossScreen*BlocksDownScreen)

ClearArray()

Content= rand(1,16)
Row = rand(1,BlocksDownScreen)
Colum = rand(1,BlocksAccrossScreen)

StoreInArray(Colum,Row,Content)

' trace=1

for Row = 1 to BlocksDownScreen
for Colum = 1 to BlocksAccrossScreen
Content = GetArrayContents(Colum,Row)
if Content <> 0
if trace<2 then print "Colum: ", Colum, " Row: ", Row,  " Contents: ", Content
endif
if trace=2 then print Content,
next Colum
if trace=2 then print
next Row
print

input temp$
DELETE pScreen
Closeconsole
end

' >=- Subroutines -=<

sub StoreInArray(Colum as int, Row as int ,Content as int)
#pScreen[(Colum-1) + (Row-1)*BlocksAccrossScreen] = Content
if trace = 1 then print "Sub StoreInArray >=- pScreen: [",(Colum-1) + (Row-1)*BlocksAccrossScreen,"] Colum: ",Colum," Row: ",Row," Contents: ",Content," -=<"
endsub

sub GetArrayContents (Colum as int, Row as int),int
Content = #pScreen[(Colum-1) + (Row-1)*BlocksAccrossScreen]
if trace = 1 then print "Sub GetArrayContents >=- pScreen: [",(Colum-1) + (Row-1)*BlocksAccrossScreen,"] Colum: ",Colum," Row: ",Row," Contents: ",Content," -=<"
return Content
endsub

Sub ClearArray ()
for Row = 1 to BlocksDownScreen
for Colum = 1 to BlocksAccrossScreen
#pScreen[(Colum-1) + (Row-1)*BlocksAccrossScreen] = 0
if trace = 1 then print "Sub ClearArray >=- pScreen: [",(Colum-1) + (Row-1)*BlocksAccrossScreen,"] Colum: ",Colum," Row: ",Row," Contents: ",Content," -=<"
next Colum
next Row
endsub
  http://www.codingmonkeys.com
Covers many languages including Aurora , IWBasicEbasic (Ebasic, IBasic) , Creative Basic