From b2ad183bb46e6a4fb2e1b897af4f92047801e46d Mon Sep 17 00:00:00 2001 From: Jacobie Jackson Date: Sat, 1 Aug 2026 22:03:28 -0500 Subject: [PATCH] Add Binary Blitz educational game --- README.md | 5 +- content/contribution/binary-blitz/index.html | 42 ++++ content/contribution/binary-blitz/script.js | 158 +++++++++++++++ content/contribution/binary-blitz/style.css | 198 +++++++++++++++++++ 4 files changed, 401 insertions(+), 2 deletions(-) create mode 100644 content/contribution/binary-blitz/index.html create mode 100644 content/contribution/binary-blitz/script.js create mode 100644 content/contribution/binary-blitz/style.css diff --git a/README.md b/README.md index 1176ce0..7703790 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,8 @@ These projects are perfect for anyone who wants to: | 6️⃣ | ✂️ **Rock Paper Scissors** | Classic hand game with interactive UI and score tracking. | | 7️⃣ | 🔴🟡 **Connect 4** | Drop discs to connect four in a row before your opponent does. | | 8️⃣ | ⚡ **Typing Test** | Test your typing speed with small quotes. | -| 9️⃣ | 🧩 **Sudoku** | Fill the 9×9 grid so each row, column and 3×3 box contains digits 1–9. +| 9️⃣ | 🧩 **Sudoku** | Fill the 9×9 grid so each row, column and 3×3 box contains digits 1–9. | +| 🔟 | 💻 **Binary Blitz** | Convert binary numbers to decimal and build your score across ten rounds. | > Want to add your own game? Fork this repo and bring your creativity to life! 🎨 @@ -412,4 +413,4 @@ If you find this project helpful: - 🧑‍💻 Contribute your own game or fix bugs - 💬 Share this project with friends -> “Play. Code. Learn. Contribute.” — _Hacktoberfest 2025_ 💻🎉 \ No newline at end of file +> “Play. Code. Learn. Contribute.” — _Hacktoberfest 2025_ 💻🎉 diff --git a/content/contribution/binary-blitz/index.html b/content/contribution/binary-blitz/index.html new file mode 100644 index 0000000..8722b6d --- /dev/null +++ b/content/contribution/binary-blitz/index.html @@ -0,0 +1,42 @@ + + + + + + + Binary Blitz + + + +
+
+

Binary conversion challenge

+

Binary Blitz

+

Convert each binary number to decimal. Choose the correct answer before moving to the next round.

+
+ +
+

Question 1/10

+

Score 0

+
+ +
+

What is this binary number in decimal?

+

00000000

+
+ + +
+ + +
+ + + + diff --git a/content/contribution/binary-blitz/script.js b/content/contribution/binary-blitz/script.js new file mode 100644 index 0000000..f79c0d2 --- /dev/null +++ b/content/contribution/binary-blitz/script.js @@ -0,0 +1,158 @@ +const TOTAL_QUESTIONS = 10; +const MIN_VALUE = 1; +const MAX_VALUE = 255; + +const questionNumberElement = document.querySelector("#question-number"); +const questionTotalElement = document.querySelector("#question-total"); +const scoreElement = document.querySelector("#score"); +const binaryNumberElement = document.querySelector("#binary-number"); +const answerOptionsElement = document.querySelector("#answer-options"); +const feedbackElement = document.querySelector("#feedback"); +const nextButton = document.querySelector("#next-button"); +const restartButton = document.querySelector("#restart-button"); +const questionPanel = document.querySelector("#question-panel"); +const resultsPanel = document.querySelector("#results-panel"); +const finalScoreElement = document.querySelector("#final-score"); +const resultMessageElement = document.querySelector("#result-message"); + +let currentQuestion = 1; +let score = 0; +let correctAnswer = 0; +let usedValues = new Set(); + +function randomInteger(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +function getUniqueQuestionValue() { + let value; + + do { + value = randomInteger(MIN_VALUE, MAX_VALUE); + } while (usedValues.has(value)); + + usedValues.add(value); + return value; +} + +function shuffle(values) { + const shuffledValues = [...values]; + + for (let index = shuffledValues.length - 1; index > 0; index -= 1) { + const randomIndex = randomInteger(0, index); + [shuffledValues[index], shuffledValues[randomIndex]] = [ + shuffledValues[randomIndex], + shuffledValues[index] + ]; + } + + return shuffledValues; +} + +function createAnswerChoices(answer) { + const choices = new Set([answer]); + + while (choices.size < 4) { + const offset = randomInteger(-18, 18); + const possibleChoice = answer + offset; + + if (possibleChoice >= MIN_VALUE && possibleChoice <= MAX_VALUE) { + choices.add(possibleChoice); + } + } + + return shuffle([...choices]); +} + +function renderQuestion() { + correctAnswer = getUniqueQuestionValue(); + const binaryValue = correctAnswer.toString(2).padStart(8, "0"); + + questionNumberElement.textContent = currentQuestion; + scoreElement.textContent = score; + binaryNumberElement.textContent = binaryValue; + feedbackElement.textContent = ""; + feedbackElement.className = "feedback"; + nextButton.hidden = true; + answerOptionsElement.replaceChildren(); + + createAnswerChoices(correctAnswer).forEach((choice) => { + const button = document.createElement("button"); + button.type = "button"; + button.className = "answer-button"; + button.textContent = choice; + button.dataset.value = choice; + button.addEventListener("click", handleAnswer); + answerOptionsElement.append(button); + }); +} + +function handleAnswer(event) { + const selectedAnswer = Number(event.currentTarget.dataset.value); + const answerButtons = answerOptionsElement.querySelectorAll("button"); + + answerButtons.forEach((button) => { + button.disabled = true; + + if (Number(button.dataset.value) === correctAnswer) { + button.classList.add("correct"); + } + }); + + if (selectedAnswer === correctAnswer) { + score += 1; + scoreElement.textContent = score; + feedbackElement.textContent = "Correct! Nice conversion."; + feedbackElement.classList.add("correct-text"); + } else { + event.currentTarget.classList.add("incorrect"); + feedbackElement.textContent = `Not quite. The correct answer is ${correctAnswer}.`; + feedbackElement.classList.add("incorrect-text"); + } + + nextButton.textContent = currentQuestion === TOTAL_QUESTIONS + ? "See Results" + : "Next Question"; + nextButton.hidden = false; +} + +function showResults() { + questionPanel.hidden = true; + resultsPanel.hidden = false; + finalScoreElement.textContent = `${score} out of ${TOTAL_QUESTIONS}`; + + if (score === TOTAL_QUESTIONS) { + resultMessageElement.textContent = "Perfect score—you are a binary master!"; + } else if (score >= 7) { + resultMessageElement.textContent = "Great work! Your binary skills are strong."; + } else if (score >= 4) { + resultMessageElement.textContent = "Good start. A little more practice will sharpen your skills."; + } else { + resultMessageElement.textContent = "Keep practicing—you will get faster with every round."; + } +} + +function goToNextQuestion() { + if (currentQuestion === TOTAL_QUESTIONS) { + showResults(); + return; + } + + currentQuestion += 1; + renderQuestion(); +} + +function startGame() { + currentQuestion = 1; + score = 0; + usedValues = new Set(); + questionTotalElement.textContent = TOTAL_QUESTIONS; + questionPanel.hidden = false; + resultsPanel.hidden = true; + renderQuestion(); +} + +nextButton.addEventListener("click", goToNextQuestion); +restartButton.addEventListener("click", startGame); + +startGame(); diff --git a/content/contribution/binary-blitz/style.css b/content/contribution/binary-blitz/style.css new file mode 100644 index 0000000..20487a7 --- /dev/null +++ b/content/contribution/binary-blitz/style.css @@ -0,0 +1,198 @@ +:root { + color-scheme: dark; + --background: #07111f; + --panel: #101d31; + --panel-light: #182943; + --accent: #38f2a4; + --accent-dark: #0a5f44; + --text: #f4f8ff; + --muted: #a9bad2; + --correct: #54e59a; + --incorrect: #ff7b8b; +} + +* { + box-sizing: border-box; +} + +body { + min-height: 100vh; + margin: 0; + display: grid; + place-items: center; + padding: 24px; + font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + color: var(--text); + background: + radial-gradient(circle at 20% 20%, rgba(56, 242, 164, 0.14), transparent 30%), + linear-gradient(145deg, #06101c, var(--background)); +} + +.game-card { + width: min(100%, 680px); + padding: clamp(24px, 5vw, 48px); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 24px; + background: rgba(16, 29, 49, 0.94); + box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35); +} + +header { + text-align: center; +} + +.eyebrow { + margin: 0 0 6px; + color: var(--accent); + font-size: 0.78rem; + font-weight: 800; + letter-spacing: 0.13em; + text-transform: uppercase; +} + +h1, +h2 { + margin: 0; +} + +h1 { + font-size: clamp(2.25rem, 8vw, 4rem); + letter-spacing: -0.05em; +} + +.instructions, +.prompt, +#result-message { + color: var(--muted); + line-height: 1.55; +} + +.status-bar { + display: flex; + justify-content: space-between; + margin: 28px 0 20px; + padding: 12px 18px; + border-radius: 12px; + background: var(--panel-light); +} + +.status-bar p { + margin: 0; +} + +.question-panel, +.results-panel { + text-align: center; +} + +.binary-number { + margin: 10px 0 24px; + color: var(--accent); + font-family: "Courier New", monospace; + font-size: clamp(2rem, 9vw, 4.25rem); + font-weight: 800; + letter-spacing: 0.12em; + text-shadow: 0 0 24px rgba(56, 242, 164, 0.25); +} + +.answer-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; +} + +.answer-button, +.primary-button { + min-height: 52px; + border: 0; + border-radius: 12px; + font: inherit; + font-weight: 750; + cursor: pointer; + transition: transform 150ms ease, background 150ms ease; +} + +.answer-button { + color: var(--text); + background: var(--panel-light); +} + +.answer-button:hover:not(:disabled), +.answer-button:focus-visible { + transform: translateY(-2px); + background: #243b5d; + outline: 2px solid var(--accent); + outline-offset: 2px; +} + +.answer-button.correct { + color: #032719; + background: var(--correct); +} + +.answer-button.incorrect { + color: #3a0710; + background: var(--incorrect); +} + +.answer-button:disabled { + cursor: default; +} + +.feedback { + min-height: 28px; + margin: 18px 0 12px; + font-weight: 750; +} + +.feedback.correct-text { + color: var(--correct); +} + +.feedback.incorrect-text { + color: var(--incorrect); +} + +.primary-button { + padding: 0 24px; + color: #04251a; + background: var(--accent); +} + +.primary-button:hover, +.primary-button:focus-visible { + transform: translateY(-2px); + background: #76ffc5; + outline: 2px solid white; + outline-offset: 2px; +} + +.results-panel { + padding: 18px 0 6px; +} + +.result-icon { + margin: 0 0 10px; + font-size: 3rem; +} + +.final-score { + margin: 18px 0 4px; + color: var(--accent); + font-size: 2rem; + font-weight: 800; +} + +[hidden] { + display: none; +} + +@media (max-width: 520px) { + .answer-grid { + grid-template-columns: 1fr; + } + + .binary-number { + letter-spacing: 0.06em; + } +}