沟通"哪个扑克牌" View和Model之间 - 最好的方法?

时间:2017-01-13 08:19:33

标签: swift

为了好玩,我在Swift中从头开始构建FreeCell单人纸牌游戏。我已经为我的甲板设置了模型来构建套牌,每个Card结构都有套装,等级和描述(例如,4♠️)以及其他一些属性。游戏模型只是存储哪些卡在哪些列中。视图中的更改(移动卡片)将提醒控制器修改哪些卡在哪些列中。

当用户点击卡片(UIView的子类,包括包含card.description的标签)时,label.text将被发送到控制器以识别模型中的卡片。我想知道最好的办法是什么。

我能想到的最明显的方法是构建字典,其中键是描述,值是卡片。当然,我可以在我的DeckBuilder类中编写一个函数来为我构建字典。但由于描述已经作为Card结构的属性存在,这似乎有点多余和笨重。

另一种方法是,每次选择一张牌时,都会遍历模型中的牌组,然后说出“#34;如果选择卡片说明== tryCard.description {//这是正确的牌! }"但这看起来很荒谬,而且理论上计算上太昂贵了(虽然实际上我确定它根本没有时间)。

我喜欢做的是让控制器说"获取具有此String作为其描述属性的卡。"与字典查找类似,但没有实际字典。

这可能是最后一个解决方案吗?如果没有,你认为最好的是什么?

Thankya!

2 个答案:

答案 0 :(得分:1)

您不应使用标签文本作为某个位置值的指示;这就像在视图中存储模型一样。相反,您已经有了表示列状态的内部结构。每列可以是一系列卡片。列本身可以是列数组:

    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())
        }
    }

现在,如果您点击了一个视图。您只需要知道该列中的哪个列和索引被单击(您可以根据视图的框架或通过为每个视图指定标记来执行此操作)。您现在可以获取卡的值,但查看列数组:列[selectedColumn] [selectedRow]

答案 1 :(得分:1)

我会创建两个枚举,一个用于排名,一个用于诉讼。

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

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

这比字典更安全,更易读。在结构卡中,您可以添加这两个属性。

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

如果您想比较字符串,比较枚举或甚至让您的Card结构符合Equatable协议,那么由您决定。我可能会选择Equatable协议,但我不认为这些选项之间存在很大差异。