2017-01-13 1 views
1

Aus Spaß Ich baue ein FreeCell Solitaire Spiel von Grund auf in Swift. Ich habe mein Modell für das Deck eingerichtet, um das Deck zu bauen, und jede Kartenstruktur hat eine Farbe, Rang und Beschreibung (z. B. 4 ♠ ️) plus einige andere Eigenschaften. Das Modell für das Spiel speichert einfach, welche Karten in welchen Spalten enthalten sind. Eine Änderung in der Ansicht (Verschieben einer Karte) wird den Controller warnen, um zu modifizieren, welche Karten sich in welchen Spalten befinden.Kommunikation "welche Spielkarte" zwischen View und Model - bester Weg?

Wenn ein Benutzer auf die Karte tippt (eine Unterklasse von UIView mit einem Etikett, das card.description enthält), wird der label.text an den Controller gesendet, um die Karte im Modell zu identifizieren. Ich frage mich, was der beste Weg ist, dies zu tun.

Der offensichtlichste Weg, den ich mir vorstellen kann, ist ein Wörterbuch zu erstellen, wo die Schlüssel Beschreibungen sind und die Werte Karten sind. Ich kann natürlich eine Funktion in meine DeckBuilder-Klasse schreiben, um das Wörterbuch für mich zu erstellen. Aber da die Beschreibung bereits als eine Eigenschaft der Kartenstruktur existiert, scheint dies ein wenig überflüssig und klobig zu sein. Eine andere Methode wäre, jedes Mal, wenn eine Karte ausgewählt wird, durch das Kartenspiel im Modell zu iterieren und "if selectedCard.description == tryCard.description {// das ist die richtige Karte!}" Zu sagen das erscheint absurd unelegant und theoretisch zu rechenintensiv (obwohl ich mir in Wirklichkeit sicher bin, dass es keine Zeit braucht).

Was ich gerne tun würde, ist der Controller sagen "Holen Sie sich die Karte, die diese Zeichenfolge als Beschreibungseigenschaft hat." Ähnlich dem Wörterbuch-Lookup, aber ohne ein Wörterbuch.

Ist diese letzte Lösung möglich? Wenn nicht, was hältst du für das Beste?

Danke!

Antwort

1

Sie sollten den Text eines Etiketts nicht als Hinweis auf einen Wert an einem bestimmten Ort verwenden. Das ist wie das Speichern Ihres Modells in Ihrer Ansicht. Stattdessen haben Sie eine interne Struktur, die den Zustand der Spalten darstellt. Jede Spalte kann ein Array von Karten sein. Die Spalten selbst können in einem Array von Spalten sein:

struct Card {} 
    var deck = [Card]() 
    var columns: [[Card]] = [[Card]](repeating: [], count: 7) 
    deck.shuffle() 
    for i in 0..<columns.count { 
     for j in 0..<i { 
      columns[i].append(deck.draw()) 
     } 
    } 

Jetzt, wenn Sie einen Klick auf eine Ansicht haben. Sie müssen nur wissen, welche Spalte und welcher Index in dieser Spalte angeklickt wurde (Sie können dies basierend auf dem Rahmen der Ansicht oder indem Sie jeder Ansicht ein Tag zuweisen). Sie können jetzt den Wert der Karte erhalten, aber das Spaltenarray betrachten: columns [selectedColumn] [selectedRow]

+0

Danke! Dies scheint ein viel besserer Weg zu sein, um zwischen dem Modell und der Sichtweise zu kommunizieren. –

1

Ich würde zwei Enums erstellen, eins für den Rang und eins für den Anzug.

enum Rank { 
    case value(Int) 
    case jack 
    case queen 
    case king 
    case ace 
} 

enum Suit { 
    case diamond 
    case heart 
    case spade 
    case club 
} 

Dies ist viel sicherer und lesbarer als ein Wörterbuch. In Ihrer Strukturkarte können Sie diese beiden Eigenschaften hinzufügen.

struct Card { 
    var rank: Rank 
    var suit: Suit 
} 

Es ist an Ihnen, wenn Sie die Strings vergleichen wollen, vergleichen Sie die Aufzählungen oder sogar haben Ihre Karte struct zu dem Protokoll entsprechen gleichzusetzen. Ich würde wahrscheinlich für das Equatable-Protokoll gehen, aber ich denke nicht, dass es große Unterschiede zwischen diesen Optionen gibt.

Verwandte Themen