2D Array Framework

Post » Fri Aug 16, 2013 4:37 pm

This is a set of helper boilerplate code I developed when working on a new system for display cases. It allows for the management of a "fake" single 2-dimensional array of a given size. It does not assume (nor was it built around) being able to manage multiple such arrays per script.

This framework makes a few assumptions about its use (because it was built to solve my own problem), mainly that it was designed to manage a collection of very unique things, and not lots of similar things. Specifically, ObjectReferences.

Throughout the code, you will see iX and iY used as input parameters. These refer to the indicies in the first (X) and second (Y) dimensions of the logical array, respectively. iXWidth and iYHeight refer to the size of a range starting at some coordinate iX, iY in the array. iX and iY are always the lowest indicies of the range when used in this way. iXWidth and iYHeight refer to the total size of the range. For instance, a range spanning index 0 to 4 would have an iXWidth or iYHeight of 5, not 4.

There are a lot of different applications for something like this. Perhaps someone will write an in-game board game with it or something.

Preparation

In order to use this in your own scripts, you will need to do a bit of manual work. This is why it's "fake".

In your script, in the "empty" (global) scope, define the following:

int iXSize = 16			;2D Array size in the 1st dimension (max size: n)int iYSize = 16			;2D Array size in the 2nd dimension (max size: 128)
This defines your logical 2D array's dimensions. The 1st dimension (x) has no defined upper limit. The 2nd dimension has the traditional restriction of 128 elements.

After that, in the global scope, define the arrays to be used by the framework. Here (as noted by the iXSize and iYSize above), I am creating a 16x16 2D array. This requires that I create 16 arrays. In these examples (because it happens to be what I needed for the project I'm working on), the arrays are of type ObjectReference. They can be made any type you like, but would require some surgery in other parts of the framework to support it.

;2D Array Declarations;Quantity specified MUST match iXSizeObjectReference[] YNodes0ObjectReference[] YNodes1ObjectReference[] YNodes2ObjectReference[] YNodes3ObjectReference[] YNodes4ObjectReference[] YNodes5ObjectReference[] YNodes6ObjectReference[] YNodes7ObjectReference[] YNodes8ObjectReference[] YNodes9ObjectReference[] YNodes10ObjectReference[] YNodes11ObjectReference[] YNodes12ObjectReference[] YNodes13ObjectReference[] YNodes14ObjectReference[] YNodes15
Next we need to write a function that will encapsulate instantiating our arrays. I wish there were a more automatic way of doing this, but Papyrus demands that the array size be known at compile-time in the form of an integer literal instead of a variable.

function Create_2D()
Creates the 2D array.
Spoiler

function Create_2D()    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Creates the 2D array.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.        YNodes0 = new ObjectReference[16]        ;Specify integer literal here, must match iYSize    YNodes1 = new ObjectReference[16]    YNodes2 = new ObjectReference[16]    YNodes3 = new ObjectReference[16]    YNodes4 = new ObjectReference[16]    YNodes5 = new ObjectReference[16]    YNodes6 = new ObjectReference[16]    YNodes7 = new ObjectReference[16]    YNodes8 = new ObjectReference[16]    YNodes9 = new ObjectReference[16]    YNodes10 = new ObjectReference[16]    YNodes11 = new ObjectReference[16]    YNodes12 = new ObjectReference[16]    YNodes13 = new ObjectReference[16]    YNodes14 = new ObjectReference[16]    YNodes15 = new ObjectReference[16]endFunction


Now that that's out of the way, we have one last bit of boilerplate to do, which is to map our arrays to numerical IDs in the GetArrayFromID() function.

ObjectReference[] function GetArrayFromID(int iID)
Maps an ID to an array. These arrays MUST be listed manually by the user in the code below in order for the rest of the framework to function!
Spoiler

ObjectReference[] function GetArrayFromID(int iID)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Maps an ID to an array.    ;These arrays MUST be listed manually by the user in the code    ;below in order for the rest of the framework to function!        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    if iID == 0        return YNodes0    elseif iID == 1        return YNodes1    elseif iID == 2        return YNodes2    elseif iID == 3        return YNodes3    elseif iID == 4        return YNodes4    elseif iID == 5        return YNodes5    elseif iID == 6        return YNodes6    elseif iID == 7        return YNodes7    elseif iID == 8        return YNodes8    elseif iID == 9        return YNodes9    elseif iID == 10        return YNodes10    elseif iID == 11        return YNodes11    elseif iID == 12        return YNodes12    elseif iID == 13        return YNodes13    elseif iID == 14        return YNodes14    elseif iID == 15        return YNodes15    endifendFunction


As you can see, we just have to take the arrays we defined earlier and map them sequentially to a numerical ID starting at 0.

Somewhere in your code before you attempt to make use of your 2D array functions, you will need to call your instantiation function in order to actually instantiate the arrays you defined:

Create_2D()
That's it! Now that that's out of the way, you're able to use all of the rest of the functions in this framework. Have fun, and I hope someone finds them useful. :geek:

These haven't been exhaustively tested yet, but I'm (fairly sure) that everything works as intended. If you spot something I messed up, please point it out so I can update this post. I will probably also be making slight tweaks to this over time as this display case project matures.

int[] function Find_2D(ObjectReference akObject)
Finds the first occurrence of akObject in the 2D array. Returns an int[2] with the indicies of the object found.
Spoiler

int[] function Find_2D(ObjectReference akObject)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Finds the first occurrence of akObject in the 2D array.    ;Returns an int[2] with the indicies of the object found.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        int[0]        =        Index of akObject in 1st dimension.    ;                            -1 if not found.    ;        int[1]        =        Index of akObject in 2nd dimension.    ;                            -1 if not found.    int[] iReturn = new int[2]    int iX = 0    while iX < iXSize        int iY = GetArrayFromID(iX).Find(akObject)        if iY >= 0            iReturn[0] = iX            iReturn[1] = iY            return iReturn        endif        iX += 1    endWhile    iReturn[0] = -1    iReturn[1] = -1    return iReturnendFunction


ObjectReference function Read_2D(int iX, int iY)
Returns the value at the given indicies.
Spoiler

ObjectReference function Read_2D(int iX, int iY)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Returns the value at the given indicies.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        ObjectReference        =    The ObjectReference found.    ;                                Returns None if not found.    return GetArrayFromID(iX)[iY]endFunction


function Write_2D(int iX, int iY, ObjectReference akObject)
Writes akObject to the specified indicies.
Spoiler

function Write_2D(int iX, int iY, ObjectReference akObject)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Writes akObject to the specified indicies.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    GetArrayFromID(iX)[iY] = akObjectendFunction


bool function IsEmpty_2D(int iX, int iY)
Checks whether or not the field at the given indicies is None.
Spoiler

bool function IsEmpty_2D(int iX, int iY)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Checks whether or not the field at the given indicies is None.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        true        =        The field at the indicies is None.    ;        false        =        The field at the indicies is not None.    if GetArrayFromID(iX)[iY] == none        return true    else        return false    endifendFunction


function Clear_2D(int iX, int iY)
Clears (sets to None) the indicies specified in the 2D array.
Spoiler

function Clear_2D(int iX, int iY)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Clears (sets to None) the indicies specified in the 2D array.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    GetArrayFromID(iX)[iY] = NoneendFunction


int[] function FindRange_2D(ObjectReference akObject)
Exhaustively searches the 2D array for akObject, and attempts to return the parameters where this ObjectReference is found contiguously in the 2D array.

If the 2D array is populated with non-contiguous instances of akObject, this function will not return valid results, and will instead return the parameters of the lowest and highest indicies found that contain akObject.

Spoiler

int[] function FindRange_2D(ObjectReference akObject)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Exhaustively searches the 2D array for akObject, and attempts    ;to return the parameters where this ObjectReference is found    ;contiguously in the 2D array.    ;    ;If the 2D array is populated with non-contiguous instances of    ;akObject, this function will not return valid results, and    ;will instead return the parameters of the lowest and highest    ;indicies found that contain akObject.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        int[0]        =        Starting (lowest) index found in 1st dimension.    ;                            -1 if not found.    ;        int[1]        =        Starting (lowest) index found in 2nd dimension.    ;                            -1 if not found.    ;        int[2]        =        Width of range found in the 1st dimension.    ;                            -1 if either of the first two return values are -1.    ;        int[3]        =        Height of range found in the 2nd dimension.    ;                            -1 if either of the first two return values are -1.    int[] iReturn = new int[4]    int iXStart = -1    int iYStart = -1    int iXWidth = -1    int iYHeight = -1    int iXLargestIndex = -1    int iYLargestIndex = -1    int xD = 0    while xD < iXSize        int yD = 0        while yD < iYSize            if GetArrayFromID(xD)[yD] != None                ObjectReference r = GetArrayFromID(xD)[yD]                if r == akObject                    if iXStart == -1                        iXStart = xD                        iXLargestIndex = xD                    else                        iXLargestIndex = xD                    endif                    if iYStart == -1                        iYStart = yD                        iYLargestIndex = yD                    else                        iYLargestIndex = yD                    endif                endif            endif            yD += 1        endWhile        xD += 1    endWhile    if iXStart != -1 && iYStart != -1        iXWidth = (iXLargestIndex - iXStart) + 1        iYHeight = (iYLargestIndex - iYStart) + 1    endif    iReturn[0] = iXStart    iReturn[1] = iYStart    iReturn[2] = iXWidth    iReturn[3] = iYHeight    return iReturnendFunction


function WriteRange_2D(int iX, int iY, int iXWidth, int iYHeight,ObjectReference akObject)
Writes akObject to the indicies specified by the starting (lowest) indicies iX and iY, over the range iXWidth (1st dimension) and iYHeight (2nd dimension).
Spoiler

function WriteRange_2D(int iX, int iY, int iXWidth, int iYHeight, ObjectReference akObject)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Writes akObject to the indicies specified by the starting (lowest)    ;indicies iX and iY, over the range iXWidth (1st dimension) and    ;iYHeight (2nd dimension).        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    int xD = iX    while xD < (iXWidth - 1)        int yD = iY        while yD < (iYHeight - 1)            GetArrayFromID(xD)[yD] = akObject            yD += 1        endWhile        xD += 1    endWhileendFunction


bool function IsEmptyRange_2D(int iX, int iY, int iXWidth, int iYHeight)
Checks whether or not the indicies specified by the starting (lowest) indicies iX and iY, over the range iXWidth (1st dimension) and iYHeight (2nd dimension) contain all None values.
Spoiler

bool function IsEmptyRange_2D(int iX, int iY, int iXWidth, int iYHeight)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Checks whether or not the indicies specified by the starting (lowest)    ;indicies iX and iY, over the range iXWidth (1st dimension) and    ;iYHeight (2nd dimension) contain all None values.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        true        =        The entire range of indicies is None.    ;        false        =        One or more indicies in the range is not None.    int xD = iX    while xD < (iXWidth - 1)        int yD = iY        while yD < (iYHeight - 1)            if GetArrayFromID(xD)[yD] != None                return false            endif            yD += 1        endWhile        xD += 1    endWhile    return trueendFunction


function ClearRange_2D(int iX, int iY, int iXWidth, int iYHeight)
Clears (sets to None) the indicies specified by the starting (lowest) indicies iX and iY, over the range iXWidth (1st dimension) and iYHeight (2nd dimension).
Spoiler

function ClearRange_2D(int iX, int iY, int iXWidth, int iYHeight)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Clears (sets to None) the indicies specified by the starting (lowest)    ;indicies iX and iY, over the range iXWidth (1st dimension) and    ;iYHeight (2nd dimension).        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    int xD = iX    while xD < (iXWidth - 1)        int yD = iY        while yD < (iYHeight - 1)            GetArrayFromID(xD)[yD] = None            yD += 1        endWhile        xD += 1    endWhileendFunction


function ClearAll_2D()
Clears (sets to None) the entire 2D array.
Spoiler

function ClearAll_2D()    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Clears (sets to None) the entire 2D array.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    int xD = 0    while xD < iXSize        int yD = 0        while yD < iYSize            GetArrayFromID(xD)[yD] = None            yD += 1        endWhile        xD += 1    endWhileendFunction


function ClearAllReferenceOfType_2D(ObjectReference akObject)
Clears (sets to None) the indicies found in the 2D array that contain akObject.
Spoiler

function ClearAllReferenceOfType_2D(ObjectReference akObject)    ;-----------\    ;Description \    ;----------------------------------------------------------------    ;Clears (sets to None) the indicies found in the 2D array    ;that contain akObject.        ;-------------\    ;Return Values \    ;----------------------------------------------------------------    ;        None.    int xD = 0    while xD < iXSize        int yD = 0        while yD < iYSize            if GetArrayFromID(xD)[yD] == akObject                GetArrayFromID(xD)[yD] = None            endif            yD += 1        endWhile        xD += 1    endWhileendFunction
User avatar
Susan
 
Posts: 3536
Joined: Sun Jun 25, 2006 2:46 am

Return to V - Skyrim