"Warben-Felder" in 2D Array umrechnen

  • Hallo Community!
    Ich habe mal wieder ein Problem bei dem ich nicht weiterkomme. :)

    Folgendes:
    Ich habe ein etwas ungewöhnlicheres Spielfeld. Dieses Spielfeld besteht aus einzelnen Sechsecken die wie Waben aneinander geordnet sind. Hier einmal so ein Spielfeld als ASCII-Art:


    Dazu habe ich ein 2 Dimensionales Array deklariert welches 7x7 Elemente besitzt. In diesem Array sind die Spielfeld Eigenschaften dokumentiert. Um es für mein Problem einfach zu halten gibt es nur 3 möglichen Zustände.
    „-1“ steht dabei für ein Feld welches nicht begehbar ist. (Im ASCII-Art einfach Weggelassen)
    „0“ steht für ein Feld welches begehbar ist.
    „1“ steht für ein Feld auf welches eine Figur steht.

    Dazu folgende Deklaration:

    [autoit]

    Global $aField[7][7] = [[-1, -1, -1, -1, -1, -1, -1], _
    [-1, 0, 0, 0, 0, 0, -1], _
    [-1, 0, 0, 0, 0, 0, -1], _
    [-1, 0, 0, 1, 0, 0, -1], _
    [-1, 0, 0, 0, 0, 0, -1], _
    [-1, 0, 0, 0, 0, 0, -1], _
    [-1, -1, -1, -1, -1, -1, -1]]

    [/autoit]

    Mein Problem:
    Wegen der ungewöhnlichen Spielfeldform (mit 6 benachbarten Felder) ist es etwas schwierig das 2D Array so zu verändern dass es der Beschaffenheit meines Spielfeldes entspricht. Heißt im Klartext, wenn ich meine Figur (die auf Feld N steht) nach rechts oben (auf das Feld R) ziehe, welche Werte muss ich dann im Array ändern? Von der Logik her wäre der Index [3][3] das Feld N und der Index [2][4] das Feld R. Leider lässt sich das so nicht auf alle Felder übertragen. Wenn ich von dem Feld G nach M ziehe, dann wechsle ich im Array von [2][2] auf [2][3]. Ich hoffe es ist so verständlich wie ich das meine, das Bewegen meiner Figur hat kein strukturiertes Muster im 2D Array. Zumindest ist mir keines bisher aufgefallen.

    Ich habe den Index zu einem Feld folgendermaßen ermittelt:
    Bei meinem Spielfeld habe ich von oben links angefangen zu zählen (A, F, L, Q, V = 5 |+ B, G, M, R, W = 10 |+ C, G, N = 13)
    Dann habe ich bei den „0“ markierten Feldern angefangen zu zählen von links oben und bin so zur Mitte gekommen.
    So habe ich bisher alle Warben-Felder in das 2D Array übertragen.
    Aber wie mache ich das meinem Programm klar?

    Ich könnte da einige Denkansätze gebrauchen.
    Die Schwierigkeit ist dabei, dass das Feld unterschiedlich groß sein kann.
    Die Map soll später nämlich zufällig generiert werden.

    Falls ich mich zu unklar ausgedrückt haben sollte, dann tut es mir sehr leid...
    Besser kann ich’s nicht erklären. ^^

    LG. Make =)

    Einmal editiert, zuletzt von Yjuq (25. März 2014 um 23:56)

  • Nach deiner Zeichnung erscheint es mir am sinnvollsten sich an den Spalten zu orientieren. Die Felder also so ins Array zu schreiben wie es deine Nummerierung nahelegt.
    Das Array wäre dann folgendermaßen aufgebaut:

    Code
    $aPanel[$iCol][$iRow]
    $iCol = Index der Spalte
    $iRow = Index der Reihe


    Die Verschiebung jeder zweiten Spalte wird im Array selbst nicht berücksichtigt.

    Dann brauchst du nur einen Regelsatz welche Änderung der Indizes eine bestimmte Bewegungsrichtung im Allgemeinen zur Folge hat.
    Dabei gibt es für die nach oben verschobenen Spalten einen anderen Regelsatz als für die nach unten verschobenen Spalten. Das musst du bei BEwegungen mit horizontalem Anteil berücksichtigen.
    Es gibt natürlich beliebig viele andere Ansätze. Vielleicht hat jemand eine bessere Idee.
    Ich kann dir eventuell später noch ein Beispielscript machen wenn ich dafür Zeit finde ;).

  • Ich konnte das Problem ein wenig anders lösen.
    Ein 2 Dimensionales Array lässt sich ja in ein 1 Dimensionales Array umrechnen.
    Wenn ich nun von einer Wabe aus nach...

    Spoiler anzeigen

    ... links bewege, verändert sich die Position um -1.
    ... links oben bewege, verändert sich die Position um -6.
    ... rechts oben bewege, verändert sich die Position um -5.
    ... rechts bewege, verändert sich die Position um +1.
    ... rechts unten bewege, verändert sich die Position um +5.
    ... links unten bewege, verändert sich die Position um +4.

    Dabei bin ich immer von der roten Wabe ausgegangen.
    Danach wird die Position (die ich im Eindimensionalen Raum berechnet habe) in eine Koordinate umgerechnet.
    So kann ich die Werte im Array abspeichern. Zudem habe ich das auch direkt dynamisch gehalten.

    Hier der Code:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aiField[5][5]
    $aiField[2][2] = 1

    [/autoit] [autoit][/autoit] [autoit]

    _MovePlayer($aiField, Random(1, 6, 1))
    _ArrayDisplay($aiField)

    [/autoit] [autoit][/autoit] [autoit]

    Func _MovePlayer(ByRef $aiField, $iMove)
    Local $iPos = _GetPlayer($aiField)
    Local $x = Floor($iPos / UBound($aiField)), $y = Mod($iPos, UBound($aiField))
    Switch $iMove
    Case 1
    $iPos -= 1
    Case 2
    $iPos -= UBound($aiField) +1
    Case 3
    $iPos -= UBound($aiField)
    Case 4
    $iPos += 1
    Case 5
    $iPos += UBound($aiField) -1
    Case 6
    $iPos += UBound($aiField)
    EndSwitch
    $aiField[$x][$y] = 0
    $x = Floor($iPos / UBound($aiField))
    $y = Mod($iPos, UBound($aiField))
    $aiField[$x][$y] = 1
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetPlayer(ByRef $aiField)
    Local $i, $n
    For $i = 0 To UBound($aiField) -1
    For $n = 0 To UBound($aiField, 2) -1
    If $aiField[$i][$n] Then Return UBound($aiField) * $i + $n
    Next
    Next
    EndFunc

    [/autoit]