//this is a mental arithmetic trainer
//how to use:
//the goal of the game is to use Addition and subtraction operation
//to get the number on the lower bottom right from the starting number
//on the left hand side of the game, which represents user's current number.
//from left to right
//the first button allows the users to select which row to proceed(upper or lower)
//the second button allows the user to select what sign to use(+ or -)
//the third button is the confirmation button, will into the next column.
//each time user press the "confirmation" button, the user's number(far left on the lcd)
//will add/subtract the number on the closest column according to user's choice.
//the goal is to get the target number after proceeding the three column in each round.
//以下是自己设置的变量
const int btp = 6;
const int btf = 5;
const int btc = 7;
//bt:button detection pin
//bt (p:postion) (f:flip) (c:confirm)
int user = 0;//玩家目前的数字
int tgt = 10;//target,用户的数字
int sign[3];//预设的正确答案三次分别是加号还是减号
int signf;//用于计算diff
int diff;//目标与目前的总差,也可用于计算compensate
int comp;//compensate,修正除出非整数时的误差
int x; //差
int r_ct;//roll counter
int s_ct;//sign counter
int a;
int b;
int c;
int fx1;//flux #1, a+,b-
int fx2;//flux #2, b+,c-
//生成随机数(错误答案)
int r1;
int r2;
int r3;
//生成答案位置(答案摆放)
int p1;
int p2;
int p3;
//下面是用户状态的数字:
int gc=3;//game status counter, 为3时刷新答案数字,每次确认键(推进键)都会导致其加1
int urs=1;//user sign,用户选择的家好或者减号
int urp=1;//user selection,选择上行或者下行
int lv;//用户等级
int signf2;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
delay(100);
lcd.begin();
lcd.backlight();
pinMode(btp,INPUT);
pinMode(btf,INPUT);
pinMode(btc,INPUT);
pinMode(10,OUTPUT);
Serial.begin(9600);
randomSeed(analogRead(A4));
}
void logInfo(){
Serial.println(gc);
Serial.print("p1:");
Serial.print(p1);
Serial.print("p2:");
Serial.print(p2);
Serial.print("p3:");
Serial.print(p3);
Serial.print(" a:");
Serial.print(a);
Serial.print(" b:");
Serial.print(b);
Serial.print(" c:");
Serial.print(c);
Serial.print(" user:");
Serial.print(user);
Serial.print(" tgt:");
Serial.print(tgt);
Serial.print(" x=");
Serial.print(x);
Serial.print(" fx1:");
Serial.print(fx1);
Serial.print(" fx2:");
Serial.print(fx2);
Serial.print(" comp:");
Serial.print(comp);
Serial.print(" signf:");
Serial.print(signf2);
Serial.print(" sign:");
Serial.print(sign[0]);
Serial.print(" ");
Serial.print(sign[1]);
Serial.print(" ");
Serial.print(sign[2]);
Serial.println("");
}
void loop()
{
logInfo();
//pin10 is the VCC of lcd
digitalWrite(10,HIGH);//按钮供电电压
delay(100);
lcd.clear();
//下面正式开始生成新一轮的答案
if(gc == 3){
tgt = random(1,21);
//设置目标
sign[0] = random(2);
sign[1] = random(2);
sign[2] = random(2);
//设置每次计数的加减号
for (int i = 0; i<=2; i++){//1代表该答案为正,0为负
if(sign[i]==1){
signf += 1;
}
else{
signf -= 1;
}
}//设置signf,最终加减计数器
diff = tgt - user;//求出tgt和user的差
x = diff/signf;//x
comp = signf*x - diff;//comp是假diff-真diff,假比真大多少
//这个compensate加入到最后一个正确答案所在路径的数
if(sign[0]==1){
a = x;
}
else{
a = 0-x;
}
if(sign[2]==1){
b = x;
}
else{
b = 0-x;
}
if(sign[2]==1){
c = x;
}
else{
c = 0-x;
}
fx1 = random(1,9);
a = a + fx1;
b = b - fx1;
fx2 = random(1,9);
b = b + fx2;
c = c - fx2;
c = c - comp;
//致此,正确答案生成完
//下面生成错误答案
r1 = random(0,19);
r2 = random(0,19);
r3 = random(0,19);
gc = 0;//game status counter清零,用户返回一号位置
//生成答案摆放位置
p1 = random(2);
delay(5);
p2 = random(2);
delay(5);
p3 = random(2);
signf2=signf;
signf=0;//重置加减号计数器
}//【答案的六个数字及位置生成完毕】
//以下两个分别是选择符号以及位置
if (digitalRead(btp)==HIGH){
urs = urs*(0-1);
delay(100);
}
if (digitalRead(btf)==HIGH){
urp = urp*(0-1);
delay(100);
}
//用户还在第一阶段的情况:
if(gc == 0){
//已经有:用户数字,用户加减号选择,答案以及位置
//打印用户位置(上或下)1上,-1下
if(urp == 1){
lcd.setCursor(0,0);
}
else{
lcd.setCursor(0,1);
}
lcd.print(user);//打印用户数字(最多两位)
//打印用户符号(加或减)1+,-1-
if(urs == 1){
lcd.print("+");
}
else{
lcd.print("-");
}
////////放置数字
if(p1==1){//放置一号答案
lcd.setCursor(3,0);
lcd.print(a);
lcd.setCursor(3,1);
lcd.print(r1);
}
else{
lcd.setCursor(3,0);
lcd.print(r1);
lcd.setCursor(3,1);
lcd.print(a);
}
if(p2==1){//放置二号答案
lcd.setCursor(6,0);
lcd.print(b);
lcd.setCursor(6,1);
lcd.print(r2);
}
else{
lcd.setCursor(6,0);
lcd.print(r2);
lcd.setCursor(6,1);
lcd.print(b);
}
if(p3==1){//放置三号答案
lcd.setCursor(9,0);
lcd.print(c);
lcd.setCursor(9,1);
lcd.print(r3);
}
else{
lcd.setCursor(9,0);
lcd.print(r3);
lcd.setCursor(9,1);
lcd.print(c);
}
lcd.setCursor(12,0);
lcd.print("LV");
if(lv>99){
lcd.print("!!");
}
else{
lcd.print(lv);
}
lcd.setCursor(12,1);
lcd.print("=");
lcd.print(">");
lcd.print(tgt);
//confirmation,用户决定从第一层进入第二层
if (digitalRead(btc)==HIGH){
gc+=1;
delay(200);//in case the button stays for too long and wrongly identify the user as pressing it multiple times
int adder;
if(urp==1){
if(p1 == 1){
adder = a;
}
else{
adder = r1;
}
}
else{
if(p1 == 1){
adder = r1;
}
else{
adder = a;
}
}
//决定加还是减
if(urs==1){
user = user+adder;
}
else{
user = user-adder;
}
}
}//用户位置阶段一结束
//////
//用户在第二阶段的情况:
if(gc == 1){
//已经有:用户数字,用户加减号选择,答案以及位置
//打印用户位置(上或下)1上,-1下
if(urp == 1){
lcd.setCursor(0,0);
}
else{
lcd.setCursor(0,1);
}
lcd.print(user);//打印用户数字(最多两位)//记得测试一下如果是负数占多少个显示格子
//打印用户符号(加或减)1+,-1-
if(urs == 1){
lcd.print("+");
}
else{
lcd.print("-");
}
////////放置数字
if(p2==1){//放置二号答案
lcd.setCursor(6,0);
lcd.print(b);
lcd.setCursor(6,1);
lcd.print(r2);
}
else{
lcd.setCursor(6,0);
lcd.print(r2);
lcd.setCursor(6,1);
lcd.print(b);
}
if(p3==1){//放置三号答案
lcd.setCursor(9,0);
lcd.print(c);
lcd.setCursor(9,1);
lcd.print(r3);
}
else{
lcd.setCursor(9,0);
lcd.print(r3);
lcd.setCursor(9,1);
lcd.print(c);
}
lcd.setCursor(12,0);
lcd.print("LV");
if(lv>99){
lcd.print("!!");
}
else{
lcd.print(lv);
}
lcd.setCursor(12,1);
lcd.print("=");
lcd.print(">");
lcd.print(tgt);
//confirmation,用户决定从第二层进入第三层
if (digitalRead(btc)==HIGH){
gc+=1;
delay(200);//in case the button stays for too long and wrongly identify the user as pressing it multiple times
int adder;
if(urp==1){
if(p2 == 1){
adder = b;
}
else{
adder = r2;
}
}
else{
if(p2 == 1){
adder = r2;
}
else{
adder = b;
}
}
//决定加还是减
if(urs==1){
user = user+adder;
}
else{
user = user-adder;
}
}
}//用户位置阶段二结束
//////
//用户在第三阶段的情况:
if(gc == 2){
//已经有:用户数字,用户加减号选择,答案以及位置
//打印用户位置(上或下)1上,-1下
if(urp == 1){
lcd.setCursor(0,0);
}
else{
lcd.setCursor(0,1);
}
lcd.print(user);//打印用户数字(最多两位)//记得测试一下如果是负数占多少个显示格子
//打印用户符号(加或减)1+,-1-
if(urs == 1){
lcd.print("+");
}
else{
lcd.print("-");
}
////////放置数字
if(p3==1){//放置三号答案
lcd.setCursor(9,0);
lcd.print(c);
lcd.setCursor(9,1);
lcd.print(r3);
}
else{
lcd.setCursor(9,0);
lcd.print(r3);
lcd.setCursor(9,1);
lcd.print(c);
}
lcd.setCursor(12,0);
lcd.print("LV");
if(lv>99){
lcd.print("!!");
}
else{
lcd.print(lv);
}
lcd.setCursor(12,1);
lcd.print("=");
lcd.print(">");
lcd.print(tgt);
//confirmation,用户决定从第三层进入第四层
if (digitalRead(btc)==HIGH){
gc+=1;
delay(200);//in case the button stays for too long and wrongly identify the user as pressing it multiple times
int adder;
if(urp==1){
if(p3 == 1){
adder = c;
}
else{
adder = r3;
}
}
else{
if(p3 == 1){
adder = r3;
}
else{
adder = c;
}
}
//决定加还是减
if(urs==1){
user = user+adder;
}
else{
user = user-adder;
}
}
}//用户位置阶段三结束
if(gc == 3){
lcd.clear();
//阶段四判断是否为答案
if(user==tgt){
lv+=1;
lcd.setCursor(5,0);
lcd.print("congrat!");
lcd.setCursor(7,1);
lcd.print("LV+1");
delay(1000);
}
else{
lv=0;
lcd.print("sorry, u've lost");
lcd.setCursor(7,1);
delay(500);
lcd.clear();
delay(1000);
lcd.home();
lcd.print("sorry, u've lost");
delay(1000);
lcd.clear();
delay(500);
lcd.home();
lcd.setCursor(1,0);
lcd.print("restarting...");
delay(1000);
user=0;
}
}
}
//记得在使用按钮的时候设置一个延迟,以防快速循环重复
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r