[Javascript] Broadcaster + Operator + Listener pattern -- 18. Create a Win Condition with a mapDone Operator
Many streams of events end when a certain condition is met. When we run into that condition, we'll want to pass down our own custom values. This lessons walks through adding a done condition to hangman and how we can use new operators to control what happens when it's done.
Continue with previous post.
1. Set a win logic:
let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat); hangman(inputValue)(log); // to let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat); let play = hangman(inputValue); let winPipe = pipe(filter((str) => !str.includes("*"))); let win = winPipe(play); play(console.log); win(() => { console.log("you win"); });
When we enter 'honeycomb' in the input, it will log out 'you win', but as you continue typing, 'you win' continue pop up:
/* honeycomb you win honeycombb you win honeycombbbb you win */
2. doneCondition operator:
let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat); let doneCondition = (condition) => (broadcaster) => (listener) => { let cancel = filter(condition)(broadcaster)((value) => { listener(done); cancel(); }); return () => { cancel(); }; }; let winPipe = pipe(doneCondition((str) => !str.includes("*"))); let play = hangman(inputValue); let win = winPipe(play); play(console.log); win(() => { console.log("you win"); });
Now, 'you win' only log out once.
3. Pass 'you win' from a operator:
let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat); let doneCondition = (condition) => (broadcaster) => (listener) => { let cancel = filter(condition)(broadcaster)((value) => { listener(done); cancel(); }); return () => { cancel(); }; }; let mapDone = (doneValue) => (broadcaster) => (listener) => { broadcaster((value) => { if (value === done) { listener(doneValue); } }); }; let winPipe = pipe( doneCondition((str) => !str.includes("*")), mapDone("you win!") ); let play = hangman(inputValue); let win = winPipe(play); play(console.log); win(console.log);
4. Cancel 'play' when 'win':
let hangman = pipe(map(hangmanLogic), applyOperator(word), stringConcat); let doneCondition = (condition) => (broadcaster) => (listener) => { let cancel = filter(condition)(broadcaster)((value) => { listener(done); cancel(); }); return () => { cancel(); }; }; let mapDone = (doneValue) => (broadcaster) => (listener) => { broadcaster((value) => { if (value === done) { listener(doneValue); } }); }; let cancelWhen = (cancelBroadcaster) => (broadcaster) => (listener) => { let cancel = broadcaster(listener); let cancel2 = cancelBroadcaster(() => { cancel(); }); return () => { cancel(); cancel2(); }; }; let winPipe = pipe( doneCondition((str) => !str.includes("*")), mapDone("you win!") ); let play = hangman(inputValue); let win = winPipe(play); let rules = pipe(cancelWhen(win)); let playWithWin = rules(play); playWithWin(console.log); win(console.log);