#include "SPI.h"
#include "Adafruit_ILI9341.h"
#include <Keypad.h>
// 定义ILI9341屏幕引脚
#define TFT_DC 2
#define TFT_CS 3
// 定义键盘行列引脚
#define ROW1 PA1
#define ROW2 PA4
#define ROW3 PB1
#define ROW4 PA11
#define COL1 PA12
#define COL2 PB11
#define COL3 PA2
#define COL4 PF1
Adafruit_ILI9341 lcd2 = Adafruit_ILI9341(TFT_CS, TFT_DC);
// 游戏变量
int bombNumber;//爆炸数
int guessCount;//尝试次数
int maxGuesses = 7;//总机会次数
bool gameOver = false;//游戏进行状态
String inputString = "";//屏幕输出数据
bool inputActive = false;//输出状态
/* Keypad setup */
char keyMap[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
//Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);/*--------*/
void initGame() {
bombNumber = random(1, 101); // 生成1-100的随机数
guessCount = 0;
gameOver = false;
inputString = "";
inputActive = false;
// 清屏并显示游戏标题
lcd2.fillScreen(ILI9341_BLACK);
lcd2.setCursor(0, 0);
lcd2.setTextColor(ILI9341_WHITE);
lcd2.setTextSize(2);
lcd2.println("数字炸弹游戏");
lcd2.setTextSize(1);
lcd2.println("----------------");
lcd2.println("猜一个1-100之间的数字");
lcd2.println("你有7次机会");
lcd2.println("使用键盘输入数字");
lcd2.println("按#确认输入");
lcd2.println("按*重新开始");
lcd2.println("----------------");
}
// 处理玩家猜测
void processGuess(int guess) {
guessCount++;
lcd2.fillRect(0, 160, 240, 100, ILI9341_BLACK);
lcd2.setCursor(0, 160);
lcd2.setTextColor(ILI9341_WHITE);
lcd2.setTextSize(1);
lcd2.printf("第%d次猜测: %d\n", guessCount, guess);
if (guess == bombNumber) {
gameOver = true;
lcd2.setTextColor(ILI9341_GREEN);
lcd2.println("恭喜!你找到了炸弹!");
lcd2.printf("用了%d次猜测\n", guessCount);
} else if (guessCount >= maxGuesses) {
gameOver = true;
lcd2.setTextColor(ILI9341_RED);
lcd2.println("游戏结束!你失败了!");
lcd2.printf("炸弹数字是: %d\n", bombNumber);
} else if (guess < bombNumber) {
lcd2.setTextColor(ILI9341_YELLOW);
lcd2.println("太小了!再试一次");
} else {
lcd2.setTextColor(ILI9341_YELLOW);
lcd2.println("太大了!再试一次");
}
lcd2.println("----------------");
lcd2.printf("剩余尝试: %d\n", maxGuesses - guessCount);
}
char scanKeypad() {
// 设置行引脚为输出,列引脚为输入上拉
pinMode(ROW1, OUTPUT);
pinMode(ROW2, OUTPUT);
pinMode(ROW3, OUTPUT);
pinMode(ROW4, OUTPUT);
pinMode(COL1, INPUT_PULLUP);
pinMode(COL2, INPUT_PULLUP);
pinMode(COL3, INPUT_PULLUP);
pinMode(COL4, INPUT_PULLUP);
// 扫描每一行
for (int row = 0; row < 4; row++) {
// 设置当前行为低电平,其他行为高电平
digitalWrite(ROW1, row != 0);
digitalWrite(ROW2, row != 1);
digitalWrite(ROW3, row != 2);
digitalWrite(ROW4, row != 3);
// 检查每一列
if (digitalRead(COL1) == LOW) return keyMap[row][0];
if (digitalRead(COL2) == LOW) return keyMap[row][1];
if (digitalRead(COL3) == LOW) return keyMap[row][2];
if (digitalRead(COL4) == LOW) return keyMap[row][3];
}
return 0; // 没有按键按下
}
void setup() {
Serial.begin(115200);
lcd2.begin();
lcd2.setCursor(20, 120);
lcd2.setTextColor(ILI9341_RED);
lcd2.setTextSize(3);
lcd2.println("From Group IV");
lcd2.setCursor(24, 160);
lcd2.setTextColor(ILI9341_GREEN);
lcd2.setTextSize(2);
lcd2.println("游戏正在加载.....BANG!");
/*---------------------------*/
randomSeed(analogRead(0)); // 初始化随机数种子
initGame();
}
void loop() {
char key = scanKeypad();
if (key != 0) {
delay(50); // 简单防抖
if (scanKeypad() == key) { // 确认按键
if (key == '#') { // 确认输入
if (inputString.length() > 0 && !gameOver) {
int guess = inputString.toInt();
if (guess >= 1 && guess <= 100) {
processGuess(guess);
inputString = "";
lcd2.fillRect(0, 140, 240, 20, ILI9341_BLACK);
} else {
lcd2.fillRect(0, 140, 240, 20, ILI9341_BLACK);
lcd2.setCursor(0, 140);
lcd2.setTextColor(ILI9341_RED);
lcd2.println("无效输入!请输入1-100的数字");
}
}
inputActive = false;
}
else if (key == '*') { // 重新开始
initGame();
}
else if (key >= '0' && key <= '9' && !gameOver) { // 数字输入
if (!inputActive) {
inputActive = true;
lcd2.fillRect(0, 140, 240, 20, ILI9341_BLACK);
lcd2.setCursor(0, 140);
lcd2.setTextColor(ILI9341_WHITE);
lcd2.print("输入: ");
}
if (inputString.length() < 3) { // 限制最多3位数
inputString += key;
lcd2.print(key);
}
}
while (scanKeypad() != 0); // 等待按键释放
}
}
// 串口输入仍然可用(可选)
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
if (input.equalsIgnoreCase("restart")) {
initGame();
return;
}
if (gameOver) {
Serial.println("游戏已结束,输入'restart'重新开始");
return;
}
int guess = input.toInt();
if (guess >= 1 && guess <= 100) {
processGuess(guess);
} else {
Serial.println("请输入1-100之间的数字");
}
}
}