为了好玩,我在Swift中从头开始构建FreeCell单人纸牌游戏。我已经为我的甲板设置了模型来构建套牌,每个Card结构都有套装,等级和描述(例如,4♠️)以及其他一些属性。游戏模型只是存储哪些卡在哪些列中。视图中的更改(移动卡片)将提醒控制器修改哪些卡在哪些列中。
当用户点击卡片(UIView的子类,包括包含card.description的标签)时,label.text将被发送到控制器以识别模型中的卡片。我想知道最好的办法是什么。
我能想到的最明显的方法是构建字典,其中键是描述,值是卡片。当然,我可以在我的DeckBuilder类中编写一个函数来为我构建字典。但由于描述已经作为Card结构的属性存在,这似乎有点多余和笨重。
另一种方法是,每次选择一张牌时,都会遍历模型中的牌组,然后说出“#34;如果选择卡片说明== tryCard.description {//这是正确的牌! }"但这看起来很荒谬,而且理论上计算上太昂贵了(虽然实际上我确定它根本没有时间)。
我喜欢做的是让控制器说"获取具有此String作为其描述属性的卡。"与字典查找类似,但没有实际字典。
这可能是最后一个解决方案吗?如果没有,你认为最好的是什么?
Thankya!
答案 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协议,但我不认为这些选项之间存在很大差异。