![](/img/trans.png)
[英]Add two values to a VBScript array and compare to see if they equal each other
[英]How can I compare 3 values in an array to “not” or “all” equal each other?
问题:
我正在构建游戏Set ,因此必须在板上选择3张牌。 这些卡中的每一个都有四个不同的属性:
现在,我想将3张选定的牌相互比较,并计算它们是否匹配。 我不能只是想办法解决这个问题,因为我也想以一种不错的方式编写它,而不是使用数十个for循环。
因此,如果满足以下条件,我们将有一个匹配项:
分配
因此,现在我应该发明一个解决方案,使“根据老师”非常简单,并且我为此应用程序设计的模型不应超过100行代码。 现在,我有近100行代码,还需要做更多的事情。 因此,我应该以非常干燥的方式实现这一点。
您将如何解决这个问题
我需要一些指导以指导我朝正确的方向发展。 在Swift中缺少数组的内置方法吗?还是我需要实现某种协议
( 注:以下解决方案是为Set游戏的特殊情况量身定制的,其中所有三个值均为0、1或2。这无助于检查三个任意值是否相等或全部不同。)
一点数学会有所帮助。 如果您在0到2的范围内有三个整数x,y,z,则x + y + z是(且仅当)的3的倍数
可以用
if (x + y + z) % 3 == 0 {
// x, y, z are all equal or all different.
}
因此,如果Card
类型定义为
struct Card {
let number: Int // 0, 1, 2
let symbol: Int // 0, 1, 2
let shade: Int // 0, 1, 2
let color: Int // 0, 1, 2
}
然后使用以下命令非常有效地完成对有效集合的检查:
func isValidMatch(c1: Card, c2: Card, c3: Card) -> Bool {
return (c1.number + c2.number + c3.number) % 3 == 0
&& (c1.symbol + c2.symbol + c3.symbol) % 3 == 0
&& (c1.shade + c2.shade + c3.shade) % 3 == 0
&& (c1.color + c2.color + c3.color) % 3 == 0
}
或者,为各种属性定义原始值在0、1、2范围内的枚举:
struct Card {
enum Number: Int {
case one, two, three
}
enum Symbol: Int {
case diamond, squiggle, oval
}
enum Shade: Int {
case solid, striped, open
}
enum Color: Int {
case red, green, purple
}
let number: Number
let symbol: Symbol
let shade: Shade
let color: Color
}
func isValidMatch(c1: Card, c2: Card, c3: Card) -> Bool {
return (c1.number.rawValue + c2.number.rawValue + c3.number.rawValue) % 3 == 0
&& (c1.symbol.rawValue + c2.symbol.rawValue + c3.symbol.rawValue) % 3 == 0
&& (c1.shade.rawValue + c2.shade.rawValue + c3.shade.rawValue) % 3 == 0
&& (c1.color.rawValue + c2.color.rawValue + c3.color.rawValue) % 3 == 0
}
您的Card
类应符合Equatable协议:
class Card : Equatable {
let color: Int
let shape: Int
let shade: Int
let number: Int
//This is a failable initializer (https://developer.apple.com/swift/blog/?id=17) since we haven't used enums like in another answer, which are safer.
init?(color: Int, shape: Int, shade: Int, number: Int) {
//make sure that all properties are between 0 and 2
guard 0...2 ~= color, 0...2 ~= shape, 0...2 ~= shade, 0...2 ~= number else {
fatalError("All properties should be integers between 0 and 2")
}
self.color = color
self.shape = shape
self.shade = shade
self.number = number
}
static func == (lhs: Card, rhs: Card) -> Bool {
return lhs.color == rhs.color && lhs.shape == rhs.shape && lhs.shade == rhs.shade && lhs.number == rhs.number
}
}
因此,当所有四个属性都相等时,您将具有相等性。 如@MartinR所述 :在Swift 4.1及更高版本中,编译器将自动合成==
运算符,并足以声明符合Equatable协议。
为了符合Equatable协议,您要做的就是实现此功能:
static func == (lhs: Card, rhs: Card) -> Bool
现在,如果要检查3张卡是否相等,请使用==
运算符:
let c1 = Card(color: 2, shape: 1, shade: 0, number: 1)
let c2 = Card(color: 2, shape: 1, shade: 0, number: 1)
let c3 = Card(color: 2, shape: 1, shade: 0, number: 1)
let c4 = Card(color: 2, shape: 1, shade: 0, number: 2)
(c1 == c2) && (c2 == c3)
最后,如果您希望具有一次比较三张卡片的功能,可以将此代码添加到Card
类中:
class func compareThreeCards(firstCard: Card, secondCard: Card, thirdCard: Card) -> Bool {
return (firstCard == secondCard) && (secondCard == thirdCard)
}
您可以这样使用它:
Card.compareThreeCards(firstCard: c1!, secondCard: c2!, thirdCard: c3!)
从Swift 4.1开始,结构和枚举可以免费使用Equatable和Hashable(不适用于Class)。
因此,例如,如果您具有Card结构,只需将此类型设为可散列的,使用您的卡片创建一个集合,然后对其进行比较即可。
struct Card: Hashable {
var color: Int
var shape: Int
var shade: Int
var number: Int
}
let card1 = Card(color: 2, shape: 2, shade: 2, number: 0)
let card2 = Card(color: 2, shape: 2, shade: 2, number: 1)
let card3 = Card(color: 3, shape: 1, shade: 0, number: 2)
print(card1 == card2 && card2 == card3) // Prints false, all different.
let card4 = Card(color: 1, shape: 2, shade: 0, number: 0)
let card5 = Card(color: 1, shape: 2, shade: 0, number: 0)
let card6 = Card(color: 1, shape: 2, shade: 0, number: 0)
print(card4 == card5 && card5 == card6) // Prints true, all the same.
注意(感谢Leo Dabus):设置它为无序集合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.