【问题标题】:Swift - How to manage turn order management?Swift - 如何管理转单管理?
【发布时间】:2017-05-08 17:50:30
【问题描述】:

我正在开发一款依赖回合顺序的本地游戏。

规则;

  • 游戏中有多个phases(即:买、卖)
  • 在每个phase 期间,一名玩家转一圈
  • 在每个玩家(按顺序)完成他们的回合之前,每个 phase 都不会被视为完成。

我不确定如何管理这些数据。有很多事情要跟踪。

  1. 我们所处的阶段
  2. 当前轮到的玩家
  3. 当所有玩家完成他们的回合时
  4. 当回合顺序结束时,我们可以进入下一阶段。
  5. 在所有阶段完成后重置所有回合完成

我认为订阅模式是解决此问题的最佳方法,但我不习惯这种模式。

目前我正在使用与待办事项类似的系统,其中阶段本身可以标记为完成或不完整。

这就是我目前在 Swift Playground 中处理轮班订单和阶段的方式。

// Turn order management

class TurnOrderManager: NSObject
{
    static var instance = TurnOrderManager()

    var turnOrder: [Player] = [Player]()
    private var turnOrderIndex = 0

    var current: Player {
        return turnOrder[turnOrderIndex]
    }

    func next() {
        if (self.turnOrderIndex < (self.turnOrder.count-1)) {
            turnOrderIndex += 1
        }
        else {
            print("Reached end of line")
        }
    }
}

class Player: NSObject {
    var name: String = ""

    override var description: String {
        return self.name
    }

    init(name: String) {
        super.init()
        self.name = name
    }
}

let p1:Player = Player.init(name: "Bob")
let p2:Player = Player.init(name: "Alex")

TurnOrderManager.instance.turnOrder = [p1,p2]
print (TurnOrderManager.instance.current)

TurnOrderManager.instance.next()
print (TurnOrderManager.instance.current)

TurnOrderManager.instance.next()
print (TurnOrderManager.instance.current)

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

// Phase management
enum PhaseType: Int {
    case buying = 1
    case selling
}

struct Phase {
    var id: PhaseType
    var title: String
    var completed: Bool = false {
        didSet {
            // Notify subscribers of completion
            guard completed else { return }
            handlers.forEach { $0(self) }
        }
    }

    var description:String {
        return "Phase: \(self.title), completed: \(completed)"
    }

    // Task queue
    var handlers = [(Phase) -> Void]()

    init(id: PhaseType, title: String, initialSubscription: @escaping (Phase) -> Void =
        {_ in})
    {
        self.id = id
        self.title = title
        subscribe(completion: initialSubscription)
    }

    mutating func subscribe(completion: @escaping (Phase) -> Void) {
        handlers.append(completion)
    }
}

class MyParentController {

    lazy var phase1: Phase = {
        return Phase(id: .buying, title: "Phase #1") {
            print("Do something with phase: \($0.title)")
        }
    }()

}

let controller = MyParentController()

controller.phase1.completed = true

问题:

我要通知:

  • 转弯完成
  • 所有回合都已完成(以便可以进入下一阶段)

如何让我的 TurnOrderManager 提醒 PhaseManager 当前转弯已完成。

我如何让我的 PhaseManager 知道所有回合都完成后才能进入下一阶段。

对于我的查询过于冗长,我深表歉意。

非常感谢

【问题讨论】:

    标签: swift observer-pattern subscriber


    【解决方案1】:

    您将要定义一个委托关系 PhaseManager 和您的 TurnOrderManager。

    Here 是关于协议的 Apple 文档。

    Here 是一篇关于委托的精彩文章。

    首先您需要定义一个协议。像这样的:

    protocol TurnManagerDelegate {
       func complete(turn: objectType)
       func allTurnsComplete()
    }
    

    接下来,您必须使 PhaseManager 符合协议:

    class PhaseManager: TurnManagerDelegate {
       ...
    
       func complete(turn: objectType) {
          // implement 
       }
    
       func allTurnsComplete() {
          // implement 
       }
       ...
    }
    

    最后,您必须使用委托在 TurnOrderManager 上添加一个属性:

    class TurnOrderManager {
    ...
       var delegate: TurnManagerDelegate
    ...
    }
    

    并在需要时调用 TurnOrderManager 中的函数:

    ...
    delegate?.allTurnsComplete() //example
    ...
    

    在 TurnOrderManager 尝试调用任何委托方法之前,您还必须将 PhaseManager 设置为委托。

    【讨论】:

    • 这更有意义。我感谢您的帮助。我在想我可以使用订阅模式;但我不太了解它实际上是如何工作的——但是委托/协议方法对我来说似乎很有意义,所以我一定会在一个新的游乐场文件中尝试它并从头开始
    • 没问题! NSNotifications(订阅模型)真的应该只在你需要与很多对象通信或者你需要注册系统通知(例如键盘通知)时使用
    猜你喜欢
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多