Skip to content

Instantly share code, notes, and snippets.

@pphetra
Last active September 28, 2018 23:32
Show Gist options
  • Save pphetra/85f7efd132d42f17530df55d74ca1aea to your computer and use it in GitHub Desktop.
Save pphetra/85f7efd132d42f17530df55d74ca1aea to your computer and use it in GitHub Desktop.
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