首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用enum管理游戏级别

用enum管理游戏级别
EN

Code Review用户
提问于 2018-09-26 12:47:09
回答 1查看 232关注 0票数 2

基本上我有篮子球应用程序。其中我增加了一些层次和困难。逻辑只是在枚举中使用tupple,我有一些方法可以用新值更新/获取当前级别。

我已经创建了以下代码

代码语言:javascript
复制
enum Difficulty:String {
    case easy
    case medium
    case hard
    func getRatioForTargetAgaintsAvailable() -> Float {
        switch  self {
        case .easy:
            return 0.3
        case .medium:
            return 0.5
        case .hard :
            return 0.8
        }
    }

    func getDistanceForTarget () -> Float {
        switch  self {
        case .easy:
            return 5
        case .medium:
            return 6
        case .hard :
            return 7
        }
    }

}

主enum

代码语言:javascript
复制
enum Level:CustomStringConvertible {
    var description: String {
        return "Welcome to New  \(self.getDifficulty().rawValue) Level , Your Target is \(getTargetValue()), You have \(getAvailableBalls()) Balls left"
    }

    case level1(avaiableBalls:Int,difficulty:Difficulty,totalScore:Int)
    case level2(avaiableBalls:Int,difficulty:Difficulty,totalScore:Int)
    case level3(avaiableBalls:Int,difficulty:Difficulty,totalScore:Int)

    //--------------------------------------------------------------------------------

    //MARK:- Set  Methdos

    //--------------------------------------------------------------------------------

    mutating func updateTotalScore (newValue:Int) {
        switch self {

        case .level1(  let availableBall, let  difficulty,  _):
            self = Level.level1(avaiableBalls: availableBall, difficulty: difficulty, totalScore: newValue)

        case .level2(   let availableBall, let  difficulty,   _):
            self = Level.level2(avaiableBalls: availableBall, difficulty: difficulty, totalScore: newValue)


        case .level3(   let availableBall, let  difficulty,   _):
            self = Level.level3(avaiableBalls: availableBall, difficulty: difficulty, totalScore: newValue)

        }
    }

    mutating func updateAvailableBalls (newValue:Int) {
        switch self {

        case .level1( _, let  difficulty,  let totalScore):
            self = Level.level1(avaiableBalls: newValue, difficulty: difficulty, totalScore: totalScore)

        case .level2(   _ , let  difficulty,   let totalScore):
            self = Level.level2(avaiableBalls: newValue, difficulty: difficulty, totalScore: totalScore)


        case .level3(  _ , let  difficulty,   let totalScore):
            self = Level.level3(avaiableBalls: newValue, difficulty: difficulty, totalScore: totalScore)

        }
    }

    mutating func gotoNextLevel() -> Bool {
        switch  self {
        case .level1:
            self = Level.level2(avaiableBalls: 20, difficulty: .medium, totalScore: 0)
            return true
        case .level2:
            self = Level.level2(avaiableBalls: 20, difficulty: .hard, totalScore: 0)
            return true
        case .level3 :
            self = Level.level3(avaiableBalls: 20, difficulty: .hard, totalScore: 0)
            return false


        }
    }

    mutating func restartLevel () {
        switch  self {
        case .level1:
            self = Level.level1(avaiableBalls: 20, difficulty: .easy, totalScore: 0)
        case .level2:
            self = Level.level2(avaiableBalls: 20, difficulty: .medium, totalScore: 0)
        case .level3 :
            self = Level.level3(avaiableBalls: 20, difficulty: .hard, totalScore: 0)

        }
    }


    //--------------------------------------------------------------------------------

    //MARK:-   Get  Methdos

    //--------------------------------------------------------------------------------




    func getTotalScore () -> Int {
        switch self {
        case .level1(_,_, let totalScore) :
            return totalScore
        case .level2(_,_, let totalScore) :
            return totalScore

        case .level3(_,_ ,let totalScore):
            return totalScore
        }
    }

    func getAvailableBalls () -> Int {
        switch self {
        case .level1(let availableBall,_,_) :
            return availableBall
        case .level2(let availableBall,_,_) :
            return availableBall

        case .level3(let availableBall,_,_) :
            return availableBall
        }
    }

    func getTargetValue () -> Int {
        switch self{
        case .level1(  let _, let  difficulty,   _):
            return  Int(difficulty.getRatioForTargetAgaintsAvailable() * Float(20))

        case .level2(   let _, let  difficulty,   _):
            return  Int(difficulty.getRatioForTargetAgaintsAvailable() * Float(20))


        case .level3(   let _, let  difficulty,   _):
            return  Int(difficulty.getRatioForTargetAgaintsAvailable() * Float(20))

        }
    }

    func getMinDistanceFromHook () -> Float {
        switch self{
        case .level1(  _, let  difficulty,   _):
                return difficulty.getDistanceForTarget()

        case .level2(   _, let  difficulty,   _):
            return difficulty.getDistanceForTarget()


        case .level3(   _, let  difficulty,   _):
            return difficulty.getDistanceForTarget()
        }
    }

    func getDifficulty () -> Difficulty {
        switch self{
        case .level1(  _, let  difficulty,   _):
            return difficulty

        case .level2(   _, let  difficulty,   _):
            return difficulty

        case .level3(   _, let  difficulty,   _):
            return difficulty
        }
    }

    func isLevelPassed () -> Bool {
        return getTotalScore() == getTargetValue()
    }


}

现在在我的ViewController中创建对象

代码语言:javascript
复制
var currentLevel = Level.level1(avaiableBalls: 20, difficulty: .easy, totalScore: 0)

所以我的问题是,这是实现这个功能的好方法吗?

谢谢你看这个

EN

回答 1

Code Review用户

回答已采纳

发布于 2018-09-27 18:39:41

注释和当前代码

的简化

Swift不使用getter方法的“get”前缀,因此

代码语言:javascript
复制
func getDistanceForTarget() -> Float

更好的名字

代码语言:javascript
复制
func targetDistance() -> Float

如果函数不带任何参数,没有副作用,并且是幂等的(即在每次调用时返回相同的值),在您的情况下,通常更好地表示为只读计算属性。

代码语言:javascript
复制
var targetDistance: Float

有关详细讨论,请参见软件工程方面的Swift函数与计算性质

上述内容适用于所有的getXXX方法。

getTotalScore()函数可以简化为

代码语言:javascript
复制
func getTotalScore() -> Int {
    switch self {
    case .level1(_, _, let totalScore),
         .level2(_, _, let totalScore),
         .level3(_, _, let totalScore):
        return totalScore
    }
}

因为所有情况都绑定相同的变量。这同样适用于以下getter方法。

中通配符模式前面的let

代码语言:javascript
复制
    case .level1(  let _, let  difficulty,   _):

不需要,并导致编译器警告。

中将显式转换为Float

代码语言:javascript
复制
return  Int(difficulty.getRatioForTargetAgaintsAvailable() * Float(20))

不需要,因为20既可以是整数,也可以是浮点文字:

代码语言:javascript
复制
return  Int(difficulty.getRatioForTargetAgaintsAvailable() * 20)

description协议的CustomStringConvertible方法应该提供

此实例的文本表示形式。

你滥用它是为了一个欢迎的信息。

建议采用不同的数据结构

显然,代码中有很多重复的地方。增加另一个级别将需要更新9个功能。

如果我正确理解它(我不是篮球专家!),Level类型被用来存储。

  • A级(1、2、3)。每个级别都绑定到一个Difficulty (1 =轻松,2=中等,3=硬)。
  • 一个整数可用的球。
  • 一个整数总分。

如果我们使Difficulty成为一个Int-based枚举,那么我们可以直接将它作为“级别”来使用,而不是在几个地方维护这种通信:

代码语言:javascript
复制
enum Difficulty: Int {
    case easy = 1
    case medium
    case hard
}

Level现在成为一个具有三个(独立)属性的struct。这使得许多getter方法过时:

代码语言:javascript
复制
struct PlayerStatus {

    var level: Difficulty
    var availableBalls: Int
    var totalScore: Int
}

(我在这里使用了一个不同的名称,以避免与level属性混淆。)

用init方法

代码语言:javascript
复制
init(level: Difficulty = .easy) {
    self.level = level
    availableBalls = 20
    totalScore = 0
}

创建初始状态与创建初始状态一样容易。

代码语言:javascript
复制
var currentStatus = PlayerStatus()

由于基于整数的enum Difficulty,可以使用rawValue实现更新到下一个级别,而不需要开关/大小写,并且与级别数无关:

代码语言:javascript
复制
mutating func gotoNextLevel() {
    if let newLevel = Difficulty(rawValue: self.level.rawValue + 1) {
        self = PlayerStatus(level: newLevel)
    } else {
        // Already at the highest level.
    }
}

把这一切都放在一起,我们

代码语言:javascript
复制
enum Difficulty: Int {
    case easy = 1
    case medium
    case hard

    var targetRatio: Float {
        switch  self {
        case .easy:
            return 0.3
        case .medium:
            return 0.5
        case .hard:
            return 0.8
        }
    }

    var targetDistance: Float {
        switch  self {
        case .easy:
            return 5
        case .medium:
            return 6
        case .hard:
            return 7
        }
    }
}

struct PlayerStatus {

    var level: Difficulty
    var availableBalls: Int
    var totalScore: Int

    init(level: Difficulty = .easy) {
        self.level = level
        availableBalls = 20
        totalScore = 0
    }

    mutating func restartLevel() {
        self = PlayerStatus(level: self.level)
    }

    mutating func gotoNextLevel() {
        if let newLevel = Difficulty(rawValue: self.level.rawValue + 1) {
            self = PlayerStatus(level: newLevel)
        } else {
            // Already at the highest level.
        }
    }

    var targetValue: Int {
        return Int(level.targetRatio * 20)
    }

    var levelPassed: Bool {
        return totalScore == targetValue
    }
}
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/204404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档