I know it's possible but how to do it? I know how to make a List, but how to change a list to a matrix? For example I would like to have a matrix Map Width by Map Height. The concept somehow eludes me. If someone could write a function to handle something like that I would be very thankful.
Basically you just have a bigger list and do the math yourself. That's all an array is behind the scenes.
If you want an array that's 10x10, you make a list of 100, and access element (x+y*10).
Edit: In case it's not clear which 10 to multiply Y by --
Array [Width, Height] would be List [Width*Height] and access element [x,y] in the array would be [x+y*Width] in the list.
I've been using this function:
CreateListStartingSize(MapWidth mul(MapHeight)) ->2DArray
Set/GetListElement(<-2DArray @Coord2Index(<-x <-y))
:Coord2Index
# takes cell coordinates x and y and transforms them into the corresponding array index
# allows usage of lists (=1D arrays) as if they were two dimensional
# x1 y1 - i1
swap MapHeight mul add
thanks :D I knew it must have been something easy that I just couldn't get :D
Other than almost all the topics in Builder's Corner, there so far have been no topics of which to me the concept has made no sense - this is the first.
Here is a 2x2 array.
0 1 2
3 4 5
6 7 8
Note the index of each position. That is the same as this single dimensional list:
0 1 2 3 4 5 6 7 8
You can represent any n dimensional array with a single dimensional list, so long as you define the extents of each dimension beyond the first dimension ( you must define the the width for instance in a 2 dimensional array).
Here's how I think of it, C0. You basically have a 2D array, right? However, instead of using colums like this:
1,1 | 2,1 | 3,1
1,2 | 2,2 | 3,2
1,3 | 2,3 | 3,3
We only designate one index for each coord (that way it fits in a single list), and it loops around, like this:
0 | 1 | 2
3 | 4 | 5
6 | 7 | 8
Therefore, we can access each 'coordinate' from x,y coordinates by adding 3 for each y increment - for instance, if you wanted to get index 5, which corresponds to 2,1, you take the x coord and then add the y coord multiplied by the width of the array (3), like so:
x + (y*width)
2 + (1*3)
Note that the array MUST be zero based for this method to work. (if not zero-based, you must add the base amount (so if you started indexing at 1, you would add 1) to the output of the above formula - so it would become base+x+(y*width). You cannot do this - at least, not easily - with a non-zero based coordinate system without first converting to zeroed. I hope that explains it!
EDIT: and I spent all that time making this just to have V respond before me.... :P
Right - thanks. I'd just use two lists, but I'm not sure if that would achieve the same effect.
EDIT: That is thanks to both of you, of course.
It would achieve the same effect, but with more complication than necessary, although it would be easier to understand.
Quote from: Clean0nion on January 29, 2014, 11:30:08 AM
Right - thanks. I'd just use two lists, but I'm not sure if that would achieve the same effect.
EDIT: That is thanks to both of you, of course.
How would you use two lists to represent a 64 x 64 array?
Quote from: Michionlion on January 29, 2014, 11:33:43 AM
It would achieve the same effect, but with more complication than necessary, although it would be easier to understand.
Which reminds me - and I'll stop posting after this post - one of my projects has about 16 lists in it, 12 of which are used simultaneously, and all are per script per unit. Though in some units only one of the lists is used.
@Grauniad
64 0 do
64 0 do
<-x J AppendToList
<-y I AppendToList
loop
loop
something like that
Quote from: Grauniad on January 29, 2014, 11:36:29 AM
Quote from: Clean0nion on January 29, 2014, 11:30:08 AM
Right - thanks. I'd just use two lists, but I'm not sure if that would achieve the same effect.
EDIT: That is thanks to both of you, of course.
How would you use two lists to represent a 64 x 64 array?
hmm... you're right! You'd have to do a list inside a list, and I don't know if that is possible.
Quote from: Michionlion on January 29, 2014, 11:41:20 AM
Quote from: Grauniad on January 29, 2014, 11:36:29 AM
Quote from: Clean0nion on January 29, 2014, 11:30:08 AM
Right - thanks. I'd just use two lists, but I'm not sure if that would achieve the same effect.
EDIT: That is thanks to both of you, of course.
How would you use two lists to represent a 64 x 64 array?
hmm... you're right! You'd have to do a list inside a list, and I don't know if that is possible.
Yes I lied that I wouldn't post anymore, but you should understand that I have no idea what I'm taking about.
Actually, you could do a list inside a list now that I think about it...
using <-! and ->!
Quote from: Michionlion on January 29, 2014, 11:41:20 AM
hmm... you're right! You'd have to do a list inside a list, and I don't know if that is possible.
You can do lists inside lists, but to store a 64x64 matrix you'd need 9 size-8 lists in total.
Quote from: Clean0nion on January 29, 2014, 11:43:39 AM
I have no idea what I'm taking about.
word.
Quote from: eduran on January 29, 2014, 11:44:28 AM
Quote from: Michionlion on January 29, 2014, 11:41:20 AM
hmm... you're right! You'd have to do a list inside a list, and I don't know if that is possible.
You can do lists inside lists, but to store a 64x64 matrix you'd need 9 size-8 lists in total.
I'dthink, in my simplicity, that you'd have to have more than that...
Yeah, lists in lists work... any of the data types can be held by a list, which includes other lists.
You can create a jagged array using just that technique. In a jagged array the rows don't have to all be the same length.
So the jagged array might look like this (6 rows tall with variable row width):
x x x x x
x x x
x x x x
x x x x x x x
x
x x x x
All of this falls under the 'data structure' category and it's something you learn in the first couple years of a computer science (or related) degree. That said, the practical application of data structures isn't rocket science so anybody can learn the basic structures and terminology whenever they choose. Start here:
http://en.wikipedia.org/wiki/Data_structure
Just knowing the possible structures and some example use cases can take your coding skills up several notches.
Would this work?
$arrayWidth:0
$arrayHeight:0
once
<-arrayHeight 0 do
CreateList "h" I concat ->!
I ->i
loop
<-i ->hlength
<-hlength 0 do
<-arrayWidth 0 do
"h" J concat <-! I AppendToList
loop
loop
endonce
Sorry, I think something's wrong with that. The "i" variable seems to be set in the first loop seems to come out equal to "arrayHeight", and then you transfer the SAME value to "hlength", and when you call it again, you could just use arrayHeight again instead.
$arrayWidth:0
$arrayHeight:0
once
<-arrayHeight 0 do
CreateList "h" I concat ->!
loop
<-arrayHeight 0 do
<-arrayWidth 0 do
"h" J concat <-! I AppendToList
loop
loop
endonce
That said, the code seems useless as is, it creates, Y lists with X variables equal to their position in the list. Without some way to utilize those lists... but of course, that would be what goes OUTSIDE the onceblock.
It should be <-arrayHeight 1 sub. So that's pretty much what it is.
No, wait - you're right. Yes.
And I did begin making the utilisation tool, then I remembered I had no idea what I was doing, or even what you want to extract from this list.
So I expanded on my previous code and made this:
$img:"Custom0_256"
$size:4
$dist:10
$arrayWidth:100
$arrayHeight:100
CreateList ->hh
<-arrayHeight 0 do
CreateList "h" I concat ->!
<-hh "h" I concat AppendToList
loop
<-hh GetListCount 0 do
<-arrayWidth 0 do
"h" J concat <-! I AppendToList
loop
loop
0 ->hadd
<-arrayHeight 0 do
<-arrayWidth 0 do
Self <-hh J GetListElement I GetListElement <-img SetImage
Self <-hh J GetListElement I GetListElement <-size <-size SetImageScale
Self <-hh J GetListElement I GetListElement I 8 mul <-dist mul J 8 mul <-dist mul 3 SetImagePosition
loop
loop
What it's supposed to do is add an array of images to a core so that the collection of images covers a large square, with the image directly over the core being at the bottom-left. It's all in the initial once loop of the script.
What does it do? Nothing. Doesn't even set a single image. I have no idea what I'm doing wrong (other than possibly all of it) - can anyone help?
I have no idea what you are trying to do with all these lists. If there is a purpose to them that isn't visible I'd need to know what that is before I can help you figure out what's wrong with them.
Without the lists, this should do to set the images:
<-arrayHeight 0 do
<-arrayWidth 0 do
"x" i "y" j concat concat concat ->imgSlot
Self <-imgSlot <-img SetImage
Self <-imgSlot <-size <-size SetImageScale
Self <-imgSlot I 8 mul <-dist mul J 8 mul <-dist mul 3 SetImagePosition
loop
loop
Ah, yes.
What I'm trying to do is convert a number in the array to a set of coords, which is the opposite of what you were doing.
So 3 might convert to 0,3 or 3,0 depending on how I ordered the J and I.
Storing lists in lists is interesting, and the <-! and ->! commands are too. They allow for complicated logic. Most of the time though, they are unnecessary. Just because you can use something, doesn't mean you should. Take a step back and look at what you're actually trying to do.
If I'm interpreting your intent correctly, you don't need to convert a number in an array to a set of coords, all you need to do is find a way to store a grid of images in a single CRPL core and display them on screen in a grid. Yes?
If that's the case, take a look at eduran's sample, or some derivative of handling it that way. The simpler path to achieving your goal will be easier to understand and maintain.
I would not try to maintain a list of lists unless they were dynamic and/or varying in their sizes.
On a side note, in your provided code, you are using J inside a single loop, not a nested loop.
<-arrayHeight 0 do
CreateList "h" I concat ->!
<-hh "h" I concat AppendToList
loop
<-hh GetListCount 0 do
<-arrayWidth 0 do
"h" J concat <-! I AppendToList ##### J has no practical value here, this loop is not inside another loop *****
loop
loop
Done.
0 ->i
0 ->xd
0 ->yd
while <-side 2 pow <-i gt
repeat
Self "img" <-i concat <-img SetImage
Self "img" <-i concat <-size dup SetImageScale
Self "img" <-i concat <-xd 8 mul <-dist mul SetImagePositionX
Self "img" <-i concat <-yd 8 mul <-dist mul SetImagePositionY
<-xd 1 add ->xd
<-xd <-side mod 0 eq if
<-yd 1 add ->yd
0 ->xd
endif
<-i 1 add ->i
endwhile
This probably isn't greatly transferable to any other project, but it does exactly what I want.
I made a matrix script. :)