我正在尝试为游戏Sets初始化一副纸牌,每张纸牌有4个参数:颜色,形状,阴影和纸牌上的形状数量。
我的卡类如下:
enum CardColor : Int {
case red = 1
case purple = 2
case green = 3
}
enum CardShape : Int {
case line = 1
case snake = 2
case diamond = 3
}
enum CardShade : Int {
case empty = 1
case filled = 2
case stripes = 3
}
class Card {
var color : CardColor
var shape : CardShape
var shade : CardShade
var number : Int
var image : String
var isTapped = false
var isMatched = false
init(color : CardColor , shape : CardShape, shade : CardShade , number : Int) {
self.color = color
self.shape = shape
self.shade = shade
self.number = number
self.image = "\(color.rawValue)\(shape.rawValue)\(shade.rawValue)\(number)"
}
}
我找不到初始化卡座的方法,我目前正在使用手动制作的Card卡数组:
cards = [Card(color: .red, shape: .diamond, shade: .filled, number: 1)...
以此类推。
卡片看起来像这样:
答案 0 :(得分:2)
For循环在这里可以很好地工作。使用4个嵌套循环来遍历属性并在内部循环内创建新卡:
在您的枚举中添加CaseIterable
,以便轻松访问所有案例:
enum CardColor : Int, CaseIterable {
case red = 1
case purple = 2
case green = 3
}
然后:
// Array to hold the cards
var cards = [Card]()
for color in CardColor.allCases {
for shape in CardShape.allCases {
for shade in CardShade.allCases {
for number in 1...3 {
// Create a new card and append it to the array
cards.append(Card(color: color, shape: shape, shade: shade, number: number))
}
}
}
}
答案 1 :(得分:1)
我将使用一系列flatMaps
来生成完整的牌组。我还要更改其他一些内容:
Card
为结构。任何一条为红色的空行的卡片都与其他任何一条为红色的空行的卡片相同。即卡片的身份与价值没有分别,因此引用类型(类)将无用。isTapped
结构中提取isMatched
或Card
字段。那里没有意义。如果您向Set玩家提供一张牌并询问他们isTapped
的值是什么,他们将一无所知。它根本不属于。我会制作类似CardSlot
或CardView
这样的东西来跟踪此类UI状态。image
更改为imageName
。如果它确实是image
,则希望它具有类型UIImage
或NSImage
,而不是String
。
imageName
更改为计算属性。现在,所有存储的字段(color
,shape
,shade
,parity
)都可以由成员明智的初始化程序填充,编译器将自动为该结构合成。 Card
,以防止其所有名称中使用不必要的Card
前缀。green_line_filled_three.png
胜过3123.png
rawValue
来生成图像名称,可以将其删除。几乎不再需要使用Int
原始值。 C interop是我唯一能想到的。要生成所有枚举值,可以使用CaseIterable
,而不是在init(rawValue: Int)
范围内映射Int
。number: Int
更改为arity: Card.arity
,以防止出现非法值这是下面的样子:
struct Card {
enum Color: CaseIterable { case red, purple, green }
enum Shape: CaseIterable { case line, snake, diamond }
enum Shade: CaseIterable { case empty, filled, striped }
enum Arity: CaseIterable { case one, two, three }
let color: Color
let shape: Shape
let shade: Shade
let arity: Arity
var imageName: String {
return "\(color)\(shape)\(shade)\(arity)"
}
static func generateFullDeck() -> [Card] {
return Color.allCases.flatMap { color in
return Shape.allCases.flatMap { shape in
return Shade.allCases.flatMap { shade in
return Arity.allCases.map { arity in
return Card(color: color, shape: shape, shade: shade, arity: arity)
}
}
}
}
/*
// Alternate implementation which prevents the "pyramid of doom" nesting,
// But it's considerably more complex
return Color.allCases.lazy.flatMap { color in
Shape.allCases.map { shape in (color, shape)}
}.flatMap { (color, shape) in
Shade.allCases.map { shade in (color, shape, shade) }
}.flatMap { (color, shape, shade) in
Arity.allCases.map { arity in
}
})
*/
}
}
Card.generateFullDeck().forEach { print($0) }