#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int BASE_MIN_HOLD_TIME = 1000;
const int MAX_HOLD_TIME = 5000;
const int PENALTY = 70;
const int ROUNDS = 5;
const int MAX_LEVEL = 3;
int score = 0;
int currentRound = 1;
int level = 1;
char targetKey;
unsigned long pressStartTime = 0;
unsigned long holdDuration = 0;
bool isWaitingForPress = false;
bool isHolding = false;
bool gameOver = false;
bool nextLevelPrompt = false;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(0));
startGame();
}
void loop() {
char key = keypad.getKey();
if (nextLevelPrompt) {
if (key == '#') {
level++;
Serial.println("\n=== Переход на уровень " + String(level) + " ===");
currentRound = 1;
gameOver = false;
nextLevelPrompt = false;
startNewRound();
return;
}
}
if (gameOver) {
if (key == '*') {
resetGame();
}
return;
}
KeyState state = keypad.getState();
unsigned long currentTime = millis();
if (isWaitingForPress && key) {
if (key == targetKey) {
pressStartTime = currentTime;
isHolding = true;
isWaitingForPress = false;
Serial.println("Верная клавиша! Удерживайте...");
} else {
score -= PENALTY;
Serial.println("Неверная клавиша! Штраф " + String(PENALTY) + " очков.");
Serial.println("Текущий счёт: " + String(score));
checkScoreLimit();
}
}
if (isHolding) {
if (state == PRESSED || state == HOLD) {
holdDuration = currentTime - pressStartTime;
if (holdDuration >= MAX_HOLD_TIME) {
Serial.println("\nВы достигли максимального времени удержания!");
endRound();
}
} else if (state == RELEASED) {
Serial.println("\nКлавиша отпущена.");
endRound();
}
}
if (currentRound > ROUNDS && !gameOver && !nextLevelPrompt) {
endGame();
}
}
void startGame() {
Serial.println("\n=== Игра: Реакция и сила нажатия ===");
Serial.println("Пройдите " + String(ROUNDS) + " раундов на уровне " + String(level) + "!");
score = 0;
currentRound = 1;
gameOver = false;
nextLevelPrompt = false;
startNewRound();
}
void startNewRound() {
Serial.println("\nРаунд " + String(currentRound) + " из " + String(ROUNDS) + " (Уровень " + String(level) + ")");
int row = random(0, ROWS);
int col = random(0, COLS);
targetKey = keys[row][col];
int minHoldTime = BASE_MIN_HOLD_TIME + (currentRound - 1) * 500 - level * 200;
Serial.println("Нажмите и удерживайте клавишу: " + String(targetKey));
Serial.println("Минимальное время удержания: " + String(minHoldTime / 1000.0) + " секунд");
Serial.println("Максимальное время удержания: " + String(MAX_HOLD_TIME / 1000.0) + " секунд");
isWaitingForPress = true;
isHolding = false;
holdDuration = 0;
}
void endRound() {
isHolding = false;
int minHoldTime = BASE_MIN_HOLD_TIME + (currentRound - 1) * 500 - level * 200;
int points = 0;
if (holdDuration < minHoldTime) {
points = -30 * level;
Serial.println("Удержание слишком короткое!");
} else if (holdDuration >= MAX_HOLD_TIME) {
points = 100 * level;
Serial.println("Достигнуто максимальное время удержания!");
} else {
points = map(holdDuration, minHoldTime, MAX_HOLD_TIME, 10, 100) * level;
}
score += points;
Serial.println("Итоговое время удержания: " + String(holdDuration / 1000.0, 1) + " секунд");
Serial.println("Очки за раунд: " + String(points));
Serial.println("Общий счёт: " + String(score));
checkScoreLimit();
currentRound++;
if (!gameOver && currentRound <= ROUNDS) {
startNewRound();
}
}
void endGame() {
if (level < MAX_LEVEL) {
Serial.println("\n=== Уровень пройден! ===");
Serial.println("Поздравляем! Вы набрали " + String(score) + " очков.");
Serial.println("Нажмите # для перехода на уровень " + String(level + 1));
nextLevelPrompt = true;
} else {
gameOver = true;
Serial.println("\n=== Игра завершена! ===");
Serial.println("Вы прошли все уровни! Ваш счёт: " + String(score));
Serial.println("Хотите сыграть ещё раз? Нажмите *.");
}
}
void resetGame() {
Serial.println("\nПерезапуск игры...");
level = 1;
startGame();
}
void checkScoreLimit() {
if (level == 1 && score <= -150) {
Serial.println("\n=== Игра завершена! ===");
Serial.println("Ваш счёт упал ниже -150 очков.");
Serial.println("К сожалению, вы проиграли!");
Serial.println("Хотите сыграть ещё раз? Нажмите *.");
gameOver = true;
} else if (level > 1 && score < 0) {
Serial.println("\n=== Игра завершена! ===");
Serial.println("Ваш счёт стал отрицательным.");
Serial.println("К сожалению, вы проиграли!");
Serial.println("Хотите сыграть ещё раз? Нажмите *.");
gameOver = true;
}
}