How do I Store an Array Variable Inside of Another Array Variable?
This lesson describes how to create two dimensional arrays in the context of a simple board game. Data extraction and visualization examples are provided as part of the sample code.
Data storage is a critical consideration when writing and running software. There are many ways to store data, ranging from single item variables to large scale multi-node database applications. The fashion by which data is stored and retrieved depends on a number of factors that are beyond the scope of this lesson.
Refer to: Data Grid for information on a more complex data representation in LiveCode.
This lesson describes how to arrange data in two dimensional arrays.
Let us assume we want to create a memory representation for a simple game like tic tac toe. This game has a 3X3 grid of squares that can each store one of three possible states. These states are: "O" (nought), "X" (cross) and " " (empty).
The most intuitive representation of the 3X3 grid is possibly to use an equal mapping in memory. This is a 3X3 memory storage grid representing the 3X3 game grid. We can create such a memory representation by using an array of arrays.
There are two fundamental ways by which to create two dimensional arrays in LiveCode:
1. First create a number of arrays that each stores one dimensional data, then store these arrays in a new array to create the second dimension.
2. Create a two dimensional array directly and store the data in that.
The following example shows you how to create a two dimensional array that is constructed by inserting one dimensional array data into another array. You have to create an array for each line of the board representation. You also have to create an array that holds the arrays that store individual board representation lines.
# declare the arrays we are going to populate local tLineArray1, tLineArray2, tArrayInArray # populate the one dimensional arrays tLineArray1 and tLineArray2 put "O" into tLineArray1 put "X" into tLineArray1 put " " into tLineArray2 put "O" into tLineArray2 # store the one dimensional arrays in tArrayInArray to create the two dimensional array put tLineArray1 into tArrayInArray put tLineArray2 into tArrayInArray
Note: We use this scaled down 2X2 example of the normal 3X3 tic tac toe representation for illustration purposes only. The next step uses the full 3X3 representation.
This example shows you how to create a two dimensional array by storing the board data directly in the array. There is no need to create more than one array structure.
# declare the array we are going to populate local tMultiArray # populate the two dimensional array tMultiArray with the relevant data put "O" into tMultiArray put "X" into tMultiArray put " " into tMultiArray put " " into tMultiArray put "O" into tMultiArray put "X" into tMultiArray put "X" into tMultiArray put " " into tMultiArray put "O" into tMultiArray
Once data is stored in a two dimensional array, it is useful to have a means of reading the data again. As we are using a grid-like mapping between the board representation and the array storage representation, it would be nice to print the data in a grid-like fashion. We can do so by traversing the rows and columns of the array in two nested loops.
The following code implements a generic printing algorithm that can produce a printable string for a wide range of two dimensional arrays. This algorithm can be used with both of the arrays that we created earlier in this lesson.
function displayArray @pArray # create variables that point to the line and column of the array local tLineItem, tColumnItem # create a variable that stores the output for printing local tPrintLine put empty into tPrintLine # loop through each row of the array repeat for each element tLineItem in pArray # loop through each column of the array repeat for each element tColumnItem in tLineItem # write content of the array to tPrintLine put " " & tColumnItem after tPrintLine end repeat # insert a return after each row we have written to tPrintLine put return after tPrintLine end repeat return tPrintLine end displayArray
Note: It is common practice to use nested loops to process multi-dimensional array structures.
The following code prints the array tMultiArray to the LiveCode message box. As you can see, the columns are not properly aligned. This is because the font prints characters proportionally to their individual width. A space takes up less horizontal space than the O and X. This does not lend itself for easy reading.
-- this creates the output in the standard message box -- notice how the output is not properly aligned put displayArray (tMultiArray) into message
An alternative is to create a text field in LiveCode and use a font that prints every character at an identical width, such as the font Courier. As you can see in this example, the characters are now perfectly aligned.
The last thing we are missing are lines between the characters on the board. We can update our string generation function to provide this extra formatting.
-- create a text output field and set the font to Courier -- this will allow your output to be aligned properly along the horizontal axis put displayArray (tMultiArray) into field "OutField" Note: This code requires you to create a text field in LiveCode with the name OutField.
This function builds on the previous data retrieval function. The code is fundamentally the same, with the addition of some extra code that creates lines between each grid of the board. This function is also generic and can process a number of different two dimensional arrays.
function displayArrayFormatted @pArray # create variables that point to the line and column of the array local tLineItem, tColumnItem # create variables that store the horizontal separation line and the output for printing local tSeparatorLine, tPrintLine # create a variable that ensures we create the separation line only once local tFirstCall put empty into tPrintLine put "+" into tSeparatorLine put true into tFirstCall # loop through each row of the array repeat for each element tLineItem in pArray # loop through each column of the array repeat for each element tColumnItem in tLineItem # write content of the array to tPrintLine put "|" & tColumnItem after tPrintLine # create tSeparatorLine with a length relative # to the length of the first row in the array if tFirstCall then put "-+" after tSeparatorLine end repeat # we would have created tSeparatorLine by now, # so ensure we do not create it again if tFirstCall then put false into tFirstCall # append tSeparatorLine and a return to tPrintLine put "|" & return & tSeparatorLine & return after tPrintLine end repeat # add tSeparatorLine to the front of tPrintLine put tSeparatorLine & return before tPrintLine return tPrintLine end displayArrayFormatted
Now that the string generation function is updated, we can print a tic tac toe grid that is properly aligned and has dividing lines.
-- create a text output field and set the font to Courier -- this will allow your output to be aligned properly along the horizontal axis put displayArray (tMultiArray) into field "OutField"
Note: This code requires you to create a text field in LiveCode with the name OutField.