#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h>
#define TICKS_PER_SECOND 60
/* Display */
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
/* Keypad setup */
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = { 5, 4, 3, 2 };
byte colPins[KEYPAD_COLS] = { A3, A2, A1, A0 };
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{ '1', '2', '3', '+' },
{ '4', '5', '6', '-' },
{ '7', '8', '9', '*' },
{ '.', '0', '=', '/' },
};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
uint64_t value = 0;
void showSpalshScreen(void)
{
lcd.setCursor(4, 0);
lcd.print("Welcome!");
lcd.setCursor(3, 1);
String message = "Calculator";
for (byte i = 0; i < message.length(); i++)
{
lcd.print(message[i]);
delay(50);
}
delay(500);
}
void updateCursor(void)
{
if (millis() / 250 % 2 == 0)
{
lcd.cursor();
}
else
{
lcd.noCursor();
}
}
void setup()
{
Serial.begin(115200);
lcd.begin(16, 2);
showSpalshScreen();
lcd.clear();
lcd.cursor();
lcd.setCursor(1, 0);
}
char operation = 0;
String memory = "";
String current = "";
uint64_t currentDecimal;
bool decimalPoint = false;
char nextKey = '2';
bool secretMode = false;
double calculate(char operation, double left, double right)
{
switch (operation)
{
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
case '/': return left / right;
}
}
char gameID = '0';
int jumperObstacle = -1;
int jumperObstacleY = 1;
int jumperJumpTime = 0;
int walkerPosX = 0;
int walkerPosY = 0;
void setClear()
{
lcd.clear();
lcd.setCursor(0, 0);
}
void processGameWalker(char key)
{
lcd.clear();
if(key == '2')
{
walkerPosY -= 1;
}
if(key == '5')
{
walkerPosY += 1;
}
if(key == '4')
{
walkerPosX -= 1;
}
if(key == '6')
{
walkerPosX += 1;
}
if(walkerPosY < 0)
{
walkerPosY = 0;
}
if(walkerPosY > 1)
{
walkerPosY = 1;
}
if(walkerPosX < 0)
{
walkerPosX = 0;
}
if(walkerPosX > 16)
{
walkerPosX = 16;
}
lcd.setCursor(walkerPosX, walkerPosY);
}
void processGameJumper(char key)
{
if(key == '2')
{
jumperJumpTime += TICKS_PER_SECOND;
if(jumperJumpTime > TICKS_PER_SECOND * 2)
{
jumperJumpTime = TICKS_PER_SECOND * 2;
}
}
if(key == '5')
{
jumperJumpTime = 0;
}
}
void GameWalkerUpdate(void)
{
lcd.
}
void GameJumperUpdate(void)
{
static uint64_t ticks = 0;
ticks++;
lcd.clear();
int y = 1;
if (jumperJumpTime != 0)
{
y = 0;
jumperJumpTime--;
}
if(ticks % (TICKS_PER_SECOND / 2) == 0)
{
if(--jumperObstacle <= 0)
{
jumperObstacle = 16;
jumperObstacleY = rand() % 2 == 0 ? 1 : 0;
}
}
lcd.setCursor(5, y);
lcd.print("&");
lcd.setCursor(jumperObstacle, jumperObstacleY);
lcd.print("#");
if(jumperObstacle == 4 && y == jumperObstacleY)
{
lcd.clear();
lcd.setCursor(4, jumperObstacleY);
lcd.print("YOU LOST");
gameID = 0;
jumperObstacle = -1;
jumperJumpTime = 0;
jumperObstacleY = 1;
ticks = 0;
}
}
void processSecretMode(char key)
{
Serial.println(key);
if (key == '=')
{
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Secret mode");
gameID = '0';
return;
}
if ('.' == key)
{
lcd.clear();
secretMode = false;
gameID = 0;
return;
}
switch (gameID)
{
case '0':
Serial.println("Setting game...");
gameID = key;
break;
case '1':
processGameWalker(key);
break;
case '2':
processGameJumper(key);
break;
default:
Serial.println("Unknown game");
break;
}
}
void secretModeUpdate(void)
{
switch (gameID)
{
case '1':
GameWalkerUpdate();
break;
case '2':
GameJumperUpdate();
break;
}
}
void processInput(char key)
{
if (secretMode)
{
processSecretMode(key);
}
else
{
if (nextKey == key)
{
switch (nextKey)
{
case '2':
nextKey = '1';
break;
case '1':
nextKey = '3';
break;
case '3':
nextKey = '7';
break;
case '7':
nextKey = '=';
break;
case '=':
secretMode = true;
return;
default:
nextKey = '2';
return;
}
}
if ('-' == key && current == "")
{
current = "-";
lcd.print("-");
return;
}
else if ('-' == key && current == "-")
{
current = "";
lcd.setCursor(1, 1);
lcd.print(" ");
lcd.setCursor(1, 1);
}
switch (key)
{
case '+':
case '-':
case '*':
case '/':
if (!operation)
{
memory = current;
current = "";
}
operation = key;
lcd.setCursor(0, 1);
lcd.print(key);
lcd.setCursor(current.length() + 1, 1);
return;
case '=':
float leftNum = memory.toDouble();
float rightNum = current.toDouble();
memory = String(calculate(operation, leftNum, rightNum));
current = "";
lcd.clear();
lcd.setCursor(1, 0);
lcd.print(memory);
lcd.setCursor(0, 1);
lcd.print(operation);
return;
}
if ('.' == key && current.indexOf('.') >= 0)
{
return;
}
if ('.' != key && current == "0")
{
current = String(key);
}
else if (key)
{
current += String(key);
}
lcd.print(key);
}
}
void loop()
{
delay(1000 / TICKS_PER_SECOND);
if (!secretMode)
{
updateCursor();
}
char key = keypad.getKey();
if (key)
{
processInput(key);
}
if (secretMode)
{
secretModeUpdate();
}
}