diff --git a/Basic-Typing-Game/index.html b/Basic-Typing-Game/index.html new file mode 100644 index 00000000..bdd760c5 --- /dev/null +++ b/Basic-Typing-Game/index.html @@ -0,0 +1,22 @@ + + + + + Typing game + + + +

Typing game!

+

Practice your typing skills with a quote from Sherlock Holmes. Click start to begin!

+

+

+

+

+ +
+ + +
+ + + \ No newline at end of file diff --git a/Basic-Typing-Game/script.js b/Basic-Typing-Game/script.js new file mode 100644 index 00000000..e00a94ce --- /dev/null +++ b/Basic-Typing-Game/script.js @@ -0,0 +1,104 @@ +// all of our quotes +const quotes = [ + 'When you have eliminated the impossible, whatever remains, however improbable, must be the truth.', + 'There is nothing more deceptive than an obvious fact.', + 'I ought to know by this time that when a fact appears to be opposed to a long train of deductions it invariably proves to be capable of bearing some other interpretation.', + 'I never make exceptions. An exception disproves the rule.', + 'What one man can invent another can discover.', + 'Nothing clears up a case so much as stating it to another person.', + 'Education never ends, Watson. It is a series of lessons, with the greatest for the last.', +]; +// store the list of words and the index of the word the player is currently typing +let words = []; +let wordIndex = 0; +// the starting time +let startTime = Date.now(); +// page elements +const quoteElement = document.getElementById('quote'); +const messageElement = document.getElementById('message'); +const typedValueElement = document.getElementById('typed-value'); +typedValueElement.disabled = true; + +// Load scores from local storage +let bestScore = localStorage.getItem("BestTime") || null; +let leastScore = localStorage.getItem("LeastTime") || null; + +if (bestScore) { + document.getElementById('best-score').innerText = `Best Score: ${bestScore} seconds`; +} +if (leastScore) { + document.getElementById('least-score').innerText = `Least Time: ${leastScore} seconds`; +} + +// at the end of script.js +document.getElementById('start').addEventListener('click', () => { + // get a quote + const quoteIndex = Math.floor(Math.random() * quotes.length); + const quote = quotes[quoteIndex]; + // Put the quote into an array of words + words = quote.split(' '); + // reset the word index for tracking + wordIndex = 0; + + // UI updates + // Create an array of span elements so we can set a class + const spanWords = words.map(word => `${word} `); + // Convert into string and set as innerHTML on quote display + quoteElement.innerHTML = spanWords.join(''); + // Highlight the first word + quoteElement.childNodes[0].className = 'highlight'; + // Clear any prior messages + messageElement.innerText = ''; + + // Setup the textbox + typedValueElement.value = ''; + typedValueElement.disabled = false; // Activate input + typedValueElement.focus(); + + // Start the timer + startTime = new Date().getTime(); +}); + +// at the end of script.js +typedValueElement.addEventListener('input', () => { + // Get the current word + const currentWord = words[wordIndex]; + // get the current value + const typedValue = typedValueElement.value; + + if (typedValue === currentWord && wordIndex === words.length - 1) { + // end of sentence + const elapsedTime = (new Date().getTime() - startTime) / 1000; + const message = `CONGRATULATIONS! You finished in ${elapsedTime} seconds.`; + messageElement.innerText = message; + typedValueElement.disabled = true; + + // Check and update least and best scores + if (!bestScore || elapsedTime < parseFloat(bestScore)) { + bestScore = elapsedTime; + localStorage.setItem("BestTime", bestScore); + document.getElementById('best-score').innerText = `Best Score: ${bestScore} seconds`; + } + + if (!leastScore || elapsedTime > parseFloat(leastScore)) { + leastScore = elapsedTime; + localStorage.setItem("LeastTime", leastScore); + document.getElementById('least-score').innerText = `Least Time: ${leastScore} seconds`; + } + + } else if (typedValue.endsWith(' ') && typedValue.trim() === currentWord) { + // end of word + typedValueElement.value = ''; + wordIndex++; + // reset the class name for all elements in quote + for (const wordElement of quoteElement.childNodes) { + wordElement.className = ''; + } + // highlight the new word + quoteElement.childNodes[wordIndex].className = 'highlight'; + } else if (currentWord.startsWith(typedValue)) { + typedValueElement.className = ''; // Correct typing + } else { + typedValueElement.className = 'error'; // Error state + } +}); diff --git a/Basic-Typing-Game/style.css b/Basic-Typing-Game/style.css new file mode 100644 index 00000000..744b6e73 --- /dev/null +++ b/Basic-Typing-Game/style.css @@ -0,0 +1,72 @@ +/* inside style.css */ +/* inside style.css */ +body { + font-family: Arial, sans-serif; + background-color: #f0f0f0; + color: #333; + margin: 0; + padding: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; +} + +h1 { + color: #4CAF50; + margin-bottom: 20px; +} + +p { + font-size: 18px; + margin: 10px 0; +} + +#quote { + font-size: 24px; + font-style: italic; + margin-bottom: 20px; +} + +#message, #best-score { + font-size: 20px; + margin: 10px 0; +} + +div { + display: flex; + flex-direction: column; + align-items: center; +} + +input[type="text"] { + padding: 10px; + font-size: 18px; + border: 2px solid #ccc; + border-radius: 5px; + margin-bottom: 10px; + width: 300px; +} + +button { + padding: 10px 20px; + font-size: 18px; + color: white; + background-color: #4CAF50; + border: none; + border-radius: 5px; + cursor: pointer; +} + +button:hover { + background-color: #45a049; +} +.highlight { + background-color: yellow; + } + +.error { + background-color: lightcoral; + border: red; +} \ No newline at end of file