#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
// choosing constructor:
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
///////the images:///////////////////////////////////////////////////////
// ' bomb', 12x16px
const unsigned char epd_bitmap_bomb[] PROGMEM = {
0x10, 0x00, 0x04, 0x00, 0x19, 0x00, 0x64, 0x00, 0x80, 0x00, 0x80,
0x00, 0xc4, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f,
0xf8, 0x0f, 0xf8, 0x0f, 0xf8, 0x0f, 0xf0, 0x07, 0xe0, 0x03};
// 'fire', 13x16px
const unsigned char epd_bitmap_fire[] PROGMEM = {
0x90, 0x00, 0x00, 0x01, 0x40, 0x00, 0x24, 0x04, 0x50, 0x02, 0x92,
0x02, 0xa0, 0x15, 0x2e, 0x0c, 0x14, 0x09, 0x08, 0x04, 0x51, 0x14,
0x94, 0x18, 0xca, 0x13, 0xe4, 0x09, 0xc8, 0x05, 0xf0, 0x03};
// 'poison', 14x15px
const unsigned char epd_bitmap_poison[] PROGMEM = {
0xe0, 0x01, 0xf8, 0x07, 0xf8, 0x07, 0xd0, 0x02, 0x10, 0x02,
0x08, 0x04, 0x84, 0x08, 0x12, 0x10, 0xf9, 0x23, 0xfd, 0x2f,
0xfd, 0x2f, 0xf9, 0x27, 0xf2, 0x13, 0x04, 0x08, 0xf8, 0x07};
// 'sword', 14x14px
const unsigned char epd_bitmap_sword[] PROGMEM = {
0x00, 0x30, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07,
0x86, 0x03, 0xc6, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x3c, 0x00,
0x7e, 0x00, 0x9f, 0x01, 0x8f, 0x01, 0x07, 0x00};
// 'tnt', 14x12px
const unsigned char epd_bitmap_tnt[] PROGMEM = {
0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x2e, 0x1d, 0x64, 0x09,
0xa4, 0x09, 0x24, 0x09, 0x00, 0x00, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f};
// 'jumping', 21x28px
const unsigned char epd_bitmap_jumping[] PROGMEM = {
0x00, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00,
0xe0, 0xff, 0x00, 0x10, 0x00, 0x01, 0x08, 0x00, 0x02, 0x08, 0x00, 0x02,
0x88, 0x20, 0x02, 0x88, 0x20, 0x02, 0x08, 0x0e, 0x02, 0x08, 0x00, 0x02,
0x08, 0x00, 0x02, 0x10, 0x00, 0x01, 0xe3, 0xff, 0x18, 0x43, 0x40, 0x18,
0x24, 0x80, 0x04, 0x38, 0x80, 0x03, 0x20, 0x80, 0x00, 0x20, 0x80, 0x00,
0x20, 0x80, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00,
0x00, 0x11, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00, 0x80, 0x31, 0x00};
// 'moving robot 1', 15x29px
const unsigned char epd_bitmap_moving_right_1[] PROGMEM = {
0x40, 0x00, 0xa0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xfc, 0x1f,
0x02, 0x20, 0x01, 0x40, 0x01, 0x40, 0x21, 0x48, 0x21, 0x48, 0x81, 0x43,
0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0xfc, 0x1f, 0x08, 0x08, 0x04, 0x10,
0x0c, 0x10, 0x14, 0x10, 0x24, 0x10, 0xc4, 0x10, 0xc4, 0x10, 0xf8, 0x0f,
0x20, 0x02, 0x60, 0x02, 0x60, 0x06, 0xe0, 0x06, 0x00, 0x0e};
// 'moving robot2', 19x29px
const unsigned char epd_bitmap_moving_right_2[] PROGMEM = {
0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x01, 0x00, 0xf0, 0x7f, 0x00, 0x08, 0x80, 0x00, 0x04,
0x00, 0x01, 0x04, 0x00, 0x01, 0x84, 0x20, 0x01, 0x84, 0x20, 0x01,
0x04, 0x0e, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x01, 0x08, 0x80,
0x00, 0xf0, 0x7f, 0x00, 0x20, 0x20, 0x00, 0x10, 0x40, 0x00, 0x18,
0x40, 0x00, 0x14, 0xc0, 0x00, 0x12, 0x40, 0x01, 0x13, 0x40, 0x02,
0x13, 0x40, 0x06, 0xe0, 0x3f, 0x06, 0x80, 0x08, 0x00, 0x80, 0x18,
0x00, 0x80, 0x19, 0x00, 0x80, 0x39, 0x00, 0x80, 0x03, 0x00};
// 'robot_resting', 19x29px
const unsigned char epd_bitmap_robot_resting[] PROGMEM = {
0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02,
0x00, 0x00, 0x02, 0x00, 0xf0, 0x7f, 0x00, 0x08, 0x80, 0x00, 0x04,
0x00, 0x01, 0x04, 0x00, 0x01, 0x44, 0x10, 0x01, 0x44, 0x10, 0x01,
0x04, 0x07, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x01, 0x08, 0x80,
0x00, 0xf0, 0x7f, 0x00, 0x20, 0x20, 0x00, 0x10, 0x40, 0x00, 0x10,
0x40, 0x00, 0x18, 0xc0, 0x00, 0x14, 0x40, 0x01, 0x12, 0x40, 0x02,
0x13, 0x40, 0x06, 0xe3, 0x3f, 0x06, 0x80, 0x08, 0x00, 0x80, 0x08,
0x00, 0xc0, 0x18, 0x00, 0xc0, 0x18, 0x00, 0xe0, 0x38, 0x00};
// ' moving_left 1', 19x29px
const unsigned char epd_bitmap__moving_left_1[] PROGMEM = {
0x00, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04,
0x00, 0x00, 0x04, 0x00, 0xf0, 0x7f, 0x00, 0x08, 0x80, 0x00, 0x04,
0x00, 0x01, 0x04, 0x00, 0x01, 0x24, 0x08, 0x01, 0x24, 0x08, 0x01,
0x84, 0x03, 0x01, 0x04, 0x00, 0x01, 0x04, 0x00, 0x01, 0x08, 0x80,
0x00, 0xf0, 0x7f, 0x00, 0x20, 0x20, 0x00, 0x10, 0x40, 0x00, 0x10,
0xc0, 0x00, 0x18, 0x40, 0x01, 0x14, 0x40, 0x02, 0x12, 0x40, 0x06,
0x13, 0x40, 0x06, 0xe3, 0x3f, 0x00, 0x80, 0x08, 0x00, 0x80, 0x0c,
0x00, 0xc0, 0x0c, 0x00, 0xc0, 0x0e, 0x00, 0xe0, 0x00, 0x00};
// ' moving_left 2', 15x29px
const unsigned char epd_bitmap__moving_left_2[] PROGMEM = {
0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xfc, 0x1f,
0x02, 0x20, 0x01, 0x40, 0x01, 0x40, 0x09, 0x42, 0x09, 0x42, 0xe1, 0x40,
0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0xfc, 0x1f, 0x08, 0x08, 0x04, 0x10,
0x04, 0x18, 0x04, 0x14, 0x04, 0x12, 0x84, 0x11, 0x84, 0x11, 0xf8, 0x0f,
0x20, 0x02, 0x30, 0x02, 0x30, 0x03, 0x38, 0x03, 0x80, 0x03};
//////////////////////////////////////////////////////////////////////////////////
char patterns[] = {'t', 'b', 's', 'f', 'p'};
int level = 1;
const int left = 7;
const int jump = 8;
const int right = 9;
const int buzzer = 6;
int dino_position = -1;
int game_speed = 250;
char sum_patterns[10]; //hold up to 10 char
int pattern;
int state_menu_win_lost = 0;
bool state_pattern_action = 0; //
void robot_state(int x);
void changing_state();
void reset();
String string_to_char_converter(char character);
int robot_resting_state = 50;
int direction = 1;
int sum_patterns_index;
char selected = '_';
int score = 0;
int highest_score = 0;
void constant_images();
void setup() {
Serial.begin(9600);
u8g2.begin();
u8g2.setBitmapMode(1); // screen mode
pinMode(jump, INPUT_PULLUP);
pinMode(left, INPUT_PULLUP);
pinMode(right, INPUT_PULLUP);
u8g2.setFont(u8g_font_profont10);
pinMode(buzzer, OUTPUT);
}
void loop() {
if (state_menu_win_lost == 0) {
u8g2.clearBuffer();
u8g2.drawStr(0, 10, "Welcome to TANGO");
u8g2.drawStr(0, 20, "DETECTING FRAUD");
u8g2.drawStr(20, 30, "Press button to start");
u8g2.drawXBMP(50, 30, 19, 29, epd_bitmap_robot_resting);
u8g2.sendBuffer();
// if pressed button
if (digitalRead(jump) == LOW || digitalRead(right) == LOW || digitalRead(left) == LOW) {
state_menu_win_lost = 1;
}
} else if (state_menu_win_lost == 1) {
u8g2.clearBuffer();
randomSeed(analogRead(0));
if (state_pattern_action == 0) {
// generate pattern
for (int n = 0; n < level; n++) {
pattern = random(0, 5);
sum_patterns[n] = patterns[pattern];
}
// show pattern on oled
u8g2.drawStr(0, 20, "The pattern is:");
u8g2.drawStr(75, 20, sum_patterns);
u8g2.drawXBMP(50, 30, 19, 29, epd_bitmap_robot_resting);
u8g2.sendBuffer();
delay(500 * level);
state_pattern_action = 1;
} else {
robot_state(robot_resting_state);
changing_state();
if (sum_patterns_index == level) {
// level won
reset();
level += 1;
state_pattern_action = 0;
} else if (selected == '_') {
// continue we didn't select anythin
} else if (sum_patterns[sum_patterns_index] == selected) {
// continue
score += 1;
sum_patterns_index += 1;
selected = '_';
if (level == 10 && sum_patterns_index == level) {
// won
reset();
u8g2.clearBuffer();
u8g2.drawStr(20, 20, "YOU'VE WON!");
u8g2.drawXBMP(50, 30, 19, 29, epd_bitmap_robot_resting);
u8g2.sendBuffer();
delay(5000);
state_menu_win_lost = 0; // back to menu
level = 1;
state_pattern_action = 0;
state_menu_win_lost = 0;
}
} else {
// lost
state_menu_win_lost = 2;
if (highest_score < score) {
highest_score = score;
}
}
}
} else {
reset();
u8g2.clearBuffer();
u8g2.drawStr(0, 10, "YOU'VE LOST!");
u8g2.drawStr(10, 20, "your score:");
u8g2.setCursor(70, 20);
u8g2.print(score);
u8g2.drawStr(10, 30, "highest score:");
u8g2.setCursor(85, 30);
u8g2.print(highest_score);
score = 0;
u8g2.drawXBMP(50, 30, 19, 29, epd_bitmap_robot_resting);
u8g2.sendBuffer();
delay(3500);
state_menu_win_lost = 0; // back to menu
memset(sum_patterns, 0, sizeof(sum_patterns));
level = 1;
sum_patterns_index = 0;
state_pattern_action = 0;
state_menu_win_lost = 0;
}
delay(10);
Serial.println(selected);
}
void robot_state(int x) {
if (direction == 0) {
constant_images();
u8g2.drawXBMP(x, 30, 15, 29, epd_bitmap_moving_right_1);
u8g2.sendBuffer();
delay(80);
constant_images();
u8g2.drawXBMP(x + 5, 30, 19, 29, epd_bitmap_moving_right_2);
u8g2.sendBuffer();
delay(80);
} else if (direction == 2) {
constant_images();
u8g2.drawXBMP(x, 30, 19, 29, epd_bitmap__moving_left_1);
u8g2.sendBuffer();
delay(80);
constant_images();
u8g2.drawXBMP(x - 5, 30, 15, 29, epd_bitmap__moving_left_2);
u8g2.sendBuffer();
delay(80);
} else if (direction == 3) {
constant_images();
u8g2.drawXBMP(x, 30, 21, 28, epd_bitmap_jumping);
u8g2.sendBuffer();
delay(80);
if (x <= 8) {
selected = 'b';
} else if ((x >= 15) & (x <= 29)) {
selected = 'f';
} else if ((x >= 43) & (x <= 57)) {
selected = 'p';
} else if ((x >= 71) & (x <= 86)) {
selected = 't';
} else if (x >= 98) {
selected = 's';
} else {
selected = '_';
}
} else {
constant_images();
u8g2.drawXBMP(x, 30, 19, 29, epd_bitmap_robot_resting);
u8g2.sendBuffer();
delay(80);
}
}
void changing_state() {
if ((digitalRead(right) == LOW) & (robot_resting_state < 102)) {
robot_resting_state += 12;
direction = 0;
} else if ((digitalRead(left) == LOW) & (robot_resting_state > 8)) {
robot_resting_state -= 12;
direction = 2;
} else if (digitalRead(jump) == LOW) {
delay(200); // debounce ////////////////////////////////////////////////////adjust in real time, fix the double click
if (digitalRead(jump) == HIGH) {
direction = 3;
tone(buzzer, 1000); // Send 1KHz sound signal...
delay(10); // ...for 1 sec
noTone(buzzer);
}
} else {
direction = 1;
}
}
void reset() {
sum_patterns_index = 0;
direction = 1;
robot_resting_state = 50;
selected = '_';
}
void constant_images() {
u8g2.clearBuffer();
u8g2.drawStr(60, 8, "score:");
u8g2.setCursor(90, 8);
u8g2.print(score);
u8g2.drawXBMP(5, 10, 12, 16, epd_bitmap_bomb);
u8g2.drawXBMP(29, 10, 13, 16, epd_bitmap_fire);
u8g2.drawXBMP(54, 10, 14, 15, epd_bitmap_poison);
u8g2.drawXBMP(81, 13, 14, 12, epd_bitmap_tnt);
u8g2.drawXBMP(108, 10, 14, 14, epd_bitmap_sword);
}