@@ -10,18 +10,28 @@ export type Round = Readonly<{
1010 didGuess : boolean ;
1111} > ;
1212
13- function getNewRound ( wordPack : readonly string [ ] ) : Round {
14- const word = getRandomElement ( wordPack ) ;
15-
16- return {
17- wordUnscrambled : word ,
18- wordScrambled : scrambleString ( word ) ,
19- didGuess : false ,
20- } ;
13+ function getNewRound (
14+ wordPack : readonly string [ ] ,
15+ bannedWords : readonly string [ ] ,
16+ ) : Round {
17+ while ( true ) {
18+ const word = getRandomElement ( wordPack ) ;
19+
20+ try {
21+ return {
22+ wordUnscrambled : word ,
23+ wordScrambled : scrambleString ( word , bannedWords ) ,
24+ didGuess : false ,
25+ } ;
26+ } catch {
27+ console . warn ( "Struggled to scramble " + word ) ;
28+ }
29+ }
2130}
2231
2332type PreGameState = Readonly < {
2433 phase : "pre-game" ;
34+ bannedWords : readonly string [ ] | null ;
2535 wordPack : readonly string [ ] | null ;
2636} > ;
2737
@@ -30,12 +40,14 @@ type InGameState = Readonly<{
3040 currentRound : Round ;
3141 finishedRounds : readonly Round [ ] ;
3242 guess : string ;
43+ bannedWords : readonly string [ ] ;
3344 wordPack : readonly string [ ] ;
3445} > ;
3546
3647type PostGameState = {
3748 phase : "post-game" ;
3849 finishedRounds : readonly Round [ ] ;
50+ bannedWords : readonly string [ ] ;
3951 wordPack : readonly string [ ] ;
4052} ;
4153
@@ -44,7 +56,7 @@ export type State = PreGameState | InGameState | PostGameState;
4456function getNewRoundState ( state : InGameState , didGuess : boolean ) : InGameState {
4557 return {
4658 ...state ,
47- currentRound : getNewRound ( state . wordPack ) ,
59+ currentRound : getNewRound ( state . wordPack , state . bannedWords ) ,
4860 finishedRounds : [
4961 ...state . finishedRounds ,
5062 didGuess ? { ...state . currentRound , didGuess : true } : state . currentRound ,
@@ -54,15 +66,16 @@ function getNewRoundState(state: InGameState, didGuess: boolean): InGameState {
5466}
5567
5668export function getInitialState ( ) : State {
57- return { phase : "pre-game" , wordPack : null } ;
69+ return { phase : "pre-game" , bannedWords : null , wordPack : null } ;
5870}
5971
6072export type Action =
61- | { type : "load-data" ; wordPack : readonly string [ ] }
62- | { type : "start-game" }
63- | { type : "update-guess " ; newGuess : string }
73+ | { type : "end-game" }
74+ | { type : "load-banned-words" ; bannedWords : readonly string [ ] }
75+ | { type : "load-word-pack " ; wordPack : readonly string [ ] }
6476 | { type : "skip-word" }
65- | { type : "end-game" } ;
77+ | { type : "start-game" }
78+ | { type : "update-guess" ; newGuess : string } ;
6679
6780export function reducer ( state : State , action : Action ) : State {
6881 switch ( action . type ) {
@@ -75,13 +88,23 @@ export function reducer(state: State, action: Action): State {
7588 return {
7689 phase : "post-game" ,
7790 finishedRounds : [ ...state . finishedRounds , state . currentRound ] ,
91+ bannedWords : state . bannedWords ,
7892 wordPack : state . wordPack ,
7993 } ;
8094 }
8195
82- case "load-data" : {
83- // No-op if not in pre-game phase.
84- if ( state . phase !== "pre-game" ) {
96+ case "load-banned-words" : {
97+ // No-op if not in pre-game phase, or if we already have banned words..
98+ if ( state . phase !== "pre-game" || state . bannedWords ) {
99+ return state ;
100+ }
101+
102+ return { ...state , bannedWords : action . bannedWords } ;
103+ }
104+
105+ case "load-word-pack" : {
106+ // No-op if not in pre-game phase, or if we already have a word pack.
107+ if ( state . phase !== "pre-game" || state . wordPack ) {
85108 return state ;
86109 }
87110
@@ -104,16 +127,17 @@ export function reducer(state: State, action: Action): State {
104127 }
105128
106129 // No-op if data is not loaded.
107- const { wordPack } = state ;
108- if ( wordPack == null ) {
130+ const { bannedWords , wordPack } = state ;
131+ if ( bannedWords == null || wordPack == null ) {
109132 return state ;
110133 }
111134
112135 return {
113136 phase : "in-game" ,
114- currentRound : getNewRound ( wordPack ) ,
137+ currentRound : getNewRound ( wordPack , bannedWords ) ,
115138 finishedRounds : [ ] ,
116139 guess : "" ,
140+ bannedWords,
117141 wordPack,
118142 } ;
119143 }
0 commit comments