W1520 Finite State Machine

From Coder Merlin
Revision as of 23:26, 14 April 2019 by Chukwuemeka-tinashe (talk | contribs) (Created page with "== Research == * Watch [https://www.mathworks.com/videos/understanding-state-machines-what-are-they-1-of-4-90488.html State Machines] (MathWorks) == Examples == === RPG ===...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder

Research[edit]

Examples[edit]

RPG[edit]

enum State {
    case inTheCourtyard
    case inTheCastle
    case inTheDungeon
    case death
}

// Prompt the user for an entry
// Continue to prompt until a valid entry is returned
// We ignore any invalid or superfluous input
// The selected character is returned
func getKeyboardInput(prompt:String, allowedCharacters:Set<Character>) -> Character {
    var key : Character = "\u{0000}"
    repeat {
        print("\(prompt) ->", terminator:"")
        if let line = readLine() {
           key = line.first ?? key
        }

        if !allowedCharacters.contains(key) {
            print("Invalid entry.  Press one of \(allowedCharacters) followed by <ENTER>.")
        }
    } while !allowedCharacters.contains(key)
    return key
}

func handleCourtyardInteraction() -> State {
    print("You find yourself in a wide courtyard.")
    var key : Character
    repeat {
        key = getKeyboardInput(prompt:"Would you like to go to the C)astle or wait for the D)ragon?", allowedCharacters:["C", "D"])
        switch key {
        case "C":
            print("Let's head to the castle!")
        case "D":
            print("You look above and see no dragon yet.")
        default:
            fatalError("Unexpected key \(key).")
        }
    } while key != "C";
    return .inTheCastle
}

func handleCastleInteraction() -> State {
    print("You find yourself in a dark, dank castle.")

    var key : Character
    repeat {
        key = getKeyboardInput(prompt:"Would you like to light a C)andle or look for the L)ight switch?", allowedCharacters:["C", "L"])
        switch key {
        case "C":
            print("You (very surprisingly) find a box of matches in your armor's front pocket.  You successfully light the candle.")
            print("You see a long, winding stairway immediately in front of you, and realize that had you taken another step in ")
            print("the dark, it would have been your last.")
            print("You descend carefully down the stairs to find yourself...")
        case "L":
            print("You slowly turn to your right, feeling in front of you for a light switch.")
            print("You touch only air.")
        default:
            fatalError("Unexpected key \(key).")
        }
    } while key != "C"
    return .inTheDungeon
}

func handleDungeonInteraction() -> State {
    print("You find yourself in a dungeon.")

    var key : Character
    repeat {
        key = getKeyboardInput(prompt:"Would you like to turn R)ight, L)eft, or move F)orwards?", allowedCharacters:["R", "L", "F"])
        switch key {
        case "R":
            print("You move cautiously to your right.  You see a flickering, momentary shadow.")
        case "L":
            print("You dart anxiously to your left.  You hear a deep, growl and sense a whiff of dragon's breath... but then it's gone.")
        case "F":
            print("You, quite briefly, see teeth.  Oh sh... is your final thought.")
        default:
            fatalError("Unexpected key \(key).")
        }
    } while key != "F"
    return .death
}

func main() {
    var state = State.inTheCourtyard
    repeat {
        switch state {
        case .inTheCourtyard:
            state = handleCourtyardInteraction()
        case .inTheCastle:
            state = handleCastleInteraction()
        case .inTheDungeon:
            state = handleDungeonInteraction()
        case .death:
            do {}
        }
    } while state != .death
    print("It's over.  Goodbye.")
}

main()