Что такое элегантный способ хранения 2D-поля блоков, имеющих атрибуты? (Без занятий) - PullRequest
0 голосов
/ 11 января 2019

У меня есть такой двумерный массив, который хранит поле маленькой игры:

'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"}}

Теперь я хочу присвоить этим плиткам атрибуты (более одного). Так что я могу использовать

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

например.

Так что вместо того, чтобы заполнять это строками, я хотел бы заполнить это структурами? Но это будет похоже на кошмар.

Каков наилучший способ сделать это?

(Я сейчас пытаюсь уклоняться от занятий, потому что я изучаю vb.net, а мы пока мало занимались с классами.)

Ответы [ 3 ]

0 голосов
/ 12 января 2019

Похоже, вы пытаетесь настроить игровое поле . Таким образом, в ООП легче воспринимать это как объект. Вот тот, над которым я очень медленно работаю.

Важно отметить, что мой массив увеличен по сравнению с размером игрового поля. Это делает проверку допустимых перемещений не обязательной для проверки на выход за край массива, только для блокирующих элементов.

Как видите, я также ссылаюсь на Piece, который является классом / объектом, похожим на то, что вы хотите делать с элементами поля. Это все еще в стадии разработки, и я пытаюсь сделать несколько разных способов, отсюда закомментированный код.

pBoard в приведенном ниже коде соответствует вашему field.

Public Class Board
    Private pBoard(,) As Piece
    'Private pPieces As List(Of Piece)
    Private Const pEMPTYSPACE As PieceID = 0
    Private Const pBLOCK As PieceID = -1
    'Private pBlockPiece As New Piece(pBLOCK, PieceAlignment.Block, PieceListIndex.None)
    'Private pEmptyPiece As New Piece(pEMPTYSPACE, PieceAlignment.Null, PieceListIndex.None)


    Property UIElement As Control

    Public Structure PieceQuartet
        Dim QuartetSet As Boolean
        Dim North As Piece
        Dim South As Piece
        Dim West As Piece
        Dim East As Piece
        'Public ReadOnly Property HasValue As Boolean
        '    Get
        '        Return Not (North Is Nothing Or South Is Nothing Or West Is Nothing Or East Is Nothing)
        '    End Get
        'End Property
    End Structure

    Public Structure PieceLegalMovesQuartet
        Dim QuartetSet As Boolean
        Dim North As Boolean
        Dim South As Boolean
        Dim West As Boolean
        Dim East As Boolean
    End Structure

    Public Sub New(rows As Integer, columns As Integer) ', blockPiece As Piece)
        ReDim pBoard(rows + 2, columns + 2) ' 0-based, setting a strong boundary around the real board (1..8 or 1..10 matrix).
        ' set empty field
        For iterator1 = 0 To rows + 1
            For iterator2 = 0 To columns + 1
                pBoard(iterator1, iterator2) = EmptyPiece 'Nothing
            Next
        Next
        ' set boundaries
        For iterator1 = 0 To columns + 1
            pBoard(0, iterator1) = BlockPiece 'blockPiece
            pBoard(rows + 1, iterator1) = BlockPiece 'blockPiece
        Next
        For iterator1 = 0 To rows + 1
            pBoard(iterator1, 0) = BlockPiece 'blockPiece
            pBoard(iterator1, columns + 1) = BlockPiece 'blockPiece
        Next
    End Sub

    Public Function AddPiece(row As Integer, column As Integer, piece As Piece) As Boolean
        Dim tVacant As Boolean
        tVacant = pBoard(row, column) Is Nothing OrElse pBoard(row, column).Alignment = PieceAlignment.Null
        If tVacant Then pBoard(row, column) = piece
        Return tVacant
    End Function

    Public Sub RemovePiece(row As Integer, column As Integer)
        pBoard(row, column) = EmptyPiece 'Nothing
    End Sub

    Public Function GetPiece(row As Integer, column As Integer) As Piece
        Return pBoard(row, column)
    End Function

    Public Function Neighbours(row As Integer, column As Integer) As PieceQuartet
        Dim tQuartet As New PieceQuartet
        If row <= 0 Or column <= 0 Or row >= pBoard.GetUpperBound(1) Or column >= pBoard.GetUpperBound(2) Then
            tQuartet = Nothing ' not allowed to be on or outside the boundary of the board.
        Else
            tQuartet.QuartetSet = True
            tQuartet.North = pBoard(row - 1, column)
            tQuartet.South = pBoard(row + 1, column)
            tQuartet.West = pBoard(row, column - 1)
            tQuartet.East = pBoard(row, column + 1)
        End If
        Return tQuartet
    End Function

    Function Neighbours(tuple As Tuple(Of Integer, Integer)) As PieceQuartet
        Return Neighbours(tuple.Item1, tuple.Item2)
    End Function

End Class
0 голосов
/ 16 января 2019

Я решил это сейчас со структурой и с помощью парсера для преобразования массива:

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

Я также заметил, что массив хранит x и y не так, как я думал. Поэтому я поменял их местами при разборе.

0 голосов
/ 12 января 2019

Просто измените тип данных вашего массива. Быстрый поиск / замена сделали все остальное.

Private field(,) As ConsoleColor
    Private Sub FillArray()
        'F = Forrest -> ConsoleColor.DarkGreen
        'G = Grass   -> ConsoleColor.Green
        'S = Sand    -> ConsoleColor.DarkYellow
        'W = Water   -> ConsoleColor.Cyan
        field = {{ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.DarkGreen},
                {ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.DarkGreen},
                {ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.Green, ConsoleColor.Cyan, ConsoleColor.DarkYellow, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Green},
                {ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Cyan, ConsoleColor.DarkYellow, ConsoleColor.DarkYellow, ConsoleColor.DarkYellow, ConsoleColor.DarkGreen, ConsoleColor.Cyan},
                {ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Cyan, ConsoleColor.DarkYellow, ConsoleColor.DarkYellow, ConsoleColor.Green, ConsoleColor.DarkGreen, ConsoleColor.Cyan},
                {ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.DarkYellow, ConsoleColor.Green, ConsoleColor.DarkGreen, ConsoleColor.Cyan},
                {ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.DarkGreen, ConsoleColor.Cyan},
                {ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.DarkGreen, ConsoleColor.Green, ConsoleColor.Green, ConsoleColor.DarkGreen, ConsoleColor.Cyan}}
End Sub

Затем использовать ваш массив

Sub Main()
        FillArray()
        Console.ForegroundColor = field(1, 1)
End Sub

Нет. Необходим цвет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...