# Simon Says

> The challenge is to build a React-based Simon Says game that plays color sequences the user must replicate, advancing levels and detecting mistakes, with complete UI and test coverage provided.

- Difficulty: advanced
- Tags: useState, useEffect, customHook, game
- Estimated time: 90 minutes
- Tests: 15
- Requires subscription: yes

## Overview

The challenge is to build a React-based Simon Says game that plays color sequences the user must replicate, advancing levels and detecting mistakes, with complete UI and test coverage provided.


## Requirements

- Implement the "Start Game" button functionality:

  - Initialize the game state at level 0 (level 0 is hidden from UI).
  - Start the sequence with one random color (complete `getRandomColor`).
  - Disable the start button while playing.

- Implement sequence playback logic:

  - Before playing a new sequence, wait `SPEED * 3`.
  - Highlight each color visually and play its beep (using provided `colorSounds`).
  - For each color:
    - Keep active for `SPEED` duration.
    - After deactivation, wait `SPEED / 5` before next color.
  - Disable color buttons during playback.

- Handle user interaction:

  - Enable color buttons after playback.
  - Collect user clicks incrementally, playing respective beeps.
  - After each click, check correctness with `matchSequencePosition`.
  - On incorrect input, show `"FAIL!"` and disable further input.
  - On full correct sequence (`matchSequence`):
    - Increase level.
    - Add random color.
    - Replay sequence.

- Display game state:

  - Show current level (except 0).
  - Show `"FAIL!"` on failure.
  - Manage button enabled/disabled states accordingly.

- Use provided utilities:
  - Implement `getRandomColor`, `matchSequence`, and `matchSequencePosition`.
  - Use provided `playBeep()` and `wait(ms)` as-is.


## Notes

- Keep hooks and state logic simple and well scoped to improve maintainability and testability.
- Isolate game logic (sequence and validation) from UI rendering to enhance modularity.
- Prefer functional state updates (`setState(prev => ...)`) to avoid stale closures and bugs.
- Carefully manage asynchronous timing to synchronize animations and user inputs smoothly.
- Properly disable buttons during sequence playback to prevent unintended interactions.
- Provide clear and visible feedback messages for failures and game states to improve user experience.
- Use explicit and separate mappings for base background colors (`baseClassesMap`), active state background colors (`activeBgClassesMap`), and CSS `:active` pseudo-class backgrounds (`activePseudoClassesMap`).
- This approach ensures Tailwind generates all necessary classes and buttons respond visually both to React state changes (`activeColor`) and user interactions (`:active`).
- Avoid dynamic class interpolations inside pseudo-class variants like `active:${colorClass}`, as Tailwind cannot detect and process these during build time.


## Tests

01. renders the app title
02. renders the four color buttons
03. FAIL appears when wrong sequence is entered
04. level reaches 1 when sequence is correctly matched
05. level reaches 3 when sequence is correctly matched three times
06. FAIL appears if wrong color is entered at level 3
07. color buttons are disabled during sequence playback
08. Start Game button disables during gameplay and enables after fail
09. activeColor button has the correct active style during sequence playback
10. clicking color buttons before game starts does not affect sequence or level
11. game resets state correctly after fail and restart
12. level does not increase if sequence is partially matched and increases after full match
13. color sound functions are called when sequence plays and buttons clicked
14. color buttons have correct aria-labels
15. verifies exact delays for initial start and between colors


