我想知道如何使一个 Int
符合 d6
(模值)。
我想通过协议来实现;但我不太清楚如何让Int遵循d6的规则;也就是说。
语境: 我有一个程序,其中有一个数组的 orders
的整数,这些整数是由随机的 d6
由Gameplaykit生成。
按照。
// Fill array with 3 existingOrders
let orders = [Order(), Order(), Order()]
orders.forEach { (order) in
print (order.value)
}
// Order struct ----
struct Order {
enum State: Int {
case existingOrder = 0, completedOrder
}
private (set) var value: Int // I want this value to conform to a `d6` protocol
var state: Order.State
init() {
self.value = Die.roll
self.state = .existingOrder
}
}
我们利用Gameplaykit生成一个随机的数字
struct Die: Equatable {
public static var roll: Int {
let d6 = GKRandomDistribution.d6()
return (d6.nextInt())
}
}
所以,我想做的是 value
中的命令结构符合d6协议。
起初我以为我可以直接这样做。
protocol Rollable {
func roll() -> Int
}
struct D6: Rollable {
var value: Int
func roll() -> Int {
let d6 = GKRandomDistribution.d6()
return (d6.nextInt())
}
init() {
self.value = roll() // throws error: self used before all stored properties
}
mutating func decrease(by amount: Int) {
guard (self.value > 0) else { return }
self.value -= amount
}
}
然而它并不是一个协议,而且它还抛出了一个错误。
错误:在所有存储属性之前使用了self
因此,我的疑问是 -- -- 能否强制执行 value: Int
里面 Order
结构,以符合一个 d6
协议中的d6。
感谢
编辑:尝试在关联类型中进行操作。
protocol Die {
associatedtype d6 = Int
var value: d6 { get set }
func roll() -> d6
}
不过不知道这样做对不对
我认为你在这里不需要一个协议的值,而是使用依赖注入来设置使用什么GKRandomDistribution。我的解决方案没有使用你的 Rollable
协议,但如果你想的话,当然可以从这个解决方案中提取一个协议。
class Dice {
let randomDistribution: GKRandomDistribution
private(set) var value: Int
init(_ randomDistribution: GKRandomDistribution) {
self.randomDistribution = randomDistribution
value = 0
self.roll()
}
func roll() {
value = randomDistribution.nextInt()
}
func decrease(by amount: Int) {
guard (self.value >= randomDistribution.lowestValue + amount) else { return }
self.value -= amount
}
}