我有一个 Player 类,它具有三个 Int 属性和 totalAbilityScore 属性,用于计算这三个 Int 属性的总和。
private var strength : Int?
private var speed : Int?
private var agility : Int?
private var totalAbilityScore : Int?
我的挑战是创建 15 个玩家对象,并且没有两个玩家的总属性得分(速度 + 力量 + 敏捷 = 总属性得分)相同,总得分小于 100。
我尝试生成 15 个唯一的随机数并使用以下代码存储在数组中。现在我的问题是,从数组中的每个变量生成其他两个不同变量的可能方法是什么,以便这些总和应小于 100 并与数组中的其他数字不同。
func randomNumber(between lower: Int, and upper: Int) -> Int {
return Int(arc4random_uniform(UInt32(upper - lower))) + lower
}
func generateRandomUniqueNumbers(forLowerBound lower: Int, andUpperBound upper:Int, andNumNumbers iterations: Int) -> [Int] {
guard iterations <= (upper - lower) else { return [] }
var numbers: Set<Int> = Set<Int>()
(0..<iterations).forEach { _ in
let beforeCount = numbers.count
repeat {
numbers.insert(randomNumber(between: lower, and: upper))
} while numbers.count == beforeCount
}
return numbers.map{ $0 }
}
最佳答案
无需将您的播放器属性设为可选。使用结构并使总计成为计算属性:
struct Player {
let strength : Int
let speed : Int
let agility : Int
var totalAbilityScore: Int {
return strength + speed + agility
}
}
检查方法内部的逻辑注释:
func generatePlayers(n: Int) -> [Player] {
var possibleTotals = Array(0..<100)
var players: [Player] = []
// make totals a set so it wont rpeat
var totals: Set<Int> = []
// loop while totals count it is not reached
while totals.count < n {
// pick a random index and remove it
let index = Int(arc4random_uniform(UInt32(possibleTotals.count)))
totals.insert(possibleTotals[index])
possibleTotals.remove(at: index)
}
// loop through your totals
for total in totals {
// make sure you have enough elements to pick two index to split your array from 0 to 99
if total > 2 {
// make your indexes a set so it wont repeat
var indexes: Set<Int> = []
let array = Array(0..<total)
while indexes.count < 2 {
let index = Int(arc4random_uniform(UInt32(total)))
indexes.insert(index)
}
// sort your indexes
let sortedIndices = indexes.sorted()
// create 3 array slices
let a1 = array[0..<sortedIndices[0]]
let a2 = array[sortedIndices[0]..<sortedIndices[1]]
let a3 = array[sortedIndices[1]..<array.endIndex]
// initialize your player with the slices count
print(total, [a1.count, a2.count, a3.count])
players.append(Player(strength: a1.count, speed: a2.count, agility: a3.count))
// take care of very small totals like 0,1 or 2
} else if total == 2 {
var values = [0, 1, 1]
values.indices.dropLast().forEach {
values.swapAt($0, Int(arc4random_uniform(UInt32(values.count - $0))) + $0)
}
print(values)
players.append(Player(strength: values[0], speed: values[1], agility: values[2]))
} else if total == 1 {
var values = [0, 0, 1]
values.indices.dropLast().forEach {
values.swapAt($0, Int(arc4random_uniform(UInt32(values.count - $0))) + $0)
}
print(values)
players.append(Player(strength: values[0], speed: values[1], agility: values[2]))
} else {
print([0,0,0])
players.append(Player(strength: 0, speed: 0, agility: 0))
}
}
return players
}
测试
let players = generatePlayers(n: 15)
这将打印
68 [7, 55, 6]
[0, 0, 0]
37 [4, 16, 17]
32 [17, 7, 8]
72 [0, 52, 20]
22 [13, 7, 2]
70 [28, 30, 12]
18 [2, 4, 12]
9 [4, 2, 3]
39 [6, 32, 1]
31 [18, 2, 11]
92 [53, 12, 27]
81 [36, 31, 14]
98 [65, 9, 24]
关于ios - 假设 x,y,z 是我需要实现的类的属性 total = x+y+z 并且我创建的每个对象的总数应该不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46575997/