Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new project of basic typing game #2354

Merged
merged 2 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Basic-Typing-Game/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<!-- inside index.html -->
<html>
<head>
<title>Typing game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Typing game!</h1>
<p>Practice your typing skills with a quote from Sherlock Holmes. Click <b>start</b> to begin!</p>
<p id="best-score"></p>
<p id="least-score"></p>
<p id="quote"></p> <!-- This will display our quote -->
<p id="message"></p> <!-- This will display any status messages -->

<div>
<input type="text" aria-label="current word" id="typed-value" /> <!-- The textbox for typing -->
<button type="button" id="start">Start</button> <!-- To start the game -->
</div>
<script src="script.js"></script>
</body>
</html>
104 changes: 104 additions & 0 deletions Basic-Typing-Game/script.js
Original file line number Diff line number Diff line change
@@ -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 => `<span>${word} </span>`);
// 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
}
});
72 changes: 72 additions & 0 deletions Basic-Typing-Game/style.css
Original file line number Diff line number Diff line change
@@ -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;
}
Loading