Skip to content
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
Binary file added assets/simon-says-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions en/beginner-projects/simon-says.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# 🎮 Simon Says Game

![Simon Says Preview](../../assets/simon-says-preview.png)

## Description

A memory game where players repeat sequences of colored buttons. Each round adds a new color to the sequence, and the player must remember and repeat it correctly to advance levels.

## Features

- Start button to begin the game
- Colored buttons (Green, Red, Yellow, Blue) that flash
- Adds a new color each level
- Level tracking and Game Over message

## Concepts Practiced

- DOM manipulation
- Event listeners
- Async functions and Promises
- Game logic and sequence handling
- CSS animations and visual feedback

## Bonus Challenge

- Show the **score** after the game is over (score = number of levels completed).
- Add **sound effects** for each button click.
- Add **glowing animation** for each button to make the game more interactive.

## Live Demo

<div align="center">
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The align attribute is obsolete in HTML5. Prefer a style-based approach, e.g., <div style="text-align:center"> or a CSS class.

Suggested change
<div align="center">
<div style="text-align:center;">

Copilot uses AI. Check for mistakes.
<iframe src="https://codesandbox.io/p/sandbox/frosty-nobel-849xrz"
style="width:100%; height: 500px; border:0; border-radius: 4px; overflow:hidden;"
title="simon-says-game"
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add loading="lazy" to the iframe to defer loading the demo until it scrolls into view, improving page load performance.

Suggested change
title="simon-says-game"
title="simon-says-game" loading="lazy"

Copilot uses AI. Check for mistakes.
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
Comment on lines +33 to +37
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iframe src points to a CodeSandbox editor URL (/p/sandbox/...) which is typically blocked from embedding; use the embed endpoint instead. Replace with https://codesandbox.io/embed/frosty-nobel-849xrz (optionally add query params like ?fontsize=14&hidenavigation=1&theme=light).

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +37
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iframe permissions and sandbox flags are overly broad for a simple game embed; apply the principle of least privilege. Suggest narrowing to only what’s needed, e.g., allow="fullscreen" and sandbox="allow-scripts allow-same-origin".

Suggested change
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
allow="fullscreen"
sandbox="allow-scripts allow-same-origin"

Copilot uses AI. Check for mistakes.
></iframe>
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provide a fallback link for users/browsers that block iframes. Add a link just below the iframe, e.g.,

<a href="https://codesandbox.io/s/frosty-nobel-849xrz\" target="_blank" rel="noopener noreferrer">Open live demo on CodeSandbox

.

Suggested change
></iframe>
></iframe>
<p><a href="https://codesandbox.io/s/frosty-nobel-849xrz" target="_blank" rel="noopener noreferrer">Open live demo on CodeSandbox</a></p>

Copilot uses AI. Check for mistakes.
</div>
36 changes: 36 additions & 0 deletions examples/Simon-Says/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Simon Says — Memory Game 🎮

This is a fun and interactive **Simon Says** memory game built using **HTML, CSS, and modern JavaScript (ES Modules)**.
Players must observe and repeat an increasingly long sequence of colors — testing their memory and focus!

## Features

- 🎨 **Colorful animated buttons** for each level.
- 🧠 **Progressive difficulty** — sequence length increases with each correct round.
- ❌ **Game over feedback** with flashing animations.
- 🔁 **Restart option** to play again after losing.
- ⚡ Built using **plain HTML, CSS, and JS (no libraries or frameworks)**.

## Files

- `index.html` — main markup and game layout
- `styles.css` — visual design, colors, and animations
- `index.mjs` — core game logic using ES modules (sequence generation, user input, and level progression)

## How to Play

1. Open `index.html` in your browser (Chrome, Edge, or Firefox recommended).
2. Press 'Start Game' button to start the game.
3. Watch the color sequence shown by the game.
4. Repeat the sequence by clicking the color buttons in the same order.
5. Each level adds one more color to the sequence — try to remember them all!
6. If you click the wrong color, the game ends — press any key to restart.

## Notes

- The game uses **JavaScript timing functions** to display sequences with smooth delays.
- Fully responsive — works well on both **desktop and mobile** browsers.

---

✨ **Enjoy testing your memory skills with Simon Says!**
22 changes: 22 additions & 0 deletions examples/Simon-Says/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simon Says Game</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Simon Says Game</h1>
<div class="game-container">
<div class="color-button" id="green"></div>
<div class="color-button" id="red"></div>
<div class="color-button" id="yellow"></div>
<div class="color-button" id="blue"></div>
</div>
<button id="start-btn">Start Game</button>
<p id="message"></p>

<script type="module" src="index.mjs"></script>
</body>
</html>
71 changes: 71 additions & 0 deletions examples/Simon-Says/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const buttons = Array.from(document.querySelectorAll(".color-button"));
const startBtn = document.getElementById("start-btn");
const message = document.getElementById("message");

let sequence = [];
let playerSequence = [];
let level = 0;
let acceptingInput = false;

// Flash a button visually
function flashButton(button) {
return new Promise((resolve) => {
button.classList.add("active");
setTimeout(() => {
button.classList.remove("active");
setTimeout(resolve, 200);
}, 500);
});
}

// Start next round: add new button and flash only it
async function nextRound() {
acceptingInput = false;
const newButton = buttons[Math.floor(Math.random() * buttons.length)];
sequence.push(newButton);
await flashButton(newButton); // flash only the new button
playerSequence = []; // reset player input for new round
acceptingInput = true;
message.textContent = `Level ${level}: Repeat the sequence`;
}

// Check player input
function checkPlayerInput() {
const currentIndex = playerSequence.length - 1;
if (playerSequence[currentIndex] !== sequence[currentIndex]) {
message.textContent = `Game Over! You reached level ${level}`;
startBtn.disabled = false;
sequence = [];
playerSequence = [];
level = 0;
acceptingInput = false;
return false;
}

if (playerSequence.length === sequence.length) {
level++;
message.textContent = `Level ${level} completed!`;
setTimeout(nextRound, 800); // small delay before next round
}
return true;
}

// Button click handler
buttons.forEach((btn) => {
btn.addEventListener("click", async () => {
if (!acceptingInput) return;
playerSequence.push(btn);
await flashButton(btn);
checkPlayerInput();
});
});

// Start button
startBtn.addEventListener("click", () => {
level = 1;
message.textContent = `Level ${level}: Repeat the sequence`;
sequence = [];
playerSequence = [];
nextRound();
startBtn.disabled = true;
});
50 changes: 50 additions & 0 deletions examples/Simon-Says/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
body {
font-family: Arial, sans-serif;
text-align: center;
background: #222;
color: #fff;
}

h1 {
margin-top: 20px;
}

.game-container {
display: grid;
grid-template-columns: repeat(2, 150px);
grid-gap: 20px;
justify-content: center;
margin: 40px auto;
}

.color-button {
width: 150px;
height: 150px;
border-radius: 15px;
cursor: pointer;
transition: transform 0.1s, opacity 0.2s;
}

#green { background: #0f0; }
#red { background: #f00; }
#yellow { background: #ff0; }
#blue { background: #00f; }

.color-button.active {
transform: scale(1.1);
opacity: 0.7;
}

#start-btn {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
margin-top: 20px;
}

#message {
margin-top: 20px;
font-size: 18px;
}