Dies ist ein sehr einfaches Reaktions-Spiel für 2 Personen, welches ich mir ausgedacht und dann mit einem Arduino und ein paar LEDs nachgebaut habe.
Ziel des Spiels ist schneller richtig zu reagieren als der gegnerische Spieler.
Sobald einer der beiden Spieler seinen Knopf drückt, beginnt das Spiel. Es wird in jeder
Spielrunde nach einer kurzen Zeit eine von zwei Spiel-LEDs aufleuchten. Leuchtet die blau
LED, so muss der Spieler versuchen, vor dem Gegner seinen Knopf zu drücken. Gelingt dies, so
erhält er einen Punkt. Leuchtet jedoch die rote LED darf kein Spieler drücken. Tut er dies
dennoch, so verliert er einen Punkt. Der Spieler, der zuerst 10 Punkte erreicht hat, gewinnt
das Spiel.
/**
* How to play:
* Goal of the game is to be faster than the other player.
* Each player has a button and a colored status LED. After one button is pressed the game begins.
* During the game there will be lit one of two LEDs: red or blue. If the blue LED is lit each player
* has to hit his button as fast as possible to get 1 point. If the red LED is lit then players must
* not press their buttons otherwise they lose 1 point. After one player has gathered 10 points he
* wins the game.
*/
#define PIN_LED_GOOD 8
#define PIN_LED_BAD 9
#define DEBOUNCE_TIME 300 // in ms
#define GAME_STATE_RUNNING 1
#define GAME_STATE_END 2
#define PLAYER_1 0
#define PLAYER_2 1
#define PLAYER_AMOUNT 2
#define WINNING_SCORE 10
#define MIN_CHANGE_TIME 1200 // in ms
#define MAX_CHANGE_TIME 2500 // in ms
const byte pinButtons[PLAYER_AMOUNT] = {2, 3};
const byte pinLeds[PLAYER_AMOUNT] = {10, 11};
byte gameState;
byte ledState;
byte score[PLAYER_AMOUNT];
unsigned long lastButtonClick[PLAYER_AMOUNT];
unsigned long lastLedChange;
unsigned long nextLedStateChange;
void setup()
{
randomSeed(analogRead(0));
pinMode(PIN_LED_GOOD, OUTPUT);
pinMode(PIN_LED_BAD, OUTPUT);
for (byte i=0; i<PLAYER_AMOUNT; i++) {
pinMode(pinLeds[i], OUTPUT);
pinMode(pinButtons[i], INPUT);
lastButtonClick[i] = millis();
}
gameState = GAME_STATE_END;
}
void loop()
{
switch(gameState)
{
case GAME_STATE_END:
if (isButtonPressed(PLAYER_1) || isButtonPressed(PLAYER_2)) {
initGame();
}
break;
case GAME_STATE_RUNNING:
toggleLedState();
if (isButtonPressed(PLAYER_1)) {
checkGameState(PLAYER_1);
}
if (isButtonPressed(PLAYER_2)) {
checkGameState(PLAYER_2);
}
break;
}
}
void initGame()
{
gameState = GAME_STATE_RUNNING;
setNextLedChange();
ledState = 0;
digitalWrite(PIN_LED_GOOD, LOW);
digitalWrite(PIN_LED_BAD, LOW);
for (byte i=0; i<PLAYER_AMOUNT; i++) {
digitalWrite(pinLeds[i], LOW);
lastButtonClick[i] = millis();
score[i] = 0;
}
}
void setNextLedChange()
{
lastLedChange = millis();
nextLedStateChange = random(MIN_CHANGE_TIME, MAX_CHANGE_TIME);
}
bool isButtonPressed(byte playerId)
{
if (millis() - lastButtonClick[playerId] < DEBOUNCE_TIME) {
return false;
}
if (digitalRead(pinButtons[playerId]) == HIGH) {
lastButtonClick[playerId] = millis();
return true;
}
return false;
}
void toggleLedState()
{
if (ledState == PIN_LED_GOOD) {
return;
}
if ((millis() - lastLedChange) < nextLedStateChange) {
return;
}
if (ledState == PIN_LED_BAD) {
digitalWrite(PIN_LED_BAD, LOW);
setNextLedChange();
}
if (random(0, 100) > 50) {
ledState = PIN_LED_GOOD;
digitalWrite(PIN_LED_GOOD, HIGH);
digitalWrite(PIN_LED_BAD, LOW);
} else {
ledState = PIN_LED_BAD;
digitalWrite(PIN_LED_GOOD, LOW);
digitalWrite(PIN_LED_BAD, HIGH);
setNextLedChange();
}
}
void checkGameState(byte playerId)
{
switch(ledState) {
case PIN_LED_GOOD:
digitalWrite(PIN_LED_GOOD, LOW);
score[playerId]++;
if (score[playerId] >= WINNING_SCORE) {
gameState = GAME_STATE_END;
for(byte i=0; i<10; i++) {
digitalWrite(pinLeds[playerId], HIGH);
delay(250);
digitalWrite(pinLeds[playerId], LOW);
delay(250);
}
return;
}
break;
case PIN_LED_BAD:
digitalWrite(PIN_LED_BAD, LOW);
if (score[playerId] > 0) {
score[playerId]--;
}
break;
}
ledState = 0;
setNextLedChange();
}
Errata: Die Polungen der LEDs sind auf dem obigen Schaltplan und auch der fertigen Platine leider alle vertauscht, dies bitte beim Nachbau beachten!
Hinweise zur Bestückung des PCBs:
Zum Ausprobieren habe ich die Schaltung dieses Spiels als Platinen-Layout erstellt (siehe oben) und dann bei JLCPCB, einem in China ansässigen Platinenhersteller, als 10er-Pack PCBs fertigen lassen. Nach ca. 14 Tagen hatte ich ein Paket mit den fertigen Platinen in der Post und das Resultat meiner ersten selbst gefertigten Platine ist zufrieden stellend: