I have a Player
class that stores a rating
property of type Int
:
class Player {
typealias Rating: Int
var rating: Rating = 0
}
I then have various Range
instances that specify the level
that a given player
is at:
private let level1Range = 0 ..< 100
private let level2Range = 100 ..< 500
I can then switch
on the player
rating
property to obtain the level that the player
is at:
switch rating {
case level1Range:
print("On Level 1")
case level2Range:
print("On Level 2")
default:
break
}
I want to be able to say what the next level is and how far away the player
is from that next level.
I'm not sure of the best way to go out this problem. I started by making an array:
private var ratingRanges: [Range] {
return [level1Range, level2Range]
}
But I get the error:
Reference to generic type 'Range' requires arguments in <...> Insert '<<#Bound: Comparable#>>'
If this worked, I guess I could then find the first non-zero value:
ratingRanges.first(where: { $0.min() - self.rating > 0 })
in order to locate the next range.
Or is there a more efficient method to achieve this?
Thanks for any help
You need to provide the generic placeholder type of the Range
:
private var ratingRanges: [Range<Rating>] {
return [level1Range, level2Range]
}
Or simpler, with automatic type inference, as a (lazy) stored property:
private lazy var ratingRanges = [level1Range, level2Range]
Determining the next range can then be done as
func nextRange() -> Range<Rating>? {
return ratingRanges.first(where: { $0.lowerBound > rating})
}
My solution is to create Level enum:
enum Level: Int {
case level1 = 1
case level2
init?(rating: Int) {
switch rating {
case Level.level1.range:
self = .level1
case Level.level2.range:
self = .level2
default:
return nil
}
}
var range: CountableRange<Int> {
switch self {
case .level1:
return level1Range
case .level2:
return level2Range
}
}
}
And then all you need to do is to add following methods to your Player class:
func nextLevel() -> Level? {
guard let currentLevel = Level(rating: rating) else {
return nil
}
guard let nextLevel = Level(rawValue: currentLevel.rawValue + 1) else {
return nil
}
return nextLevel
}
func distanceTo(level: Level) -> Int {
let levelLowerBound = level.range.lowerBound
return levelLowerBound - rating
}
May you should to keep the maximum value of range only. For example, instead of
private let level1Range = 0 ..< 100
private let level2Range = 100 ..< 500
you can use
private let level1MaxRating = 100
private let level2MaxRating = 500
and compare with
switch rating {
case 0...level1MaxRating:
print("level 1")
case (level1MaxRating+1)...level2MaxRating:
print("level 2")
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.