问题描述
我正在尝试初始化一副纸牌。我的卡片结构中有卡片属性。我的方法是尝试创建枚举状态的数组,然后遍历所有这些以初始化每个卡。我这样做很麻烦。
I am trying to initialize a deck of cards. I have card attributes in my card struct. My approach is to try and create an array of "enum states", then iterate through those to initialize each card. I am having trouble doing so.
游戏类
import Foundation
struct Set{
var cards = [Card]()
init(){
let properties : [Any] =
[cardShape.self, cardColor.self, cardNumber.self, cardShading.self]
for prop in properties{
// Not really sure how to iterate through this array...
// Ideally it would be something like this.
// Iterate through array, for property in array,
// card.add(property)
}
}
}
卡类
import UIKit
import Foundation
struct Card{
var attributes : properties = properties()
mutating func addProperty(value : Property){
if value is cardShape{
attributes.shape = value as! cardShape
} else if value is cardColor{
attributes.color = value as! cardColor
} else if value is cardNumber{
attributes.number = value as! cardNumber
}else if value is cardShading{
attributes.shading = value as! cardShading
}else{
print("error")
}
}
}
protocol Property{
static var allValues : [Property] {get}
}
struct properties{
var shape : cardShape = cardShape.none
var color : cardColor = cardColor.none
var number : cardNumber = cardNumber.none
var shading : cardShading = cardShading.none
}
enum cardShape : String,Property{
case Square = "■"
case Triangle = "▲"
case Circle = "●"
case none
static var allValues : [Property]{ return [cardShape.Square,cardShape.Triangle,cardShape.Circle]}
}
enum cardColor:Property {
case Red
case Purple
case Green
case none
static var allValues : [Property] {return [cardColor.Red,cardColor.Purple,cardColor.Green]}
}
enum cardNumber : Int,Property{
case One = 1
case Two = 2
case Three = 3
case none
static var allValues : [Property] {return [cardNumber.One,cardNumber.Two,cardNumber.Three]}
}
enum cardShading: Property {
case Solid
case Striped
case Outlined
case none
static var allValues : [Property] {return [cardShading.Solid,cardShading.Striped,cardShading.Outlined]}
}
因此,总而言之,我的主要问题是尝试创建一个枚举数组,然后循环遍历枚举状态以初始化具有特定属性状态的卡。
So to summarize, my main issue is trying to create an array of enums, then cycling through the enum states to initialize a card with specific attribute states.
推荐答案
您将要确保涵盖所有属性组合,并确保每个卡都具有四种属性中的一种。我建议使用嵌套循环:
You will want to make sure you cover all combinations of attributes and make sure each card has one of each of the four types of attributes. I would suggest using nested loops:
for shape in cardShape.allValues {
for color in cardColor.allValues {
for number in cardNumber.allValues {
for shading in cardShading.allValues {
var card = Card()
card.addProperty(shape)
card.addProperty(color)
card.addProperty(number)
card.addProperty(shading)
cards.append(card)
}
}
}
}
我相信您的卡
结构
有点太复杂了。如果您更改自己的表示形式,将更容易创建卡片。
I believe your Card
struct
is a bit too complex. If you change your representation, it will be easier to create the cards.
让卡片将不同的属性表示为自己的属性:
Have your card represent the different attributes as their own property:
struct Card {
let shape: CardShape
let color: CardColor
let number: CardNumber
let shading: CardShading
}
然后使用嵌套循环创建您的卡片:
Then use nested loops to create your cards:
for shape in CardShape.allValues {
for color in CardColor.allValues {
for number in CardNumber.allValues {
for shading in CardShading.allValues {
cards.append(Card(shape: shape, color: color, number: number, shading: shading))
}
}
}
}
注意:
- 枚举应以大写字母开头,而枚举值应以小写字母开头。
- Usin每个属性使用单独的属性将使检查卡之间的匹配属性变得更加容易。
- 默认情况下,您会获得一个初始化所有属性的初始化程序。通过使用嵌套循环初始化它们,您将能够创建所有可能的卡。
- 更改您的
allValues
属性以返回特定属性类型(例如[CardShape]
)。
- Your enums should start with uppercase characters, and your enum values should start with lowercase characters.
- Using separate properties for each attribute will make it much easier to check for matching attributes between cards.
- You get an initializer by default that initializes all properties. By initializing them with nested loops, you will be able to create all possible cards.
- Change your
allValues
properties to return arrays of the specific attribute type (for example[CardShape]
).
替代答案:
除了使用嵌套数组,还可以使用函数可创建属性组合的列表。将 init
添加到 Card
需花费 [Property]
的卡片,您可以用两行代码创建卡:
Instead of using nested arrays, you could use MartinR's combinations
function to create the list of combinations of the properties. Adding an init
to Card
that takes [Property]
, you can create the cards in two lines of code:
struct Card {
var shape = CardShape.none
var color = CardColor.none
var number = CardNumber.none
var shading = CardShading.none
init(properties: [Property]) {
for property in properties {
switch property {
case let shape as CardShape:
self.shape = shape
case let color as CardColor:
self.color = color
case let number as CardNumber:
self.number = number
case let shading as CardShading:
self.shading = shading
default:
break
}
}
}
}
// https://stackoverflow.com/a/45136672/1630618
func combinations<T>(options: [[T]]) -> AnySequence<[T]> {
guard let lastOption = options.last else {
return AnySequence(CollectionOfOne([]))
}
let headCombinations = combinations(options: Array(options.dropLast()))
return AnySequence(headCombinations.lazy.flatMap { head in
lastOption.lazy.map { head + [$0] }
})
}
struct SetGame {
let cards: [Card]
init(){
let properties: [Property.Type] = [CardShape.self, CardColor.self, CardNumber.self, CardShading.self]
cards = combinations(options: properties.map { $0.allValues }).map(Card.init)
}
}
工作原理:
-
properties.map {$ 0.allValues}
在每个项目上调用allValues
properties
数组创建一个[[Property]]
并与[[。square,.triangle, .circle],[。red,.purple,.green],[。one,.two,.three],[。solid, .striped,.outlined]]
- 这将传递给
combinations
,从而创建一个包含所有81这些属性的组合:[[.. square,.red,.one,.solid],...,[.circle,.green,.three,.outlined]]
。 -
map
在此序列上运行,以调用Card.init
每种组合都会产生[Card]
,其中有81张卡。
properties.map { $0.allValues }
callsallValues
on each item of theproperties
array creating an[[Property]]
with[[.square, .triangle, .circle], [.red, .purple, .green], [.one, .two, .three], [.solid, .striped, .outlined]]
- This is passed to
combinations
which creates a sequence with all 81 combinations of these properties:[[.square, .red, .one, .solid], ..., [.circle, .green, .three, .outlined]]
. map
is run on this sequence to callCard.init
with each combination which results in an[Card]
with 81 cards.
这篇关于枚举的可迭代数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!