Sha256: 975f15bba5348a2c7db193e58cd053f9bbdbea55992cffe4a79803d770238478

Contents?: true

Size: 1.98 KB

Versions: 396

Compression:

Stored size: 1.98 KB

Contents

module Hangman

open System

let allowedFailures = 9

type Progress =
    | Win
    | Lose
    | Busy of int

type State = { progress: Progress; maskedWord: string; guesses: Set<char> }

let updateProgress word guess (state: State) =
    match state.progress with
    | Win  -> { state with progress = Win }
    | Lose -> { state with progress = Lose }
    | Busy x -> 
        if state.maskedWord = word then
            { state with progress = Win }
        elif x <= 0 then
            { state with progress = Lose }
        elif not <| word.Contains(string guess) || Set.contains guess state.guesses then
            { state with progress = Busy (x - 1) }        
        else
            state            

let updateMaskedWord word guess (state: State) = 
    let updatedGuesses = Set.add guess state.guesses
    let updatedMaskedWord = 
        word 
        |> Seq.map (fun x -> if Set.contains x updatedGuesses then x else '_') 
        |> Seq.toArray 
        |> System.String 

    { state with maskedWord = updatedMaskedWord }    

let updateGuesses guess (state: State) = { state with guesses = Set.add guess state.guesses }

let updateState word guess (state: State) =
    state
    |> updateMaskedWord word guess
    |> updateProgress word guess
    |> updateGuesses guess

let mkStartState (word: string) = { progress = Busy allowedFailures; maskedWord = String('_', word.Length); guesses = Set.empty }

type Game(word) = 
    let initialState = new Event<State>()
    let guesses = new Event<char>()
    let startState = mkStartState word
    
    member this.States = Observable.merge initialState.Publish (Observable.scan (fun state guess -> updateState word guess state) startState guesses.Publish)    
    member this.Start() = initialState.Trigger(startState)
    member this.MakeGuess(guess) = guesses.Trigger(guess)

let createGame word = new Game(word)
let startGame (game: Game) = game.Start()
let makeGuess guess (game: Game) = game.MakeGuess(guess)
let statesObservable (game: Game) = game.States

Version data entries

396 entries across 396 versions & 1 rubygems

Version Path
trackler-2.2.1.119 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.118 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.117 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.116 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.115 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.114 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.113 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.111 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.110 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.109 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.108 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.107 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.106 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.105 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.104 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.103 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.102 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.101 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.100 tracks/fsharp/exercises/hangman/Example.fs
trackler-2.2.1.99 tracks/fsharp/exercises/hangman/Example.fs