How to create a simple and functional 2d-array -- for non-coders (Feedback?)

Red Frostraven

  • Posts: 23
How to make a functional array without any problems:

(Screenshot at bottom; I'm going over the logic in the top section, and want feedback for better methods if there are any in any of the steps)

Create a scene behavior.
Create three custom blocks:

Create Array (Global block): (Return type: None (action block))
Create Array from [ List ] Width: [ Width ] Height: [ Height ] Default value [ Anything ]

Empty [ List ]
Set item 0 in [ list ] to [ Width ]
Set item 1 in [ list ] to [ Height ]

Repeat [ [ Width ] x [ Height ] ] times
Set item [ [ 2 ] + [ current loop count ] ] to [ Anything ]

___
===
___

Set Array Value (Global block): (Return type: None (Action block))
Set Array [ List ] item X: [ Width ] Y: [ Height ] to [ Anything ]

IF [ [ Width ] < [ Get item # 0 from [ List ] ] AND [ Height ] < [ Get item # 1 from [ List ] ]
(safecheck mechanism) 

Replace item # [  2 + [ [ Height ] * [ Get item #0 from [ List ] ] + Width ] ] with [ Anything ]
** (Holy cow batman!) **

Otherwise [ Print: Can't set values outside array boundaries! ]

___
===
___

Get Array Value (Global block): (Return type: Anything)
Get Array [ List (List) ] item X: [ Width (number) ] Y: [ Height (Number) ]

IF [ [ Width ] < [ Get item # 0 from [ List ] ] AND [ Height ] < [ Get item # 1 from [ List ] ]
(safecheck mechanism) 

[ Return [ Get item # [ 2 + [ [ [ Height ] * [ Get item #0 from [ List ] ] + Width ] ]
** (Holy cow batman!) **

Otherwise
Return [ -1 ]
Print [ Can't get values outside array boundaries! ]

=================

Functional explanation:

When we set our array, we multiplied it to the size we needed.
A 12x12 array contains 144 items plus the two first entries.

Now.
Why does this work? What prevents entries from overwriting eachother when setting values?
The failsafe IF [ [ Width ] < [ Get item # 0 from [ List ] ] AND [ Height ] < [ Get item # 1 from [ List ] ]  prevents you from writing to 15,0 in the array by checking that 15 in fact is larger than the maximum allowed width for each row -- stored in the list's item #0.

Writing to X 15 Y 0 in a 14x14 array would overwrite the normal value in X 1 Y 1 -- so the X/Width comparison failsafe is important to avoid errors.

Less importantly, we don't want you to write outside Y boundaries of the array either, in case you set the boundaries for a reason, so we just stop those too -- even though you don't need to stop if you need to expand the array.
However, you can never expand the width of the array without creating a new array.

The array also starts at X 0 and Y 0 like a normal array, which means that if you create the array as 14x14 -- the location X 13, Y 13 is the final value in the array and trying to get 14,13 or 13,14 results in the error messages set up.

Trying to access X -1 and X-2 with Y 0 returns the array boundaries -- and is a nifty thing to keep in mind if you have many arrays in different sizes and need to automatically write to one.

Now. How it the array actually works, shown with a 3x3 array:

X,Y
0,0 | 1,0 | 2,0
0,1 | 1,1 | 2,1
0,2 | 1,2 | 2,2

However, this is not an actual array. It's a list where math creates the array functionality:
And the list like it actually looks:
0: (Reserved) 3
1: (Reserved) 3
2: 0,0
3: 1,0
4: 2,0
5: 0,1
6: 1,1
7: 2,1
8: 0,2
9: 1,2
10:2,2

HOW this works:

Looking at the code that actually changes the values inside the array:
Replace item # [  2 + [ [ Height ] * [ Get item #0 from [ List ] ] + Width ] ] with [ Anything ]

IF you Get Array item X (Width) = 2 and Y (Height) = 0:
2 + ( X: 2 +  ( Y: 0 * (Reserved) 3 ) ) = List item number 4

0: (Reserved) 3
1: (Reserved) 3
2: 0,0
3: 1,0
4: 2,0
5: 0,1
6: 1,1
7: 2,1
8: 0,2
9: 1,2
10:2,2

For X0 Y1:
2 + ( X: 0 + ( Y: 1 * (Reserved) 3 ) ) = List item number 5

0: (Reserved) 3
1: (Reserved) 3
2: 0,0
3: 1,0
4: 2,0
5: 0,1
6: 1,1
7: 2,1
8: 0,2
9: 1,2
10:2,2

...

WHY this works:

It works because of the multiplication of X with Y.

For instance: We can set up an array with the max size X = 10 and Y = 2:
The Array is 10 items wide and 2 items long, and "looks" like this:
[-2,0: 10][-1,0: 2] <--- The index necessary to 'remember' the array size
_____________
[0,0][1,0][2,0][3,0][4,0][5,0][6,0][7,0][8,0][9,0] <-- Values for Y = 0 and X 0 to 9
[0,1][1,1][2,1][3,1][4,1][5,1][6,1][7,1][8,1][9,1] <-- Values for Y = 1 and X 0 to 9
...

As a list:
0: [-2,0: 10]
1: [-2,0: 3]
2: [0,0] <-- First item in the array
3: [1,0]
4: [2,0]
5: [3,0]
6: [4,0]
7: [5,0]
8: [6,0]
9: [7,0]
10:[8,0]
11:[9,0] <--- Last item for Y = 0
12:[0,1] <--- First item for Y = 1
13:[1,1]
14:[2,1]
15:[3,1]
16:[4,1]
17:[5,1]
18:[6,1]
19:[7,1]
20:[8,1]
21:[9,1] <-- Last item in the array: 9,1

Functionality:
I made this array because I needed the ability to reference positions on my entire map, and I had problems with "lists within lists" -- especially when trying to register mega-sized arrays of over 100x100 (10 000 items)

This array handles 10 000 items (100x100, 500x20, 250x40) with ease.

(EDIT: I had to post prematurely because my laptop ran out of power :D )

« Last Edit: April 11, 2013, 12:19:34 pm by Red Frostraven »

hollywoodcolor

  • Posts: 4
Red,
 this is Awesome!!!

I'm just completely lost when it comes to custom blocks. I'm tiring to do a slide puzzle like game and having a really hard time getting the mechanics working. So having a simple 2d array would be a huge help.

David