A two-player competitive reaction game built for the Arduino Uno, written in C++. Both the hardware wiring and firmware are fully custom-designed.
Two players each hold a button. The game counts down through three LED stages — Ready → Set → GO — with a randomized delay before the final signal. The first player to press their button after the white LEDs light up wins the round. A victory tone plays, the loser's LED stays on as a visual indicator, and the game automatically resets.
Green LED blinks → Yellow LED blinks → Red LED blinks → White LEDs ON → Players compete
"Ready..." "Set..." (random delay) "GO! Press!" Winner detected
| Stage | LED | Duration ON | Delay OFF | Audio |
|---|---|---|---|---|
| Ready | Green | 80 ms | 900 ms | 1 kHz tone |
| Set | Yellow | 80 ms | 900 ms | 1 kHz tone |
| GO (pre-signal) | Red | 80 ms | 900–4900 ms (random) | 1 kHz tone |
| Competition | White × 2 | Until button pressed | — | — |
| Victory | Winner's LED off | — | 1.5 s pause | 2 kHz, 500 ms |
| Component | Purpose | Pin |
|---|---|---|
| Arduino Uno | Microcontroller | — |
| Green LED | "Ready" indicator | 13 |
| Yellow LED | "Set" indicator | 12 |
| Red LED | "GO" indicator | 11 |
| White LED 1 | Player 1 indicator | 9 |
| White LED 2 | Player 2 indicator | 10 |
| Push Button 1 | Player 1 input | 7 |
| Push Button 2 | Player 2 input | 6 |
| Buzzer | Audio feedback | 8 |
No external resistors needed. Buttons use
INPUT_PULLUPto leverage the Arduino's built-in pull-up resistors, connecting directly between pin and ground.
randomSeed(analogRead(A0)) reads electrical noise from an unconnected analog pin at startup, seeding the RNG with a genuinely unpredictable value. The random delay window of 0.9 – 4.9 seconds makes it impossible for players to anticipate the GO signal.
The buzzer uses two distinct frequencies:
- 1 kHz — countdown phases (Ready, Set, GO)
- 2 kHz — victory signal
This gives players clear audio cues distinguishing game state from win condition.
A while (ButtonPressed == false) loop polls both buttons continuously. The first pin read as LOW immediately triggers the win sequence — no debounce delay, no polling lag, no possibility of a tie.
After every round, all state resets and the loop restarts with no manual intervention. The game runs indefinitely in Arduino's loop().
setup() → Configures 5 LED outputs, 2 INPUT_PULLUP buttons, seeds RNG
loop() → Green blink → Yellow blink → Red blink (random delay) →
White LEDs on → Wait for button → Victory feedback → Reset
Single state variable: ButtonPressed (boolean) is the only variable needed to manage the entire game state.
| Decision | Rationale |
|---|---|
| White LEDs for players | Neutral color — no bias toward either player |
INPUT_PULLUP for buttons |
Simpler wiring, fewer components, cleaner build |
| Buzzer on pin 8 | Standard PWM-capable pin for tone() generation |
| Hardcoded pin numbers | Appropriate for a single-purpose embedded program |
Blocking while loop during competition |
Correct behavior — nothing else should execute while waiting for a reaction |
- Wire components according to the pin table above.
- Open the
.inofile in the Arduino IDE. - Select Arduino Uno as the board and the correct COM port.
- Upload the sketch.
- Press the reset button on the board and start playing.
MIT License — feel free to fork, modify, and build your own version.