Skip to content

Instantly share code, notes, and snippets.

@chrisschreiner
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisschreiner/28e53466cff8c2ebfd45 to your computer and use it in GitHub Desktop.
Save chrisschreiner/28e53466cff8c2ebfd45 to your computer and use it in GitHub Desktop.
//Swift 2.0
import Foundation
protocol vcProtocol {
func hidePuzzleMessage()
func showPuzzleMessage()
func prepareBoard()
}
class ViewController: vcProtocol {
func prepareBoard() {print("board prepared")}
func hidePuzzleMessage() {print("hide the puzzle message")}
func showPuzzleMessage() {print("show the puzzle message")}
}
/// ==========================================================================
enum Input: CustomStringConvertible {
case A, B, C, F(String), X(Int,Int)
var description: String {
switch self {
case A: return "A"
case B: return "B"
case C: return "C"
case let F(string): return "F\(string)"
case let X(x,y): return "X(\(x),\(y))"
}
}
}
/// --------------------------------------------------------------------------
typealias ReturnState = ChessGameStateProtocol?
protocol ChessGameStateProtocol {
var stateName: String {get}
func enter()
func update()
func exit()
func handleInput(input:Input) -> ReturnState
}
class Game {
var vc: vcProtocol
var state: ChessGameStateProtocol
required init(vc: vcProtocol, initialState: ChessGameStateProtocol) {
self.vc = vc
self.state = initialState
}
func handleInput(input:Input) {
if let nextState = state.handleInput(input) {
state.exit()
nextState.enter()
state = nextState
}
state.update()
}
}
/// --------------------------------------------------------------------------
class RootState: ChessGameStateProtocol {
var stateName: String {return "RootState"}
func enter() {} /// override and implement these in subclasses of RootState to invoke
/// on entering, exiting and updating of states
func exit() {}
func update() {}
func handleInput(input:Input) -> ReturnState {
print("\(stateName): no handler defined for \(input.description)")
return ErrorState()
}
}
class ErrorState: RootState {
override func update() {
fatalError("error: unaccounted state")
}
}
/// --------------------------------------------------------------------------
class NewGame: RootState {
override var stateName: String {return "NewGame"}
override func update() {
super.update()
}
override func handleInput(input:Input) -> ReturnState {
switch input {
case .A:
print("NewGame: handle case A")
return PlayerToMove(turnColor:"White piece")
case let .F(string):
print("\(stateName): handle case F with value \(string)")
return nil //but stay in the same state
default:
return super.handleInput(input)
}
}
}
class PlayerToMove: RootState {
override var stateName: String {return "PlayerToMove \(turnColor)"}
let turnColor: String
override func handleInput(input:Input) -> ReturnState {
switch input {
case .B:
print("PlayerToMove: handle case B")
return NewGame()
case .X(_,_):
print("\(stateName): handle case for \(input.description)")
return nil
default:
return super.handleInput(input)
}
}
init(turnColor:String) {self.turnColor = turnColor}
}
/// ==========================================================================
var game = Game(vc: ViewController(), initialState: NewGame())
let listOfInput:[Input] = [
.F("sample-data"),
.A,
.X(1,2)
]
for eachInput in listOfInput {
game.handleInput(eachInput)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment