Frage zu multiplen Arrays

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Frage zu multiplen Arrays

    Hallo,

    ich möchte gerne ein Tic Tac Toe - Spiefeld nachbilden, indem ich 3 Reihen mit jeweils 3 Nullen bilde, die dann später mit 1 ("x") oder 2 ("O") befüllt werden:

    Quellcode

    1. var reihen = [[0,0,0],[0,0,0],[0,0,0]]


    Ich möchte nun auch die 3 Spalten und und 2 Diagonale in Form eines multiplen Arrays abbilden, ausgehend vom Array reihen:

    Quellcode

    1. var spalten = [reihe[0][0],reihe[1][0],reihe[2][0],
    2. reihe[0][1],reihe[1][1],reihe[2][1],
    3. reihe[0][2],reihe[1][2],reihe[2][2]
    4. ]
    5. var diagonale = [reihe[0][0],reihe[1][1],reihe[2][2],
    6. reihe[0][1],reihe[1][1],reihe[2][0]
    7. ]

    Wenn ich nun Änderungen im Arry reihen vornehme, sollen sich natürlich automatisch die Werte in spalten und diagonale ändern. Hier hänge ich derzeit fest, wie kann ich das programmatisch lösen? Packe ich alles in ein struxt oder class erhalte ich Fehlermeldungen, muß ich hier mit get/set arbeiten oder evtl. subscripts?

    Danke für Tips
    Klaus
  • Wenn Du etwas mehrfach referenzieren möchtest, dann musst Du (Mutable) Objekte verwenden.

    Erstelle also z.B. eine Klasse Feld. Von dieser Klasse erzeugst Du dann 9 Objekte, welche Du dann in den Arrays reihen, spalten und diagonale verwendest. Du kannst dann jetzt über das Array reihen als auch über spalten und diagonale auf das gleiche Feld Objekte zugreifen.
  • Ich bin zwar nicht sicher, ob ich Deinen Ansatz verstehe, aber ich würde mir Routinen schreiben, die mir z. B. die x. Spalte als Array zurück liefern... Vielleicht wäre es geschickter, direkt eine Methode zu schreiben, die prüft, ob eine Dreier-Reihe vorliegt?

    Mattes

    P.S.: Ansonsten finde ich @MCDans Antwort gut, von Primitives auf Objekte zu wechseln und dann deren Pointer zu verwenden!
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MCDan schrieb:

    [Blockierte Grafik: https://www.dropbox.com/l/scl/AACOEhCPtpuVFx4olJ4yuM4kSqozPMS8590]Wenn Du etwas mehrfach referenzieren möchtest, dann musst Du (Mutable) Objekte verwenden.

    Erstelle also z.B. eine Klasse Feld. Von dieser Klasse erzeugst Du dann 9 Objekte, welche Du dann in den Arrays reihen, spalten und diagonale verwendest. Du kannst dann jetzt über das Array reihen als auch über spalten und diagonale auf das gleiche Feld Objekte zugreifen.
    Dankje erstmal, ich habe es mal versucht mit Klassen/Objekten zu lösen, das funktioniert aber leider nicht so wie ich es mir vorstelle

    Quellcode

    1. import UIKit
    2. class Spielfeld {
    3. var reihen = [[0,0,0],[0,0,0],[0,0,0]]
    4. }
    5. class Spalten {
    6. var spalten = [[spielfeld.reihen[0][0],spielfeld.reihen[1][0],spielfeld.reihen[2][0]],
    7. [spielfeld.reihen[0][1],spielfeld.reihen[1][1],spielfeld.reihen[2][1]],
    8. [spielfeld.reihen[0][2],spielfeld.reihen[1][2],spielfeld.reihen[2][2]]]
    9. }
    10. class Diagonale {
    11. var diagonale = [[spielfeld.reihen[0][0],spielfeld.reihen[1][1],spielfeld.reihen[2][2]],
    12. [spielfeld.reihen[0][1],spielfeld.reihen[1][1],spielfeld.reihen[2][0]]]
    13. }
    14. var spielfeld = Spielfeld()
    15. var columns = Spalten()
    16. var diagonals = Diagonale()
    17. print(diagonals.diagonale[0])
    18. spielfeld.reihen[0][0] = 666
    19. print(spielfeld.reihen[0])
    20. print(diagonals.diagonale[0])
    Alles anzeigen




    Quellcode

    1. Ergebnis:
    2. [0, 0, 0]
    3. [666, 0, 0]
    4. [0, 0, 0]


    Mir ist nur nicht ganz klar, warum das nicht funktioniert...

    Danke für Tips
    Klaus
  • Da liegt bei Dir ein Denkfehler vor: @MCDan schrieb von Objekten für die Felder, nicht für die Spalten oder Diagonalen. Du verwendet noch immer Primitives für die einzelnen Felder, diese werden bei der Zuweisung kopiert und somit Änderungen der Zeile z. B. nicht in die Diagonale übernommen. Du müsstest die Felder selber als Objekte deklarieren, beispielsweise NSNumber. Dann werden bei der Zuweisung nur Referenzen auf das selbe Objekt verwendet und die Belegungen der Felder bleiben konsistent...

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MyMattes schrieb:

    Da liegt bei Dir ein Denkfehler vor: @MCDan schrieb von Objekten für die Felder, nicht für die Spalten oder Diagonalen. Du verwendet noch immer Primitives für die einzelnen Felder, diese werden bei der Zuweisung kopiert und somit Änderungen der Zeile z. B. nicht in die Diagonale übernommen. Du müsstest die Felder selber als Objekte deklarieren, beispielsweise NSNumber. Dann werden bei der Zuweisung nur Referenzen auf das selbe Objekt verwendet und die Belegungen der Felder bleiben konsistent...

    Mattes

    Vielen Dank, das war der entscheidene Hinweis :)

    Ich hab es jetzt mal so gelöst und es funktioniert (ok, ist zwar etwas Overkill, aber es geht mir hier nur um das grundsätzliche Verständnis)

    Quellcode

    1. class Feld {
    2. var field: NSNumber = 0
    3. }
    4. var feld = Feld()
    5. var reihe = [feld.field, feld.field, feld.field]
    6. var spielfeld = [reihe, reihe, reihe]
    7. var spalte = [[spielfeld[0][0], spielfeld[1][0], spielfeld[2][0]],
    8. [spielfeld[0][1], spielfeld[1][1], spielfeld[2][1]],
    9. [spielfeld[0][2], spielfeld[1][2], spielfeld[2][2]]
    10. ]
    11. var diagonale = [[spielfeld[0][0], spielfeld[1][1], spielfeld[2][2]],
    12. [spielfeld[0][1], spielfeld[1][1], spielfeld[2][0]]
    13. ]
    14. print(spielfeld)
    15. spielfeld[0][0] = 666
    16. print(spielfeld)
    Alles anzeigen




    Quellcode

    1. Ergebnis:
    2. [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    3. [[666, 0, 0], [0, 0, 0], [0, 0, 0]]
  • Diese print-Ausgabe hätte mit dem vorigen Ansatz auch funktioniert, da Du beide Male das gleiche Array ausgibst, in dem Du auch die Veränderung des Feldes vornimmst. Ein richtiger Test wäre gewesen, z. B. einmal das Spielfeld und einmal eine Spalte / Reihe / Diagonale auszugeben. Trotzdem korrekt gelöst :D

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Hm, ich sehe da jetzt keinen Unterschied zum ersten Code. Du verwendest immer noch Primitives und keine Objekte in den Arrays.

    Ich wette, dass nach

    Quellcode

    1. spielfeld[0][0] = 666
    ,bei Ausgabe von spalte oder diagonale, weiterhin

    Quellcode

    1. [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    2. [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    ausgegeben wird. ;)
  • Hallo Klaus,

    (zuerst zum letzten Post von McDan: Das mit der Ausgabe ist richtig, wobei es nur 2 Diagonalen sind statt drei.)

    Ich habe deinen Code aus Post 4 als Grundlage genommen, um den in Post 3 von Mattes vorgeschlagenen Ansatz umzusetzen:

    Quellcode

    1. import Cocoa
    2. class Spielfeld {
    3. var reihen = [[0,0,0],[0,0,0],[0,0,0]]
    4. var spalten : [[Int]]
    5. {
    6. return [[reihen[0][0],reihen[1][0],reihen[2][0]],
    7. [reihen[0][1],reihen[1][1],reihen[2][1]],
    8. [reihen[0][2],reihen[1][2],reihen[2][2]]]
    9. }
    10. var diagonalen : [[Int]]
    11. {
    12. return [[reihen[0][0],reihen[1][1],reihen[2][2]],
    13. [reihen[0][1],reihen[1][1],reihen[2][0]]]
    14. }
    15. }
    16. var spielfeld = Spielfeld()
    17. print("Diagonale 1: \(spielfeld.diagonalen[0])")
    18. spielfeld.reihen[0][0] = 666
    19. print("Reihe 1: \(spielfeld.reihen[0])")
    20. print("Diagonale 1: \(spielfeld.diagonalen[0])")
    Alles anzeigen
    Eine Klasse für das Spielfeld und diese bietet passende Properties für den Zugriff auf die Felder bzw. die Spalten und
    Diagonalen. Dieser Ansatz erlaubt es, bei Int zu bleiben, da das Feld bzw. seine Einträge nicht an verschiedenen
    Stellen referenziert werden müssen. Spalten und Diagonalen liefern Kopien.

    Die Ausgabe ist dann:

    Quellcode

    1. Diagonale 1: [0, 0, 0]
    2. Reihe 1: [666, 0, 0]
    3. Diagonale 1: [666, 0, 0]

    Noch besser als der obige Code wäre es, wenn reihen ein privates Feld wäre und es für den Zugriff auf die Reihen
    ebenso wie bei Spalten eine Property gibt, die eine Kopie liefert. Dann benötigt man natürlich noch Methoden zum
    Setzen der Felder, wodurch man auch Werte wie 666 ausschliessen kann, wenn eigentlich nur 0, 1 oder 2 erlaubt
    sind. Swift typisch wäre wohl, einen eigenen enum zu definieren.

    Grüße
    Marco