Some notes on matrix manipulation

The place to discuss scripting and game modifications for X²: The Threat.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

User avatar
Burianek
Posts: 2981
Joined: Mon, 29. Dec 03, 03:29
x3tc

Some notes on matrix manipulation

Post by Burianek »

This is meant for those already familiar with scripting using the script editor.

I figured out this 'feature' of the S.E. last night after swearing at my computer for three hours. I'd like to save all of you who are thinking of venturing into the wonderful world of matrices the heartache.

You've probably already figured out that you can append one array to another to create a matrix:

Code: Select all

001   $matrix = array alloc: size = 0
002   $row1 = array alloc: size = 2
003   $row2 = array alloc: size = 2
004   row1[0] = 1
005   row1[1] = 2
006   row2[0] = 3
007   row2[1] = 4
008   append $row1 to $matrix
009   append $row2 to $matrix
will give you a matrix of form:

Code: Select all

$matrix=
1 2
3 4
What you may not have realized is that this matrix does not contain the values of four numbers, but rather pointers to two arrays.

This can become an issue.
If you are using a loop to 'build' an array:

Code: Select all

001   $return =  array alloc: size=0
002   $temprow =  array alloc: size=2
003   
004   $i = 0
005   while $i < 2
006    if $i == 0
007     $temprow[0] = 1
008     $temprow[1] = 2
009    else
010     $temprow[0] = 3
011     $temprow[1] = 4
012    end
013    inc $i = 
014    append $temprow to array $return
015   end
I mistakenly believed that this code would also return:

Code: Select all

$return=
1 2
3 4
If you're smarter than I am, you may have already realized that it does not. This code will return:

Code: Select all

$return=
3 4
3 4
If you're as unintelligent as I am (bless you for admitting it) this is the explanation:
You append $temprow to $return. It stores a pointer to the array $temprow, it does not store 1 2. When you later edit $temprow the next time through the loop, it changes the first row in matrix $return.
Then, it of course appends the changed row as the second entry in the matix.

To get around this you must reallocate / reinitialize the temporary array every time after you use it. The following code will work correctly:

Code: Select all

001   $return =  array alloc: size=0
002   $temprow =  array alloc: size=2
003   
004   $i = 0
005   while $i < 2
006    if $i == 0
007     $temprow[0] = 1
008     $temprow[1] = 2
009    else
010     $temprow[0] = 3
011     $temprow[1] = 4
012    end
013    inc $i = 
014    append $temprow to array $return
015    $temprow =  array alloc: size=2
016   end
Cheers.
I'll post more as I figure more out.
"Nature's first green is gold" . . . stay golden.
adam00
Posts: 333
Joined: Sun, 9. May 04, 12:03
x4

Post by adam00 »

Calling such construction "Matrix" is source of trouble, you should call it "array of arrays" so you will always think about it this way. Matrix for me is two dimensions array, you can't have it in X2 in strite way but can simulate it on one dimension array.

PS. Well, I even create script for sorting "rows" of array, you can specify "fields" for "sorting key" (with ascending/descending order). The sorting algoritm is quick-sort. :)
Carl Sumner
Posts: 5145
Joined: Mon, 23. Feb 04, 01:28
x4

Post by Carl Sumner »

I don't know about X2 scripts, but in other IDE's the re-allocation would "dispose" of the previous copy of the $temprow. That could leave the pointer in the matrix invalid. Or does this script processor recognize that the pointer is still in use?
:?

If the pointer is now invalid it could still work, until the memory is recovered by a "garbage collector" operation. Then, smash! :wink:
Tinker

"If engineers built buildings the way programmers write programs, the first woodpecker that came along would destroy civilization!"

Return to “X²: The Threat - Scripts and Modding”