Last active
September 28, 2018 23:32
-
-
Save pphetra/85f7efd132d42f17530df55d74ca1aea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {from, Observable} from 'rxjs'; | |
import {reduce} from "rxjs/operators"; | |
import reduceReducers from "reduce-reducers"; | |
const MAX_LIFE = 7; | |
const zip = (arr1: Array<string>, arr2: Array<string>) => arr1.map((e, i) => [e, arr2[i]]) | |
type State = { | |
status: string, | |
knownSecretWord: Array<string>, | |
selectedLetters: Set<string>, | |
secretWordLength: number, | |
lifeLeft: number | |
} | |
type HangmanReducer = (state: State, guessCh: string) => State | |
const createHangmanReducers: ((_: string) => HangmanReducer) = (secretWord: string) => { | |
const word = secretWord.split(''); | |
; | |
const knownSecretWordReducer = (state: State, guessCh: string) => ({ | |
...state, knownSecretWord: zip(word, state.knownSecretWord) | |
.map(([ch, revealCh]) => ch === guessCh ? ch : revealCh) | |
}); | |
const leftLeftReducer = (state: State, guessCh: string) => ({ | |
...state, | |
lifeLeft: word.some(w => w === guessCh) ? state.lifeLeft : state.lifeLeft - 1 | |
}); | |
const selectedLettersReducer = (state: State, guessCh: string) => ({ | |
...state, | |
selectedLetters: state.selectedLetters.add(guessCh) | |
}); | |
const statusReducer = (state: State, guessCh: string) => ({ | |
...state, status: state.lifeLeft <= 0 ? 'lose' : | |
(state.knownSecretWord.some((ch: string) => ch === '_') ? 'in-progress' : 'win') | |
}); | |
return reduceReducers(knownSecretWordReducer, leftLeftReducer, selectedLettersReducer, statusReducer); | |
}; | |
function reactiveHangman(secretWord: string, letters: Observable<string>): Observable<object> { | |
return reduce(createHangmanReducers(secretWord), { | |
status: 'in-progress', | |
knownSecretWord: secretWord.split('').map(_ => '_'), | |
selectedLetters: new Set([]), | |
secretWordLength: secretWord.length, | |
lifeLeft: MAX_LIFE | |
})(letters); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment