-
Notifications
You must be signed in to change notification settings - Fork 184
Create an Example Solution for a Rock Paper Scissors Game #323 #333
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
Create an Example Solution for a Rock Paper Scissors Game #323 #333
Conversation
|
@suryaprakash0010 is attempting to deploy a commit to the Suman Kunwar's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds a complete Rock-Paper-Scissors example demonstrating DOM manipulation, event handling, animations, and score tracking.
- New example app with HTML UI, responsive CSS, and JavaScript game logic
- Includes round history, keyboard shortcuts, and reset functionality
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| examples/Rock-Paper-Scissors/index.html | Game markup, controls, and containers for scores, results, and history |
| examples/Rock-Paper-Scissors/styles.css | Visual design, animations, responsiveness |
| examples/Rock-Paper-Scissors/script.js | Core game class, event wiring, scoring, history, and rendering |
| examples/Rock-Paper-Scissors/README.md | Documentation for features, concepts, and usage |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| // Initialize the game when DOM is loaded | ||
| document.addEventListener('DOMContentLoaded', () => { | ||
| const game = new RockPaperScissorsGame(); | ||
|
|
||
| // Add keyboard support for accessibility | ||
| document.addEventListener('keydown', (e) => { | ||
| if (e.key.toLowerCase() === 'r') { | ||
| game.playRound('rock'); | ||
| } else if (e.key.toLowerCase() === 'p') { | ||
| game.playRound('paper'); | ||
| } else if (e.key.toLowerCase() === 's') { | ||
| game.playRound('scissors'); | ||
| } | ||
| }); | ||
|
|
||
| // Add sound effects (optional) | ||
| const playSound = (type) => { | ||
| // You can add sound files in the same directory and uncomment this | ||
| // const audio = new Audio(`${type}.mp3`); | ||
| // audio.volume = 0.3; | ||
| // audio.play().catch(e => console.log('Audio play failed:', e)); | ||
| }; | ||
|
|
||
| // Export for potential testing | ||
| if (typeof module !== 'undefined' && module.exports) { | ||
| module.exports = RockPaperScissorsGame; | ||
| } | ||
| }); |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module.exports is placed inside the DOMContentLoaded handler, so it never runs in a Node/test environment where the DOM is not present. Move the export outside the event listener to make the class importable in tests: place if (typeof module !== 'undefined' && module.exports) { module.exports = RockPaperScissorsGame; } right after the class definition; keep DOM initialization inside the listener.
| <h3 id="playerChoiceText">Make your move!</h3> | ||
| </div> | ||
|
|
||
| <div class="result-display" id="gameResult"> |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result area updates dynamically but lacks an ARIA live region, so screen readers may not announce round outcomes. Add role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" to the container to announce result changes: <div class=\"result-display\" id=\"gameResult\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">.
| <div class="result-display" id="gameResult"> | |
| <div class="result-display" id="gameResult" role="status" aria-live="polite" aria-atomic="true"> |
| <button class="choice-btn rock" id="rockBtn" data-choice="rock"> | ||
| <span class="emoji">🪨</span> | ||
| <span class="label">Rock</span> | ||
| </button> | ||
| <button class="choice-btn paper" id="paperBtn" data-choice="paper"> | ||
| <span class="emoji">📄</span> | ||
| <span class="label">Paper</span> | ||
| </button> | ||
| <button class="choice-btn scissors" id="scissorsBtn" data-choice="scissors"> | ||
| <span class="emoji">✂️</span> | ||
| <span class="label">Scissors</span> | ||
| </button> | ||
| </div> | ||
|
|
||
| <button class="reset-btn" id="resetBtn"> |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Buttons default to type="submit" in some contexts; explicitly set type=\"button\" to avoid unintended form submissions and add discoverability for shortcuts with aria-keyshortcuts on choice buttons. Example: <button type=\"button\" class=\"choice-btn rock\" id=\"rockBtn\" data-choice=\"rock\" aria-keyshortcuts=\"R\">...; apply similarly for Paper (P), Scissors (S), and the Reset button.
| <button class="choice-btn rock" id="rockBtn" data-choice="rock"> | |
| <span class="emoji">🪨</span> | |
| <span class="label">Rock</span> | |
| </button> | |
| <button class="choice-btn paper" id="paperBtn" data-choice="paper"> | |
| <span class="emoji">📄</span> | |
| <span class="label">Paper</span> | |
| </button> | |
| <button class="choice-btn scissors" id="scissorsBtn" data-choice="scissors"> | |
| <span class="emoji">✂️</span> | |
| <span class="label">Scissors</span> | |
| </button> | |
| </div> | |
| <button class="reset-btn" id="resetBtn"> | |
| <button type="button" class="choice-btn rock" id="rockBtn" data-choice="rock" aria-keyshortcuts="R"> | |
| <span class="emoji">🪨</span> | |
| <span class="label">Rock</span> | |
| </button> | |
| <button type="button" class="choice-btn paper" id="paperBtn" data-choice="paper" aria-keyshortcuts="P"> | |
| <span class="emoji">📄</span> | |
| <span class="label">Paper</span> | |
| </button> | |
| <button type="button" class="choice-btn scissors" id="scissorsBtn" data-choice="scissors" aria-keyshortcuts="S"> | |
| <span class="emoji">✂️</span> | |
| <span class="label">Scissors</span> | |
| </button> | |
| </div> | |
| <button type="button" class="reset-btn" id="resetBtn" aria-keyshortcuts="X"> |
| .game-container { | ||
| background: rgba(255, 255, 255, 0.95); | ||
| backdrop-filter: blur(20px); | ||
| border-radius: 20px; | ||
| padding: 2rem; | ||
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); | ||
| max-width: 600px; | ||
| width: 100%; | ||
| border: 1px solid rgba(255, 255, 255, 0.2); |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Safari requires the -webkit-backdrop-filter prefix; add it alongside backdrop-filter for broader support: -webkit-backdrop-filter: blur(20px);.
| this.rockBtn.classList.remove('selected'); | ||
| this.paperBtn.classList.remove('selected'); | ||
| this.scissorsBtn.classList.remove('selected'); | ||
|
|
||
| const playerBtn = document.querySelector(`[data-choice="${playerChoice}"]`); | ||
| if (playerBtn) { | ||
| playerBtn.classList.add('selected'); | ||
| } |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid hard-coding individual button references; remove the selected class generically to simplify maintenance: document.querySelectorAll('.choice-btn.selected').forEach(el => el.classList.remove('selected')); then add the class to the chosen button.
| result: result | ||
| }; | ||
|
|
||
| this.gameHistory.unshift(historyItem); |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gameHistory grows unbounded even though only the last 10 entries are displayed. Cap the array to 10 entries after unshifting to avoid unnecessary memory growth: this.gameHistory.unshift(historyItem); if (this.gameHistory.length > 10) this.gameHistory.length = 10;.
| this.gameHistory.unshift(historyItem); | |
| this.gameHistory.unshift(historyItem); | |
| if (this.gameHistory.length > 10) this.gameHistory.length = 10; |
| /* Animations */ | ||
| @keyframes shake { | ||
| 0%, 100% { | ||
| transform: translateX(0); | ||
| } | ||
| 10%, 30%, 50%, 70%, 90% { | ||
| transform: translateX(-5px); | ||
| } | ||
| 20%, 40%, 60%, 80% { | ||
| transform: translateX(5px); | ||
| } | ||
| } | ||
|
|
||
| .shake { | ||
| animation: shake 0.5s ease-in-out; | ||
| } |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Respect users' reduced motion preferences by disabling or minimizing animations. Add a prefers-reduced-motion query (e.g., @media (prefers-reduced-motion: reduce) { .choice-btn.selected, .shake { animation: none !important; } .score { transition: none !important; } }).
|
|
||
| **CSS Concepts:** | ||
| - **Responsive Design** - Mobile-first approach with media queries | ||
| - **CSS Grid & Flexbox** - Layout management |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The styles use Flexbox but not CSS Grid; update this bullet to avoid confusion (e.g., change to 'Flexbox' only) or add a Grid example to align with the claim.
| - **CSS Grid & Flexbox** - Layout management | |
| - **Flexbox** - Layout management |
|
@suryaprakash0010 Great job. When you have time can you look into above suggestions? |
sumn2u
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.

Rock-Paper-Scissors Game Example (#323)
Description
Added a complete Rock-Paper-Scissors game example in the
examples/folder demonstrating DOM manipulation, event handling, animations, and game logic with score tracking.Features
Files Added
index.html— Game UI structure with buttons and score displaystyles.css— Responsive, animated design for better UXscript.js— Core game logic with event handling, animations, and scoringREADME.md— Game overview and setup instructionsConcepts Demonstrated
DOM Manipulation • Event Handling • Conditional Logic • Randomization • State Management • Animations • Responsive Design
**Ready for review! **