@@ -6,9 +6,10 @@ if (!SpeechRecognition) {
6
6
<p>Please use Chrome or Edge for the best experience.</p>
7
7
` ;
8
8
} else {
9
- const messageElement = document . getElementById ( "msg" ) ;
10
-
11
- const randomNumber = getRandomNumber ( ) ;
9
+ let messageElement ;
10
+ let randomNumber ;
11
+ let shouldRestartRecognition = true ;
12
+ let guesses = [ ] ;
12
13
let recognition = new SpeechRecognition ( ) ;
13
14
recognition . lang = "en-US" ;
14
15
recognition . start ( ) ;
@@ -18,7 +19,8 @@ if (!SpeechRecognition) {
18
19
}
19
20
20
21
function onSpeak ( event ) {
21
- const message = event . results [ 0 ] [ 0 ] . transcript ;
22
+ let message = event . results [ 0 ] [ 0 ] . transcript ;
23
+ message = message . replace ( / [ . , ; : ! ? ] + $ / , "" ) ;
22
24
writeMessage ( message ) ;
23
25
checkNumber ( message ) ;
24
26
}
@@ -32,32 +34,108 @@ if (!SpeechRecognition) {
32
34
33
35
function checkNumber ( message ) {
34
36
const number = + message ;
37
+ let feedback = "" ;
35
38
if ( Number . isNaN ( number ) ) {
36
- messageElement . innerHTML += "<div>That is not a valid number</div>" ;
39
+ feedback = "That is not a valid number" ;
40
+ } else if ( number > 100 || number < 1 ) {
41
+ feedback = "Number must be between 1 and 100" ;
42
+ } else if ( number === randomNumber ) {
43
+ feedback = `Congrats! You have guessed the number! It was ${ number } ` ;
44
+ shouldRestartRecognition = false ;
45
+ recognition . stop ( ) ;
46
+ document . body . innerHTML = `
47
+ <h2>${ feedback } </h2>
48
+ <button class="play-again" id="play-again">Play Again</button>
49
+ ` ;
50
+ speak ( feedback ) ;
51
+ renderGuesses ( ) ;
52
+ document
53
+ . getElementById ( "play-again" )
54
+ . addEventListener ( "click" , setupGame ) ;
37
55
return ;
56
+ } else if ( number > randomNumber || number < randomNumber ) {
57
+ guesses . unshift ( number ) ;
58
+ renderGuesses ( ) ;
59
+ feedback = number > randomNumber ? "GO LOWER" : "GO HIGHER" ;
38
60
}
39
- if ( number > 100 || number < 1 ) {
40
- messageElement . innerHTML += "<div>Number must be between 1 and 100</div>" ;
41
- return ;
61
+
62
+ if ( feedback ) {
63
+ messageElement . innerHTML += `<div>${ feedback } </div>` ;
64
+ speak ( feedback ) ;
42
65
}
43
- if ( number === randomNumber ) {
44
- document . body . innerHTML = `
45
- <h2>Congrats! You have guessed the number! <br><br>
46
- It was ${ number } </h2>
47
- <button class="play-again" id="play-again">Play Again</button>
48
- ` ;
49
- } else if ( number > randomNumber ) {
50
- messageElement . innerHTML += "<div>GO LOWER</div>" ;
51
- } else {
52
- messageElement . innerHTML += "<div>GO HIGHER</div>" ;
66
+ }
67
+
68
+ // Add Speech Synthesis Feedback
69
+ function speak ( text ) {
70
+ speechSynthesis . cancel ( ) ;
71
+ const utterance = new SpeechSynthesisUtterance ( text ) ;
72
+ utterance . lang = "en-US" ;
73
+ speechSynthesis . speak ( utterance ) ;
74
+ }
75
+
76
+ // Refactor Game Over Logic
77
+ function setupGame ( ) {
78
+ recognition . stop ( ) ;
79
+ shouldRestartRecognition = true ;
80
+ document . body . innerHTML = `
81
+ <img
82
+ src="https://i.ibb.co/Kb6SkTm/8399350-mic-microphone-audio-icon.png"
83
+ alt="Speak"
84
+ />
85
+ <h1>Guess a Number Between 1 - 100</h1>
86
+ <h2>Speak the number into your microphone</h2>
87
+ <div id="msg" class="msg"></div>
88
+ <div id="history" class="msg"></div>
89
+ ` ;
90
+ messageElement = document . getElementById ( "msg" ) ;
91
+ randomNumber = getRandomNumber ( ) ;
92
+ recognition . start ( ) ;
93
+ guesses = [ ] ;
94
+ renderGuesses ( ) ;
95
+ }
96
+
97
+ // Implement a Guess History
98
+ function renderGuesses ( ) {
99
+ const historyDiv = document . getElementById ( "history" ) ;
100
+ if ( ! historyDiv ) return ;
101
+ historyDiv . innerHTML =
102
+ guesses . length === 0
103
+ ? "<div>No guesses yet.</div>"
104
+ : `<div>Previous guesses: ${ guesses . join ( ", " ) } </div>` ;
105
+ }
106
+
107
+ // Handle Recognition Errors
108
+ function handleRecognitionError ( e ) {
109
+ if ( ! messageElement ) return ;
110
+ let errorMsg ;
111
+ switch ( e . error ) {
112
+ case "no-speech" :
113
+ errorMsg =
114
+ "No speech detected. Please try speaking clearly into your microphone." ;
115
+ break ;
116
+ case "audio-capture" :
117
+ errorMsg =
118
+ "No microphone found. Please check your microphone connection." ;
119
+ shouldRestartRecognition = false ;
120
+ break ;
121
+ case "not-allowed" :
122
+ errorMsg =
123
+ "Microphone access was denied. Please allow access and try again." ;
124
+ shouldRestartRecognition = false ;
125
+ break ;
126
+ default :
127
+ errorMsg = `Error: ${ e . error } ` ;
53
128
}
129
+ messageElement . innerHTML = `<div>${ errorMsg } </div>` ;
130
+ speak ( errorMsg ) ;
54
131
}
55
132
56
133
// Event Listeners
57
134
recognition . addEventListener ( "result" , onSpeak ) ;
58
- recognition . addEventListener ( "end" , ( ) => recognition . start ( ) ) ;
59
-
60
- document . body . addEventListener ( "click" , ( e ) => {
61
- if ( e . target . id == "play-again" ) history . go ( 0 ) ;
135
+ recognition . addEventListener ( "end" , ( ) => {
136
+ if ( shouldRestartRecognition ) recognition . start ( ) ;
62
137
} ) ;
138
+ recognition . addEventListener ( "error" , handleRecognitionError ) ;
139
+
140
+ setupGame ( ) ;
63
141
}
0 commit comments