diff --git a/projects/number-guessing-game/index.html b/projects/number-guessing-game/index.html
index 3dcd566..9279c98 100644
--- a/projects/number-guessing-game/index.html
+++ b/projects/number-guessing-game/index.html
@@ -1,24 +1,30 @@
-
-
I'm thinking of a number between 1 and 100. Can you guess it?
-
-
-
+
+
+
Number Guessing Game
+
I'm thinking of a number between 1 and 100. Can you guess it?
+
+
+
+
+
+
+
+
Attempts: 0
+
+
+
-
-
Attempts: 0
-
-
-
+
\ No newline at end of file
diff --git a/projects/number-guessing-game/main.js b/projects/number-guessing-game/main.js
index 21865d6..ece2ffc 100644
--- a/projects/number-guessing-game/main.js
+++ b/projects/number-guessing-game/main.js
@@ -1,92 +1,88 @@
-// Utility to generate a random integer in [min, max]
-function generateRandomInteger(min, max) {
- const minCeil = Math.ceil(min);
- const maxFloor = Math.floor(max);
- return Math.floor(Math.random() * (maxFloor - minCeil + 1)) + minCeil;
-}
+// Get references to the HTML elements
+const guessInput = document.getElementById('guessInput');
+const guessButton = document.getElementById('guessButton');
+const resetButton = document.getElementById('resetButton');
+const message = document.getElementById('message');
+const attemptsDisplay = document.getElementById('attempts');
-function initNumberGuessingGame() {
- const input = document.getElementById('guess-input');
- const guessBtn = document.getElementById('guess-btn');
- const feedback = document.getElementById('feedback');
- const attemptsText = document.getElementById('attempts');
- const attemptCount = document.getElementById('attempt-count');
- const restartBtn = document.getElementById('restart-btn');
+// Game variables
+let randomNumber;
+let attempts;
+const MIN_NUM = 1;
+const MAX_NUM = 100;
- const MIN = 1;
- const MAX = 100;
+// Function to start a new game or reset the current one
+function newGame() {
+ // 1. Generate a new random number
+ randomNumber = Math.floor(Math.random() * (MAX_NUM - MIN_NUM + 1)) + MIN_NUM;
+ console.log(`The secret number is: ${randomNumber}`); // For testing purposes
- let targetNumber = generateRandomInteger(MIN, MAX);
- let attempts = 0;
- let gameOver = false;
+ // 2. Reset the number of attempts
+ attempts = 0;
+ attemptsDisplay.textContent = `Attempts: ${attempts}`;
- function setFeedback(message, type) {
- feedback.textContent = message;
- feedback.dataset.type = type || '';
- }
+ // 3. Clear messages and input field
+ message.textContent = '';
+ guessInput.value = '';
- function setGameOver(over) {
- gameOver = over;
- input.disabled = over;
- guessBtn.disabled = over;
- if (over) {
- input.blur();
- }
- }
+ // 4. Re-enable input and guess button, hide reset button
+ guessInput.disabled = false;
+ guessButton.disabled = false;
+ resetButton.style.display = 'none'; // Hide the reset button
+ message.style.color = '#333'; // Default text color
+}
- function validateGuess(value) {
- if (value === '') return { ok: false, msg: 'Please enter a number.' };
- const num = Number(value);
- if (!Number.isFinite(num)) return { ok: false, msg: 'That is not a valid number.' };
- if (!Number.isInteger(num)) return { ok: false, msg: 'Please enter a whole number.' };
- if (num < MIN || num > MAX) return { ok: false, msg: `Enter a number between ${MIN} and ${MAX}.` };
- return { ok: true, value: num };
- }
+// Function to handle the user's guess
+function checkGuess() {
+ const userGuess = parseInt(guessInput.value);
- function handleGuess() {
- if (gameOver) return;
- const { ok, msg, value } = validateGuess(input.value.trim());
- if (!ok) {
- setFeedback(msg, 'error');
- return;
+ // Validate the input
+ if (isNaN(userGuess) || userGuess < MIN_NUM || userGuess > MAX_NUM) {
+ message.textContent = `Please enter a valid number between ${MIN_NUM} and ${MAX_NUM}.`;
+ message.style.color = 'orange'; // Will be mapped to var(--warning-color) by CSS
+ return;
}
- attempts += 1;
- attemptCount.textContent = String(attempts);
- if (value === targetNumber) {
- setFeedback(`Correct! The number was ${targetNumber}.`, 'success');
- setGameOver(true);
- return;
- }
- if (value < targetNumber) {
- setFeedback('Too low. Try a higher number.', 'low');
+ // Increment attempts
+ attempts++;
+ attemptsDisplay.textContent = `Attempts: ${attempts}`;
+
+ // Compare the guess and provide feedback
+ if (userGuess < randomNumber) {
+ message.textContent = 'Too Low! Try again.';
+ message.style.color = '#3498db'; // Will be mapped by CSS
+ } else if (userGuess > randomNumber) {
+ message.textContent = 'Too High! Try again.';
+ message.style.color = '#e74c3c'; // Will be mapped to var(--error-color) by CSS
} else {
- setFeedback('Too high. Try a lower number.', 'high');
+ message.textContent = `Correct! You guessed the number ${randomNumber} in ${attempts} attempts! 🎉`;
+ message.style.color = '#2ecc71'; // Will be mapped to var(--success-color) by CSS
+ endGame();
}
- input.select();
- }
- function restartGame() {
- targetNumber = generateRandomInteger(MIN, MAX);
- attempts = 0;
- attemptCount.textContent = '0';
- setFeedback('', '');
- input.value = '';
- setGameOver(false);
- input.focus();
- }
+ // Clear the input for the next guess
+ guessInput.value = '';
+ guessInput.focus();
+}
+
+// Function to end the game when the number is guessed correctly
+function endGame() {
+ guessInput.disabled = true;
+ guessButton.disabled = true;
+ resetButton.style.display = 'inline-block'; // Show the reset button
+}
+
+// Event Listeners
+guessButton.addEventListener('click', checkGuess);
+resetButton.addEventListener('click', newGame);
- guessBtn.addEventListener('click', handleGuess);
- input.addEventListener('keydown', function onKeyDown(event) {
- if (event.key === 'Enter') {
- handleGuess();
+// Allow pressing "Enter" to submit a guess
+guessInput.addEventListener('keydown', (event) => {
+ if (event.key === 'Enter' && !guessButton.disabled) { // Ensure button is not disabled
+ checkGuess();
}
- });
- restartBtn.addEventListener('click', restartGame);
+});
- // Init state
- attemptsText.hidden = false;
- setFeedback('', '');
-}
-window.addEventListener('DOMContentLoaded', initNumberGuessingGame);
\ No newline at end of file
+// Initialize the game when the page loads
+newGame();
\ No newline at end of file
diff --git a/projects/number-guessing-game/style.css b/projects/number-guessing-game/style.css
new file mode 100644
index 0000000..bd0ef51
--- /dev/null
+++ b/projects/number-guessing-game/style.css
@@ -0,0 +1,200 @@
+/* Custom properties for easy theme management */
+:root {
+ --primary-color: #6a0572; /* Deep purple */
+ --secondary-color: #8e2de2; /* Lighter purple */
+ --accent-color: #e0b4ff; /* Light purple for highlights */
+ --text-dark: #333333;
+ --text-light: #f4f4f4;
+ --background-light: #f0f2f5; /* Light grey for body background */
+ --card-background: #ffffff;
+ --success-color: #28a745;
+ --error-color: #dc3545;
+ --warning-color: #ffc107;
+ --border-color: #dddddd;
+ --box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
+ --border-radius-card: 15px;
+ --border-radius-elements: 8px;
+}
+
+body {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+ margin: 0;
+ background: linear-gradient(135deg, var(--background-light) 0%, var(--accent-color) 100%); /* Subtle gradient */
+ font-family: 'Poppins', sans-serif; /* Use Poppins for a modern look */
+ color: var(--text-dark);
+ line-height: 1.6;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.card {
+ background: var(--card-background);
+ padding: 2.5rem 2rem; /* Increased padding */
+ border-radius: var(--border-radius-card);
+ box-shadow: var(--box-shadow);
+ text-align: center;
+ max-width: 450px; /* Slightly wider card */
+ width: 90%;
+ position: relative;
+ overflow: hidden; /* For potential background elements */
+ animation: fadeIn 0.8s ease-out; /* Add a subtle fade-in animation */
+}
+
+/* Header */
+h1 {
+ font-family: 'Poppins', sans-serif;
+ font-weight: 700;
+ color: var(--primary-color);
+ margin-bottom: 0.8rem;
+ font-size: 2.2rem; /* Larger heading */
+ letter-spacing: -0.5px;
+}
+
+.description {
+ font-family: 'Roboto', sans-serif;
+ font-size: 1.05rem;
+ color: #555;
+ margin-bottom: 2rem; /* More space below description */
+}
+
+/* Input Group */
+.input-group {
+ display: flex;
+ gap: 12px; /* Slightly increased gap */
+ margin: 2rem 0;
+}
+
+#guessInput {
+ flex-grow: 1;
+ padding: 0.9rem 1.2rem; /* More padding */
+ border: 2px solid var(--border-color); /* Thicker border */
+ border-radius: var(--border-radius-elements);
+ font-size: 1.1rem; /* Larger font size */
+ font-family: 'Roboto', sans-serif;
+ color: var(--text-dark);
+ transition: border-color 0.3s ease, box-shadow 0.3s ease; /* Smooth transitions */
+ -webkit-appearance: none; /* Remove default number input styling */
+ -moz-appearance: textfield; /* Firefox number input styling */
+}
+
+#guessInput:focus {
+ outline: none;
+ border-color: var(--primary-color); /* Highlight on focus */
+ box-shadow: 0 0 0 3px rgba(106, 5, 114, 0.2); /* Subtle glow */
+}
+
+/* Buttons */
+.btn {
+ padding: 0.9rem 1.5rem;
+ border: none;
+ border-radius: var(--border-radius-elements);
+ font-size: 1.05rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: background-color 0.3s ease, transform 0.2s ease, box-shadow 0.3s ease;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.primary-btn {
+ background-color: var(--primary-color);
+ color: var(--text-light);
+ box-shadow: 0 4px 15px rgba(106, 5, 114, 0.3);
+}
+
+.primary-btn:hover {
+ background-color: var(--secondary-color);
+ transform: translateY(-2px); /* Lift effect */
+ box-shadow: 0 6px 20px rgba(142, 45, 226, 0.4);
+}
+
+.primary-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 2px 10px rgba(106, 5, 114, 0.2);
+}
+
+.secondary-btn {
+ background-color: #e9e9e9;
+ color: var(--primary-color);
+ border: 1px solid var(--primary-color);
+}
+
+.secondary-btn:hover {
+ background-color: var(--accent-color);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
+}
+
+.secondary-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+}
+
+.btn:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+ transform: none;
+ box-shadow: none;
+}
+
+/* Messages and Attempts */
+.message {
+ min-height: 28px; /* Ensure consistent height */
+ font-weight: 600;
+ font-size: 1.15rem; /* Slightly larger message */
+ margin-bottom: 1.5rem;
+ transition: color 0.3s ease;
+}
+
+.message[style*="color: rgb(46, 204, 113)"] { /* Correct! - Green */
+ color: var(--success-color) !important;
+}
+.message[style*="color: rgb(52, 152, 219)"] { /* Too Low! - Blue */
+ color: #3498db !important; /* Keeping original for "too low" as a different shade */
+}
+.message[style*="color: rgb(231, 76, 60)"] { /* Too High! - Red */
+ color: var(--error-color) !important;
+}
+.message[style*="color: orange"] { /* Validation error - Orange */
+ color: var(--warning-color) !important;
+}
+
+
+.attempts {
+ font-family: 'Roboto', sans-serif;
+ color: #777;
+ margin-bottom: 2rem; /* More space below attempts */
+ font-size: 1rem;
+}
+
+.reset-btn {
+ display: none; /* Initially hidden */
+ margin-top: 1rem;
+}
+
+/* Animations */
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+/* Ensure number input arrows are hidden for a cleaner look */
+/* For Chrome, Safari, Edge, Opera */
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+/* For Firefox */
+input[type=number] {
+ -moz-appearance: textfield;
+}
\ No newline at end of file
diff --git a/projects/number-guessing-game/styles.css b/projects/number-guessing-game/styles.css
deleted file mode 100644
index c45c7ef..0000000
--- a/projects/number-guessing-game/styles.css
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Basic reset */
-/* Page-level layout is handled by assets/styles.css; only tweak specifics here */
-html, body { height: 100%; }
-body {
- display: flex;
- flex-direction: column;
- align-items: center;
- background: var(--bg);
- color: var(--text);
-}
-
-h1 { margin: 24px 0 12px; font-size: 24px; font-weight: 700; color: var(--text); }
-
-#game-container {
- width: 100%;
- max-width: 420px;
- background: var(--card);
- border: 1px solid #262631;
- border-radius: 12px;
- padding: 20px;
- box-shadow: 0 0 0 1px rgba(255,255,255,0.02) inset;
-}
-
-#instructions { margin: 0 0 12px; color: var(--muted); }
-
-#controls {
- display: flex;
- gap: 8px;
-}
-
-#guess-input {
- flex: 1 1 auto;
- padding: 10px 12px;
- border: 1px solid #2a2a33;
- border-radius: 8px;
- font-size: 14px;
- outline: none;
- background: #0e0e13;
- color: var(--text);
-}
-#guess-input::placeholder { color: var(--muted); }
-#guess-input:focus { border-color: #93c5fd; box-shadow: 0 0 0 3px rgba(147,197,253,0.2); }
-
-button {
- padding: 10px 14px;
- border-radius: 8px;
- border: 1px solid #1e3a8a;
- background: linear-gradient(135deg, var(--accent), var(--accent-2));
- color: #0b1020;
- font-weight: 600;
- cursor: pointer;
-}
-button:hover { filter: brightness(1.05); }
-button:disabled { background: #1f1f27; border-color: #2a2a33; color: var(--muted); cursor: not-allowed; }
-
-#feedback { min-height: 22px; margin: 12px 0 8px; }
-#feedback[data-type="error"] { color: #f87171; }
-#feedback[data-type="low"], #feedback[data-type="high"] { color: #fbbf24; }
-#feedback[data-type="success"] { color: var(--accent); }
-
-#attempts { margin: 0 0 12px; color: var(--muted); }
-
-#restart-btn {
- width: 100%;
- background: linear-gradient(135deg, var(--accent), var(--accent-2));
- border-color: #1e3a8a;
-}
-#restart-btn:hover { filter: brightness(1.05); }
\ No newline at end of file