#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
const int buttons[4] = {5, 4, 3, 2};
int game_map[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int speaker = 6;
int game_interval = 200;
int current_interval = 0;
int score = 100;
int Hp = 5;
uint8_t arrow_top[8] = {
0b00000,
0b00000,
0b00100,
0b01110,
0b10101,
0b00100,
0b00000,
0b00000,
};
uint8_t arrow_down[8] = {
0b00000,
0b00000,
0b00100,
0b10101,
0b01110,
0b00100,
0b00000,
0b00000,
};
uint8_t arrow_right[8] = {
0b00000,
0b00100,
0b00010,
0b01111,
0b00010,
0b00100,
0b00000,
0b00000,
};
uint8_t arrow_left[8] = {
0b00000,
0b00100,
0b01000,
0b11110,
0b01000,
0b00100,
0b00000,
0b00000,
};
uint8_t blank[8] = {
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
};
uint8_t heart[8] = {
0b00000,
0b00000,
0b01010,
0b11111,
0b01110,
0b00100,
0b00000,
0b00000,
};
int generate () {
// give a some space
bool its_must_be_space = game_map[0] &&
game_map[1] &&
game_map[2] &&
game_map[3] &&
game_map[4] &&
game_map[5];
if (its_must_be_space) return 0;
return random(0, 5);
}
// Moving all variable to the right;
void move() {
for (int i = 17; i >= 0; i--) {
game_map[i + 1] = game_map[i];
}
game_map[0] = generate();
}
void setup() {
lcd.createChar(1, arrow_top);
lcd.createChar(2, arrow_right);
lcd.createChar(3, arrow_down);
lcd.createChar(4, arrow_left);
lcd.createChar(5, blank);
lcd.createChar(6, heart);
lcd.begin(16, 2);
lcd.print("\x01\x02\x03\x04");
delay(600);
for (int button_pin : buttons) {
pinMode(button_pin, INPUT_PULLUP);
}
pinMode(speaker, OUTPUT);
greeting();
reset();
// Serial.begin(115200);
}
const greeting() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Gwe");
tone(speaker, 330, 100);
delay(800);
}
String getChara(int number) {
switch (number) {
case 1:
return "\x01";
case 2:
return "\x02";
case 3:
return "\x03";
case 4:
return "\x04";
case 5:
return "-";
case -1:
return "x";
default:
return " ";
}
}
void render() {
lcd.clear();
for (int i = 0; i < 16; i++) {
int pointer = i;
if (pointer < 0) continue;
lcd.setCursor(pointer, 0);
String chara = getChara(game_map[i]);
lcd.print(chara);
}
for (int i = 0; i < Hp; i++) {
lcd.setCursor(15 - i, 1);
lcd.print("\x06");
}
lcd.setCursor(6, 1);
lcd.print("[ ]");
// lcd.setCursor(7, 1);
// lcd.print("^");
lcd.setCursor(0, 1);
lcd.print(score);
}
int inputChek() {
for (int i = 0; i < 4; i++) {
const int button_pin = buttons[i];
const bool pressed = !digitalRead(button_pin);
if (pressed) {
return i + 1;
}
}
return 0;
}
void reset() {
// lcd.clear();
game_interval = 600;
current_interval = 0;
Hp = 5;
lcd.setCursor(11, 1);
lcd.print(" ");
for (int i = 0; i < 17; i++) {
game_map[i] = 0;
}
for (int i = 0; i < 16; i++) {
move();
}
for (int i = 0; i < 30; i++) {
int remove_at = i - 14;
if (i < 16) {
lcd.setCursor(i, 0);
lcd.print("\x05");
}
if (remove_at >= 0) {
lcd.setCursor(remove_at, 0);
String chara = getChara(game_map[remove_at]);
lcd.print(chara);
}
delay(70);
}
while (score != 0) {
if (score > 0 ) score--;
else score++;
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(score);
delay(40);
}
for (int i = 0; i < Hp; i++) {
lcd.setCursor(15 - i, 1);
lcd.print("\x06");
delay(40);
}
}
void loop() {
render();
bool havePressedButton = false;
while (current_interval < game_interval) {
delay(1);
current_interval++;
const int input = inputChek();
if (input == 0 || havePressedButton) continue;
if (game_map[7] == 5 || game_map[7] == -1) continue;
// input chek
if (input == game_map[7]) {
score++;
game_map[7] = 5;
tone(speaker, 450, 10);
lcd.setCursor(7, 1);
String chara = getChara(input);
lcd.print(chara);
}
else {
Hp--; score--;
game_map[7] = -1;
tone(speaker, 170, 100);
lcd.setCursor(7, 1);
lcd.print("x");
}
havePressedButton = true;
}
havePressedButton = false;
// if (game_map[15] > 0 && game_map[15] != 5) {
// Hp--;
// tone(speaker, 170, 100);
// }
// game over
if (Hp == 0) {
lcd.setCursor(0, 1);
lcd.print(score);
while (true) {
delay(200);
lcd.setCursor(11, 1);
lcd.print(" ");
tone(speaker, 170, 100);
delay(300);
lcd.setCursor(11, 1);
lcd.print("\x06\x06\x06\x06\x06");
if (!inputChek()) continue;
reset();
return;
}
}
current_interval = 0;
// render();
move();
}