Reputation: 491
I want to create a list of levels with a score required to reach that level. But I'm not sure how best to do it.
For example I tried an enum like this:
enum xpLevels {
case 1 = 0...50
case 2 = 51...100
case 3 = 101...200
}
But this gives me errors saying: "Consecutive declarations on a line must be separated by ';'"
And I'm quite sure I haven't structured this right. Is an enum even the right thing to be using for this? I'd appreciate any help to point me in the right direction.
Upvotes: 0
Views: 123
Reputation: 236360
You can create an enumeration with the maximum score for each level as suggested by paulsm4 and declare your enumeration as CaseIterable
. Then you can create an initializer to get the corresponding case for the score:
enum Level: Int, CaseIterable {
case one = 50, two = 100, three = 200
}
extension Level {
init(rawValue: Int) {
self = Level.allCases.first { 0...$0.rawValue ~= rawValue } ?? .one
}
}
extension Int {
var level: Level { .init(rawValue: self) }
}
let score = 165
let level = score.level // three
You can also create a custom enumeration of closed ranges. You just need to create a computed property to return each case range:
enum Level: CaseIterable {
case one, two, three, four
}
extension Level: RawRepresentable {
typealias RawValue = ClosedRange<Int>
var rawValue: RawValue {
let range: RawValue
switch self {
case .one: range = 0 ... 50
case .two: range = 51 ... 100
case .three: range = 101 ... 200
case .four: range = 201 ... .max
}
return range
}
init?(rawValue: RawValue) {
guard let level = Level.allCases.first(where: { $0.rawValue == rawValue }) else { return nil }
self = level
}
init(score: Int) {
self = Level.allCases.first { $0.rawValue ~= score } ?? .one
}
}
extension Int {
var level: Level { .init(score: self) }
}
let score = 76
let level = score.level // two
Upvotes: 0
Reputation: 271575
Enums are very unsuitable for this. Try an array instead. For example, you can store:
let levelXps = [0, 50, 100, 200]
Or if you want to write out the level numbers as well:
let levelXps = [0:0, 1:50, 2:100, 3:200].values.sorted()
Then you can have a function that tells you what level it is, given a score:
func level(forScore score: Int) -> Int? {
levelXps.lastIndex(where: { score > $0 })?.advanced(by: 1)
}
This finds the index of the last item in the array that is smaller than the given score, then adds 1 to it. If the score is negative, the function returns nil.
Upvotes: 0
Reputation: 121649
If you really wanted enums, you might do something like this:
enum xpLevels {
case low = 50
case medium = 100
case high = 200
}
Then, in your code, check if the value is <= low
, else <= medium
, else it must be "high" ;)
Upvotes: 1