Search code examples
arraysvb.netarraylistenumsstructure

What is an elegant way to store a 2D field of blocks, that have attributes? (Without classes)


I have a two dimensional array like this that stores the field of a small game:

'F = Forrest -> ConsoleColor.DarkGreen, notPassable
'G = Grass   -> ConsoleColor.Green, passable
'S = Sand    -> ConsoleColor.DarkYellow, passable
'W = Water   -> ConsoleColor.Cyan, notPassable
Dim level1(,) As String = {{"F", "F", "F", "F", "G", "G", "G", "F"},
                           {"F", "F", "F", "G", "G", "G", "G", "F"},
                           {"F", "F", "G", "W", "S", "G", "G", "G"},
                           {"G", "G", "W", "S", "S", "S", "F", "W"},
                           {"G", "G", "W", "S", "S", "G", "F", "W"},
                           {"F", "F", "G", "G", "S", "G", "F", "W"},
                           {"F", "F", "G", "G", "G", "G", "F", "W"},
                           {"F", "F", "F", "F", "G", "G", "F", "W"}}

Now I want to give those tiles attributes(more than one). So that I can use

level(1,1).color
level(1,1).isPassable
'etc

for example.

So instead of filling this with strings, I would like to fill it with structures? But it would look like a nightmare.

What would be a the best way to do this?

(I try to dodge classes for now, because I'm learning vb.net and we did not do much with classes yet.)


Solution

  • I solved it now with a structure and by using a parser to convert the array:

    Private Structure Board
        Public color As Byte
        Public isPassable As Boolean
        'etc
    End Structure
    
    Sub Main()
        'F = Forrest -> ConsoleColor.DarkGreen, notPassable
        'G = Grass   -> ConsoleColor.Green, passable
        'S = Sand    -> ConsoleColor.DarkYellow, passable
        'W = Water   -> ConsoleColor.Cyan, notPassable
        Dim level1(,) As String = {{"F", "F", "F", "F", "G", "G"},
                                   {"F", "F", "F", "G", "G", "G"},
                                   {"F", "F", "G", "W", "S", "G"},
                                   {"G", "G", "W", "S", "S", "S"},
                                   {"G", "G", "W", "S", "S", "G"},
                                   {"F", "F", "G", "G", "S", "G"},
                                   {"F", "F", "G", "G", "G", "G"},
                                   {"F", "F", "F", "F", "G", "G"}}
    
        Dim level(,) As Board
        level = ParseLevel(level1)
    
        'Data can now be accessed like this:
        'level(x, y).color // level(x, y).isPassable
    
        'Test
        For y As Integer = 0 To level.GetUpperBound(1)
            For x As Integer = 0 To level.GetUpperBound(0)
                Console.SetCursorPosition(x * 3, y)
                If level(x, y).isPassable Then
                    Console.ForegroundColor = ConsoleColor.Green
                Else
                    Console.ForegroundColor = ConsoleColor.Red
                End If
                Console.Write($"{level(x, y).color:00} ")
            Next
        Next
    
        'Keep console open until input
        Console.ReadKey()
    End Sub
    
    Private Function ParseLevel(input As String(,)) As Board(,)
        Dim output(input.GetUpperBound(1), input.GetUpperBound(0)) As Board 'swapping dimensions here
    
        For x As Integer = 0 To input.GetUpperBound(1)
            For y As Integer = 0 To input.GetUpperBound(0)
                Select Case input(y, x) 'swapping x and y here
                    Case "F" 'Forrest
                        output(x, y).color = ConsoleColor.DarkGreen
                        output(x, y).isPassable = False
                        'etc
                    Case "G" 'Grass
                        output(x, y).color = ConsoleColor.Green
                        output(x, y).isPassable = True
                        'etc
                    Case "S" 'Sand
                        output(x, y).color = ConsoleColor.Yellow
                        output(x, y).isPassable = True
                        'etc
                    Case "W" 'Water
                        output(x, y).color = ConsoleColor.Cyan
                        output(x, y).isPassable = False
                        'etc
                End Select
            Next
        Next
    
        Return output
    End Function
    

    I also noticed that an array stores x and y not the way I thought. So I swapped them while parsing.